diff --git a/samples/__init__.py b/samples/__init__.py
new file mode 100644
index 000000000..4bbe0ffdb
--- /dev/null
+++ b/samples/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/samples/ingredients/__init__.py b/samples/ingredients/__init__.py
new file mode 100644
index 000000000..81d8b9be3
--- /dev/null
+++ b/samples/ingredients/__init__.py
@@ -0,0 +1,18 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
diff --git a/samples/ingredients/disks/disk_from_snapshot.py b/samples/ingredients/disks/disk_from_snapshot.py
new file mode 100644
index 000000000..e0271c47b
--- /dev/null
+++ b/samples/ingredients/disks/disk_from_snapshot.py
@@ -0,0 +1,54 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def disk_from_snapshot(
+ disk_type: str, disk_size_gb: int, boot: bool, source_snapshot: str, auto_delete: bool = False
+) -> compute_v1.AttachedDisk():
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses a disk snapshot as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_snapshot: disk snapshot to use when creating this disk. You must have read access to this disk.
+ This value uses the following format: "projects/{project_name}/global/snapshots/{snapshot_name}"
+ auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it
+
+ Returns:
+ AttachedDisk object configured to be created using the specified snapshot.
+ """
+ disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_snapshot = source_snapshot
+ initialize_params.disk_type = disk_type
+ initialize_params.disk_size_gb = disk_size_gb
+ disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ disk.auto_delete = auto_delete
+ disk.boot = boot
+ return disk
+#
diff --git a/samples/ingredients/disks/empty_disk.py b/samples/ingredients/disks/empty_disk.py
new file mode 100644
index 000000000..570292fde
--- /dev/null
+++ b/samples/ingredients/disks/empty_disk.py
@@ -0,0 +1,49 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def empty_disk(disk_type: str, disk_size_gb: int, boot: bool = False, auto_delete: bool = False) -> compute_v1.AttachedDisk():
+ """
+ Create an AttachedDisk object to be used in VM instance creation. The created disk contains
+ no data and requires formatting before it can be used.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it
+
+ Returns:
+ AttachedDisk object configured to be created as an empty disk.
+ """
+ disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.disk_type = disk_type
+ initialize_params.disk_size_gb = disk_size_gb
+ disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ disk.auto_delete = True
+ disk.boot = False
+ return disk
+#
diff --git a/samples/ingredients/disks/from_image.py b/samples/ingredients/disks/from_image.py
new file mode 100644
index 000000000..5f22f4e61
--- /dev/null
+++ b/samples/ingredients/disks/from_image.py
@@ -0,0 +1,55 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def disk_from_image(
+ disk_type: str, disk_size_gb: int, boot: bool, source_image: str, auto_delete: bool = False
+) -> compute_v1.AttachedDisk:
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
+ of the publicly available images or an image from one of your projects.
+ This value uses the following format: "projects/{project_name}/global/images/{image_name}"
+ auto_delete: boolean flag indicating whether this disk should be deleted with the VM that uses it
+
+ Returns:
+ AttachedDisk object configured to be created using the specified image.
+ """
+ boot_disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = source_image
+ initialize_params.disk_size_gb = disk_size_gb
+ initialize_params.disk_type = disk_type
+ boot_disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ boot_disk.auto_delete = auto_delete
+ boot_disk.boot = boot
+ return boot_disk
+#
diff --git a/samples/ingredients/firewall/create.py b/samples/ingredients/firewall/create.py
new file mode 100644
index 000000000..e6e9f0008
--- /dev/null
+++ b/samples/ingredients/firewall/create.py
@@ -0,0 +1,72 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def create_firewall_rule(
+ project_id: str, firewall_rule_name: str, network: str = "global/networks/default"
+) -> compute_v1.Firewall:
+ """
+ Creates a simple firewall rule allowing for incoming HTTP and HTTPS access from the entire Internet.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ firewall_rule_name: name of the rule that is created.
+ network: name of the network the rule will be applied to. Available name formats:
+ * https://www.googleapis.com/compute/v1/projects/{project_id}/global/networks/{network}
+ * projects/{project_id}/global/networks/{network}
+ * global/networks/{network}
+
+ Returns:
+ A Firewall object.
+ """
+ firewall_rule = compute_v1.Firewall()
+ firewall_rule.name = firewall_rule_name
+ firewall_rule.direction = "INGRESS"
+
+ allowed_ports = compute_v1.Allowed()
+ allowed_ports.I_p_protocol = "tcp"
+ allowed_ports.ports = ["80", "443"]
+
+ firewall_rule.allowed = [allowed_ports]
+ firewall_rule.source_ranges = ["0.0.0.0/0"]
+ firewall_rule.network = network
+ firewall_rule.description = "Allowing TCP traffic on port 80 and 443 from Internet."
+
+ firewall_rule.target_tags = ["web"]
+
+ # Note that the default value of priority for the firewall API is 1000.
+ # If you check the value of `firewall_rule.priority` at this point it
+ # will be equal to 0, however it is not treated as "set" by the library and thus
+ # the default will be applied to the new rule. If you want to create a rule that
+ # has priority == 0, you need to explicitly set it so:
+ # TODO: Uncomment to set the priority to 0
+ # firewall_rule.priority = 0
+
+ firewall_client = compute_v1.FirewallsClient()
+ op = firewall_client.insert_unary(
+ project=project_id, firewall_resource=firewall_rule
+ )
+
+ op_client = compute_v1.GlobalOperationsClient()
+ op_client.wait(project=project_id, operation=op.name)
+
+ return firewall_client.get(project=project_id, firewall=firewall_rule_name)
+#
diff --git a/samples/ingredients/firewall/delete.py b/samples/ingredients/firewall/delete.py
new file mode 100644
index 000000000..fc6a42150
--- /dev/null
+++ b/samples/ingredients/firewall/delete.py
@@ -0,0 +1,39 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def delete_firewall_rule(project_id: str, firewall_rule_name: str) -> None:
+ """
+ Deletes a firewall rule from the project.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ firewall_rule_name: name of the firewall rule you want to delete.
+ """
+ firewall_client = compute_v1.FirewallsClient()
+ operation = firewall_client.delete_unary(
+ project=project_id, firewall=firewall_rule_name
+ )
+
+ operation_client = compute_v1.GlobalOperationsClient()
+ operation_client.wait(project=project_id, operation=operation.name)
+ return
+#
diff --git a/samples/ingredients/firewall/get.py b/samples/ingredients/firewall/get.py
new file mode 100644
index 000000000..0a8388d56
--- /dev/null
+++ b/samples/ingredients/firewall/get.py
@@ -0,0 +1,36 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def get_firewall_rule(project_id: str, firewall_rule_name: str) -> compute_v1.Firewall:
+ """
+ Retrieve a Firewall from a project.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ firewall_rule_name: name of the firewall rule you want to retrieve.
+
+ Returns:
+ A Firewall object.
+ """
+ firewall_client = compute_v1.FirewallsClient()
+ return firewall_client.get(project=project_id, firewall=firewall_rule_name)
+#
diff --git a/samples/ingredients/firewall/list.py b/samples/ingredients/firewall/list.py
new file mode 100644
index 000000000..5deeac4e3
--- /dev/null
+++ b/samples/ingredients/firewall/list.py
@@ -0,0 +1,44 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from typing import Iterable
+
+from google.cloud import compute_v1
+
+
+#
+def list_firewall_rules(project_id: str) -> Iterable[compute_v1.Firewall]:
+ """
+ Return a list of all the firewall rules in specified project. Also prints the
+ list of firewall names and their descriptions.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+
+ Returns:
+ A flat list of all firewall rules defined for given project.
+ """
+ firewall_client = compute_v1.FirewallsClient()
+ firewalls_list = firewall_client.list(project=project_id)
+
+ for firewall in firewalls_list:
+ print(f" - {firewall.name}: {firewall.description}")
+
+ return firewalls_list
+#
+
diff --git a/samples/ingredients/firewall/patch.py b/samples/ingredients/firewall/patch.py
new file mode 100644
index 000000000..5017114a3
--- /dev/null
+++ b/samples/ingredients/firewall/patch.py
@@ -0,0 +1,46 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def patch_firewall_priority(project_id: str, firewall_rule_name: str, priority: int) -> None:
+ """
+ Modifies the priority of a given firewall rule.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ firewall_rule_name: name of the rule you want to modify.
+ priority: the new priority to be set for the rule.
+ """
+ firewall_rule = compute_v1.Firewall()
+ firewall_rule.priority = priority
+
+ # The patch operation doesn't require the full definition of a Firewall object. It will only update
+ # the values that were set in it, in this case it will only change the priority.
+ firewall_client = compute_v1.FirewallsClient()
+ operation = firewall_client.patch_unary(
+ project=project_id, firewall=firewall_rule_name, firewall_resource=firewall_rule
+ )
+
+ operation_client = compute_v1.GlobalOperationsClient()
+ operation_client.wait(project=project_id, operation=operation.name)
+ return
+#
+
diff --git a/samples/snippets/sample_images.py b/samples/ingredients/images/get_image.py
similarity index 60%
rename from samples/snippets/sample_images.py
rename to samples/ingredients/images/get_image.py
index 96d8bbb83..4dcce0e77 100644
--- a/samples/snippets/sample_images.py
+++ b/samples/ingredients/images/get_image.py
@@ -1,4 +1,4 @@
-# Copyright 2021 Google LLC
+# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,35 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from typing import Iterable
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
-# [START compute_images_get]
-# [START compute_images_get_list]
from google.cloud import compute_v1
-# [END compute_images_get_list]
-# [END compute_images_get]
-
-# [START compute_images_get_list]
-def list_images(project_id: str) -> Iterable[compute_v1.Image]:
- """
- Retrieve a list of images available in given project.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to list images from.
-
- Returns:
- An iterable collection of compute_v1.Image objects.
- """
- image_client = compute_v1.ImagesClient()
- return image_client.list(project=project_id)
-
-
-# [END compute_images_get_list]
-
-
-# [START compute_images_get]
+#
def get_image(project_id: str, image_name: str) -> compute_v1.Image:
"""
Retrieve detailed information about a single image from a project.
@@ -54,6 +34,4 @@ def get_image(project_id: str, image_name: str) -> compute_v1.Image:
"""
image_client = compute_v1.ImagesClient()
return image_client.get(project=project_id, image=image_name)
-
-
-# [END compute_images_get]
+#
diff --git a/samples/ingredients/images/get_image_from_family.py b/samples/ingredients/images/get_image_from_family.py
new file mode 100644
index 000000000..45daec115
--- /dev/null
+++ b/samples/ingredients/images/get_image_from_family.py
@@ -0,0 +1,42 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+
+from google.cloud import compute_v1
+
+
+#
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ """
+ Retrieve the newest image that is part of a given family in a project.
+
+ Args:
+ project: project ID or project number of the Cloud project you want to get image from.
+ family: name of the image family you want to get image from.
+
+ Returns:
+ An Image object.
+ """
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(
+ project=project, family=family
+ )
+ return newest_image
+#
diff --git a/samples/ingredients/images/list_images.py b/samples/ingredients/images/list_images.py
new file mode 100644
index 000000000..b4c191fc3
--- /dev/null
+++ b/samples/ingredients/images/list_images.py
@@ -0,0 +1,37 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from typing import Iterable
+
+from google.cloud import compute_v1
+
+
+#
+def list_images(project_id: str) -> Iterable[compute_v1.Image]:
+ """
+ Retrieve a list of images available in given project.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to list images from.
+
+ Returns:
+ An iterable collection of compute_v1.Image objects.
+ """
+ image_client = compute_v1.ImagesClient()
+ return image_client.list(project=project_id)
+#
diff --git a/samples/ingredients/instance-templates/create.py b/samples/ingredients/instance-templates/create.py
new file mode 100644
index 000000000..ca56e99a8
--- /dev/null
+++ b/samples/ingredients/instance-templates/create.py
@@ -0,0 +1,74 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+from google.cloud import compute_v1
+
+
+#
+def create_template(project_id: str, template_name: str) -> compute_v1.InstanceTemplate:
+ """
+ Create a new instance template with the provided name and a specific
+ instance configuration.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you use.
+ template_name: name of the new template to create.
+
+ Returns:
+ InstanceTemplate object that represents the new instance template.
+ """
+ # The template describes the size and source image of the boot disk
+ # to attach to the instance.
+ disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = (
+ "projects/debian-cloud/global/images/family/debian-11"
+ )
+ initialize_params.disk_size_gb = 250
+ disk.initialize_params = initialize_params
+ disk.auto_delete = True
+ disk.boot = True
+
+ # The template connects the instance to the `default` network,
+ # without specifying a subnetwork.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = "global/networks/default"
+
+ # The template lets the instance use an external IP address.
+ access_config = compute_v1.AccessConfig()
+ access_config.name = "External NAT"
+ access_config.type_ = "ONE_TO_ONE_NAT"
+ access_config.network_tier = "PREMIUM"
+ network_interface.access_configs = [access_config]
+
+ template = compute_v1.InstanceTemplate()
+ template.name = template_name
+ template.properties.disks = [disk]
+ template.properties.machine_type = "e2-standard-4"
+ template.properties.network_interfaces = [network_interface]
+
+ template_client = compute_v1.InstanceTemplatesClient()
+ operation_client = compute_v1.GlobalOperationsClient()
+ op = template_client.insert_unary(
+ project=project_id, instance_template_resource=template
+ )
+ operation_client.wait(project=project_id, operation=op.name)
+
+ return template_client.get(project=project_id, instance_template=template_name)
+#
diff --git a/samples/ingredients/instance-templates/create_from_instance.py b/samples/ingredients/instance-templates/create_from_instance.py
new file mode 100644
index 000000000..584e2f177
--- /dev/null
+++ b/samples/ingredients/instance-templates/create_from_instance.py
@@ -0,0 +1,64 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+from google.cloud import compute_v1
+
+
+#
+def create_template_from_instance(
+ project_id: str, instance: str, template_name: str
+) -> compute_v1.InstanceTemplate:
+ """
+ Create a new instance template based on an existing instance.
+ This new template specifies a different boot disk.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you use.
+ instance: the instance to base the new template on. This value uses
+ the following format: "projects/{project}/zones/{zone}/instances/{instance_name}"
+ template_name: name of the new template to create.
+
+ Returns:
+ InstanceTemplate object that represents the new instance template.
+ """
+ disk = compute_v1.DiskInstantiationConfig()
+ # Device name must match the name of a disk attached to the instance you are
+ # basing your template on.
+ disk.device_name = "disk-1"
+ # Replace the original boot disk image used in your instance with a Rocky Linux image.
+ disk.instantiate_from = "CUSTOM_IMAGE"
+ disk.custom_image = "projects/rocky-linux-cloud/global/images/family/rocky-linux-8"
+ # Override the auto_delete setting.
+ disk.auto_delete = True
+
+ template = compute_v1.InstanceTemplate()
+ template.name = template_name
+ template.source_instance = instance
+ template.source_instance_params = compute_v1.SourceInstanceParams()
+ template.source_instance_params.disk_configs = [disk]
+
+ template_client = compute_v1.InstanceTemplatesClient()
+ operation_client = compute_v1.GlobalOperationsClient()
+ op = template_client.insert_unary(
+ project=project_id, instance_template_resource=template
+ )
+ operation_client.wait(project=project_id, operation=op.name)
+
+ return template_client.get(project=project_id, instance_template=template_name)
+#
diff --git a/samples/ingredients/instance-templates/create_with_subnet.py b/samples/ingredients/instance-templates/create_with_subnet.py
new file mode 100644
index 000000000..fb80d2510
--- /dev/null
+++ b/samples/ingredients/instance-templates/create_with_subnet.py
@@ -0,0 +1,73 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+from google.cloud import compute_v1
+
+
+#
+def create_template_with_subnet(
+ project_id: str, network: str, subnetwork: str, template_name: str
+) -> compute_v1.InstanceTemplate:
+ """
+ Create an instance template that uses a provided subnet.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you use.
+ network: the network to be used in the new template. This value uses
+ the following format: "projects/{project}/global/networks/{network}"
+ subnetwork: the subnetwork to be used in the new template. This value
+ uses the following format: "projects/{project}/regions/{region}/subnetworks/{subnetwork}"
+ template_name: name of the new template to create.
+
+ Returns:
+ InstanceTemplate object that represents the new instance template.
+ """
+ # The template describes the size and source image of the book disk to
+ # attach to the instance.
+ disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = (
+ "projects/debian-cloud/global/images/family/debian-11"
+ )
+ initialize_params.disk_size_gb = 250
+ disk.initialize_params = initialize_params
+ disk.auto_delete = True
+ disk.boot = True
+
+ template = compute_v1.InstanceTemplate()
+ template.name = template_name
+ template.properties = compute_v1.InstanceProperties()
+ template.properties.disks = [disk]
+ template.properties.machine_type = "e2-standard-4"
+
+ # The template connects the instance to the specified network and subnetwork.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.network = network
+ network_interface.subnetwork = subnetwork
+ template.properties.network_interfaces = [network_interface]
+
+ template_client = compute_v1.InstanceTemplatesClient()
+ operation_client = compute_v1.GlobalOperationsClient()
+ op = template_client.insert_unary(
+ project=project_id, instance_template_resource=template
+ )
+ operation_client.wait(project=project_id, operation=op.name)
+
+ return template_client.get(project=project_id, instance_template=template_name)
+#
diff --git a/samples/ingredients/instance-templates/delete.py b/samples/ingredients/instance-templates/delete.py
new file mode 100644
index 000000000..23bd929ee
--- /dev/null
+++ b/samples/ingredients/instance-templates/delete.py
@@ -0,0 +1,39 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+from google.cloud import compute_v1
+
+
+#
+def delete_instance_template(project_id: str, template_name: str):
+ """
+ Delete an instance template.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you use.
+ template_name: name of the template to delete.
+ """
+ template_client = compute_v1.InstanceTemplatesClient()
+ operation_client = compute_v1.GlobalOperationsClient()
+ op = template_client.delete_unary(
+ project=project_id, instance_template=template_name
+ )
+ operation_client.wait(project=project_id, operation=op.name)
+ return
+#
diff --git a/samples/ingredients/instance-templates/get.py b/samples/ingredients/instance-templates/get.py
new file mode 100644
index 000000000..99aae684d
--- /dev/null
+++ b/samples/ingredients/instance-templates/get.py
@@ -0,0 +1,40 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+from google.cloud import compute_v1
+
+
+#
+def get_instance_template(
+ project_id: str, template_name: str
+) -> compute_v1.InstanceTemplate:
+ """
+ Retrieve an instance template, which you can use to create virtual machine
+ (VM) instances and managed instance groups (MIGs).
+
+ Args:
+ project_id: project ID or project number of the Cloud project you use.
+ template_name: name of the template to retrieve.
+
+ Returns:
+ InstanceTemplate object that represents the retrieved template.
+ """
+ template_client = compute_v1.InstanceTemplatesClient()
+ return template_client.get(project=project_id, instance_template=template_name)
+#
diff --git a/samples/ingredients/instance-templates/list.py b/samples/ingredients/instance-templates/list.py
new file mode 100644
index 000000000..851e2c48e
--- /dev/null
+++ b/samples/ingredients/instance-templates/list.py
@@ -0,0 +1,37 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+from typing import Iterable
+from google.cloud import compute_v1
+
+
+#
+def list_instance_templates(project_id: str) -> Iterable[compute_v1.InstanceTemplate]:
+ """
+ Get a list of InstanceTemplate objects available in a project.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you use.
+
+ Returns:
+ Iterable list of InstanceTemplate objects.
+ """
+ template_client = compute_v1.InstanceTemplatesClient()
+ return template_client.list(project=project_id)
+#
diff --git a/samples/ingredients/instances/__init__.py b/samples/ingredients/instances/__init__.py
new file mode 100644
index 000000000..81d8b9be3
--- /dev/null
+++ b/samples/ingredients/instances/__init__.py
@@ -0,0 +1,18 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
diff --git a/samples/ingredients/instances/create_instance.py b/samples/ingredients/instances/create_instance.py
new file mode 100644
index 000000000..85c2e4818
--- /dev/null
+++ b/samples/ingredients/instances/create_instance.py
@@ -0,0 +1,124 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+import re
+import sys
+from google.cloud import compute_v1
+import time
+from typing import List
+
+
+#
+def create_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
+ """
+ Send an instance creation request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ machine_type: machine type of the VM being created. This value uses the
+ following format: "zones/{zone}/machineTypes/{type_name}".
+ For example: "zones/europe-west3-c/machineTypes/f1-micro"
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ # Use the network interface provided in the network_link argument.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
+
+ # Collect information into the Instance object.
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
+ instance.network_interfaces = [network_interface]
+
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Prepare the request to insert an instance.
+ request = compute_v1.InsertInstanceRequest()
+ request.zone = zone
+ request.project = project_id
+ request.instance_resource = instance
+
+ # Wait for the create operation to complete.
+ print(f"Creating the {instance_name} instance in {zone}...")
+
+ operation = instance_client.insert_unary(request=request)
+ start = time.time()
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if time.time() - start >= 300: # 5 minutes
+ raise TimeoutError()
+ if operation.error:
+ print("Error during creation:", operation.error, file=sys.stderr)
+ raise RuntimeError(operation.error)
+ if operation.warnings:
+ print("Warning during creation:", operation.warnings, file=sys.stderr)
+ print(f"Instance {instance_name} created.")
+ return instance
+#
diff --git a/samples/ingredients/instances/create_instance_from_template.py b/samples/ingredients/instances/create_instance_from_template.py
new file mode 100644
index 000000000..73ff814f4
--- /dev/null
+++ b/samples/ingredients/instances/create_instance_from_template.py
@@ -0,0 +1,57 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+from google.cloud import compute_v1
+
+
+#
+def create_instance_from_template(
+ project_id: str, zone: str, instance_name: str, instance_template_url: str
+) -> compute_v1.Instance:
+ """
+ Creates a Compute Engine VM instance from an instance template.
+
+ Args:
+ project_id: ID or number of the project you want to use.
+ zone: Name of the zone you want to check, for example: us-west3-b
+ instance_name: Name of the new instance.
+ instance_template_url: URL of the instance template used for creating the new instance.
+ It can be a full or partial URL.
+ Examples:
+ - https://www.googleapis.com/compute/v1/projects/project/global/instanceTemplates/example-instance-template
+ - projects/project/global/instanceTemplates/example-instance-template
+ - global/instanceTemplates/example-instance-template
+
+ Returns:
+ Instance object.
+ """
+ operation_client = compute_v1.ZoneOperationsClient()
+ instance_client = compute_v1.InstancesClient()
+
+ instance_insert_request = compute_v1.InsertInstanceRequest()
+ instance_insert_request.project = project_id
+ instance_insert_request.zone = zone
+ instance_insert_request.source_instance_template = instance_template_url
+ instance_insert_request.instance_resource.name = instance_name
+
+ op = instance_client.insert_unary(instance_insert_request)
+ operation_client.wait(project=project_id, zone=zone, operation=op.name)
+
+ return instance_client.get(project=project_id, zone=zone, instance=instance_name)
+#
diff --git a/samples/ingredients/instances/create_instance_from_template_with_overrides.py b/samples/ingredients/instances/create_instance_from_template_with_overrides.py
new file mode 100644
index 000000000..001cb5179
--- /dev/null
+++ b/samples/ingredients/instances/create_instance_from_template_with_overrides.py
@@ -0,0 +1,97 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+from google.cloud import compute_v1
+
+
+#
+def create_instance_from_template_with_overrides(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ instance_template_name: str,
+ machine_type: str,
+ new_disk_source_image: str,
+) -> compute_v1.Instance:
+ """
+ Creates a Compute Engine VM instance from an instance template, changing the machine type and
+ adding a new disk created from a source image.
+
+ Args:
+ project_id: ID or number of the project you want to use.
+ zone: Name of the zone you want to check, for example: us-west3-b
+ instance_name: Name of the new instance.
+ instance_template_name: Name of the instance template used for creating the new instance.
+ machine_type: Machine type you want to set in following format:
+ "zones/{zone}/machineTypes/{type_name}". For example:
+ - "zones/europe-west3-c/machineTypes/f1-micro"
+ - You can find the list of available machine types using:
+ https://cloud.google.com/sdk/gcloud/reference/compute/machine-types/list
+ new_disk_source_image: Path the the disk image you want to use for your new
+ disk. This can be one of the public images
+ (like "projects/debian-cloud/global/images/family/debian-10")
+ or a private image you have access to.
+ For a list of available public images, see the documentation:
+ http://cloud.google.com/compute/docs/images
+
+ Returns:
+ Instance object.
+ """
+ operation_client = compute_v1.ZoneOperationsClient()
+ instance_client = compute_v1.InstancesClient()
+ instance_template_client = compute_v1.InstanceTemplatesClient()
+
+ # Retrieve an instance template by name.
+ instance_template = instance_template_client.get(
+ project=project_id, instance_template=instance_template_name
+ )
+
+ # Adjust diskType field of the instance template to use the URL formatting required by instances.insert.diskType
+ # For instance template, there is only a name, not URL.
+ for disk in instance_template.properties.disks:
+ if disk.initialize_params.disk_type:
+ disk.initialize_params.disk_type = (
+ f"zones/{zone}/diskTypes/{disk.initialize_params.disk_type}"
+ )
+
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.machine_type = machine_type
+ instance.disks = instance_template.properties.disks
+
+ new_disk = compute_v1.AttachedDisk()
+ new_disk.initialize_params.disk_size_gb = 50
+ new_disk.initialize_params.source_image = new_disk_source_image
+ new_disk.auto_delete = True
+ new_disk.boot = False
+ new_disk.type_ = "PERSISTENT"
+
+ instance.disks.append(new_disk)
+
+ instance_insert_request = compute_v1.InsertInstanceRequest()
+ instance_insert_request.project = project_id
+ instance_insert_request.zone = zone
+ instance_insert_request.instance_resource = instance
+ instance_insert_request.source_instance_template = instance_template.self_link
+
+ op = instance_client.insert_unary(instance_insert_request)
+ operation_client.wait(project=project_id, zone=zone, operation=op.name)
+
+ return instance_client.get(project=project_id, zone=zone, instance=instance_name)
+#
\ No newline at end of file
diff --git a/samples/ingredients/instances/create_start_instance/create_from_custom_image.py b/samples/ingredients/instances/create_start_instance/create_from_custom_image.py
new file mode 100644
index 000000000..2d297cbca
--- /dev/null
+++ b/samples/ingredients/instances/create_start_instance/create_from_custom_image.py
@@ -0,0 +1,61 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+from google.cloud import compute_v1
+
+
+#
+def create_from_custom_image(
+ project_id: str, zone: str, instance_name: str, custom_image_link: str
+) -> compute_v1.Instance:
+ """
+ Create a new VM instance with custom image used as its boot disk.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ custom_image_link: link to the custom image you want to use in the form of:
+ "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ Instance object.
+ """
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, custom_image_link)]
+ instance = create_instance(project_id, zone, instance_name, disks)
+ return instance
+#
diff --git a/samples/ingredients/instances/create_start_instance/create_from_public_image.py b/samples/ingredients/instances/create_start_instance/create_from_public_image.py
new file mode 100644
index 000000000..2eb8e3c2e
--- /dev/null
+++ b/samples/ingredients/instances/create_start_instance/create_from_public_image.py
@@ -0,0 +1,42 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+from google.cloud import compute_v1
+
+#
+def create_from_public_image(project_id: str, zone: str, instance_name: str) -> compute_v1.Instance:
+ """
+ Create a new VM instance with Debian 10 operating system.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+
+ Returns:
+ Instance object.
+ """
+ newest_debian = get_image_from_family(
+ project="debian-cloud", family="debian-10"
+ )
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+ instance = create_instance(project_id, zone, instance_name, disks)
+ return instance
+#
diff --git a/samples/ingredients/instances/create_start_instance/create_from_snapshot.py b/samples/ingredients/instances/create_start_instance/create_from_snapshot.py
new file mode 100644
index 000000000..a2729332c
--- /dev/null
+++ b/samples/ingredients/instances/create_start_instance/create_from_snapshot.py
@@ -0,0 +1,43 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+
+#
+def create_from_snapshot(
+ project_id: str, zone: str, instance_name: str, snapshot_link: str
+):
+ """
+ Create a new VM instance with boot disk created from a snapshot. The
+ new boot disk will have 20 gigabytes.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ snapshot_link: link to the snapshot you want to use as the source of your
+ boot disk in the form of: "projects/{project_name}/global/snapshots/{snapshot_name}"
+
+ Returns:
+ Instance object.
+ """
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_snapshot(disk_type, 20, True, snapshot_link)]
+ instance = create_instance(project_id, zone, instance_name, disks)
+ return instance
+#
diff --git a/samples/ingredients/instances/create_start_instance/create_with_additional_disk.py b/samples/ingredients/instances/create_start_instance/create_with_additional_disk.py
new file mode 100644
index 000000000..b921f27a3
--- /dev/null
+++ b/samples/ingredients/instances/create_start_instance/create_with_additional_disk.py
@@ -0,0 +1,46 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def create_with_additional_disk(project_id: str, zone: str, instance_name: str) -> compute_v1.Instance:
+ """
+ Create a new VM instance with Debian 10 operating system on a 20 GB disk
+ and a 25 GB additional empty disk.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+
+ Returns:
+ Instance object.
+ """
+ newest_debian = get_image_from_family(
+ project="debian-cloud", family="debian-10"
+ )
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [
+ disk_from_image(disk_type, 20, True, newest_debian.self_link),
+ empty_disk(disk_type, 25),
+ ]
+ instance = create_instance(project_id, zone, instance_name, disks)
+ return instance
+#
\ No newline at end of file
diff --git a/samples/ingredients/instances/create_start_instance/create_with_snapshotted_data_disk.py b/samples/ingredients/instances/create_start_instance/create_with_snapshotted_data_disk.py
new file mode 100644
index 000000000..ea87201e5
--- /dev/null
+++ b/samples/ingredients/instances/create_start_instance/create_with_snapshotted_data_disk.py
@@ -0,0 +1,48 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+
+#
+def create_with_snapshotted_data_disk(
+ project_id: str, zone: str, instance_name: str, snapshot_link: str
+):
+ """
+ Create a new VM instance with Debian 10 operating system and data disk created from snapshot.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ snapshot_link: link to the snapshot you want to use as the source of your
+ data disk in the form of: "projects/{project_name}/global/snapshots/{snapshot_name}"
+
+ Returns:
+ Instance object.
+ """
+ newest_debian = get_image_from_family(
+ project="debian-cloud", family="debian-10"
+ )
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [
+ disk_from_image(disk_type, 10, True, newest_debian.self_link),
+ disk_from_snapshot(disk_type, 11, False, snapshot_link),
+ ]
+ instance = create_instance(project_id, zone, instance_name, disks)
+ return instance
+#
diff --git a/samples/ingredients/instances/create_with_subnet.py b/samples/ingredients/instances/create_with_subnet.py
new file mode 100644
index 000000000..bc39ff223
--- /dev/null
+++ b/samples/ingredients/instances/create_with_subnet.py
@@ -0,0 +1,57 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def create_with_subnet(
+ project_id: str, zone: str, instance_name: str, network_link: str, subnet_link: str
+) -> compute_v1.Instance:
+ """
+ Create a new VM instance with Debian 10 operating system in specified network and subnetwork.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+
+ Returns:
+ Instance object.
+ """
+ newest_debian = get_image_from_family(
+ project="debian-cloud", family="debian-10"
+ )
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+ instance = create_instance(
+ project_id,
+ zone,
+ instance_name,
+ disks,
+ network_link=network_link,
+ subnetwork_link=subnet_link,
+ )
+ return instance
+#
diff --git a/samples/ingredients/instances/custom_hostname/create.py b/samples/ingredients/instances/custom_hostname/create.py
new file mode 100644
index 000000000..9a990cb9f
--- /dev/null
+++ b/samples/ingredients/instances/custom_hostname/create.py
@@ -0,0 +1,43 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def create_instance_custom_hostname(project_id: str, zone: str, instance_name: str, hostname: str) -> compute_v1.Instance:
+ """
+ Create a new VM instance with Debian 10 operating system and a custom hostname.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ hostname: the hostname you want to use for the new instance.
+
+ Returns:
+ Instance object.
+ """
+ newest_debian = get_image_from_family(
+ project="debian-cloud", family="debian-11"
+ )
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+ instance = create_instance(project_id, zone, instance_name, disks, custom_hostname=hostname)
+ return instance
+#
diff --git a/samples/ingredients/instances/custom_hostname/get.py b/samples/ingredients/instances/custom_hostname/get.py
new file mode 100644
index 000000000..b362fce26
--- /dev/null
+++ b/samples/ingredients/instances/custom_hostname/get.py
@@ -0,0 +1,40 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def get_hostname(project_id: str, zone: str, instance_name: str) -> str:
+ """
+ Retrieve the hostname of given instance.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: "us-west3-b"
+ instance_name: name of the virtual machine to check.
+
+ Returns:
+ The hostname of an instance.
+ """
+ instance_client = compute_v1.InstancesClient()
+ instance = instance_client.get(
+ project=project_id, zone=zone, instance=instance_name
+ )
+ return instance.hostname
+#
diff --git a/samples/ingredients/instances/custom_machine_types/create_extra_mem_no_helper.py b/samples/ingredients/instances/custom_machine_types/create_extra_mem_no_helper.py
new file mode 100644
index 000000000..536455f66
--- /dev/null
+++ b/samples/ingredients/instances/custom_machine_types/create_extra_mem_no_helper.py
@@ -0,0 +1,71 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from typing import List
+
+from google.cloud import compute_v1
+
+
+#
+def create_custom_instances_extra_mem(
+ project_id: str, zone: str, instance_name: str, core_count: int, memory: int
+) -> List[compute_v1.Instance]:
+ """
+ Create 3 new VM instances with extra memory without using a CustomMachineType helper class.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ core_count: number of CPU cores you want to use.
+ memory: the amount of memory for the VM instance, in megabytes.
+
+ Returns:
+ List of Instance objects.
+ """
+ newest_debian = get_image_from_family(
+ project="debian-cloud", family="debian-10"
+ )
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+ # The core_count and memory values are not validated anywhere and can be rejected by the API.
+ instances = [
+ create_instance(
+ project_id,
+ zone,
+ f"{instance_name}_n1_extra_mem",
+ disks,
+ f"zones/{zone}/machineTypes/custom-{core_count}-{memory}-ext",
+ ),
+ create_instance(
+ project_id,
+ zone,
+ f"{instance_name}_n2_extra_mem",
+ disks,
+ f"zones/{zone}/machineTypes/n2-custom-{core_count}-{memory}-ext",
+ ),
+ create_instance(
+ project_id,
+ zone,
+ f"{instance_name}_n2d_extra_mem",
+ disks,
+ f"zones/{zone}/machineTypes/n2d-custom-{core_count}-{memory}-ext",
+ ),
+ ]
+ return instances
+#
diff --git a/samples/ingredients/instances/custom_machine_types/create_shared_with_helper.py b/samples/ingredients/instances/custom_machine_types/create_shared_with_helper.py
new file mode 100644
index 000000000..a29193438
--- /dev/null
+++ b/samples/ingredients/instances/custom_machine_types/create_shared_with_helper.py
@@ -0,0 +1,60 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+
+from google.cloud import compute_v1
+
+
+#
+def create_custom_shared_core_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ cpu_series: CustomMachineType.CPUSeries,
+ memory: int,
+) -> compute_v1.Instance:
+ """
+ Create a new VM instance with a custom type using shared CPUs.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ cpu_series: the type of CPU you want to use. Pick one value from the CustomMachineType.CPUSeries enum.
+ For example: CustomMachineType.CPUSeries.E2_MICRO
+ memory: the amount of memory for the VM instance, in megabytes.
+
+ Return:
+ Instance object.
+ """
+ assert cpu_series in (
+ CustomMachineType.CPUSeries.E2_MICRO,
+ CustomMachineType.CPUSeries.E2_SMALL,
+ CustomMachineType.CPUSeries.E2_MEDIUM,
+ )
+ custom_type = CustomMachineType(zone, cpu_series, memory)
+
+ newest_debian = get_image_from_family(
+ project="debian-cloud", family="debian-10"
+ )
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+
+ return create_instance(project_id, zone, instance_name, disks, str(custom_type))
+#
diff --git a/samples/ingredients/instances/custom_machine_types/create_with_helper.py b/samples/ingredients/instances/custom_machine_types/create_with_helper.py
new file mode 100644
index 000000000..2731f40da
--- /dev/null
+++ b/samples/ingredients/instances/custom_machine_types/create_with_helper.py
@@ -0,0 +1,61 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def create_custom_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ cpu_series: CustomMachineType.CPUSeries,
+ core_count: int,
+ memory: int,
+) -> compute_v1.Instance:
+ """
+ Create a new VM instance with a custom machine type.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ cpu_series: the type of CPU you want to use. Select one value from the CustomMachineType.CPUSeries enum.
+ For example: CustomMachineType.CPUSeries.N2
+ core_count: number of CPU cores you want to use.
+ memory: the amount of memory for the VM instance, in megabytes.
+
+ Return:
+ Instance object.
+ """
+ assert cpu_series in (
+ CustomMachineType.CPUSeries.E2,
+ CustomMachineType.CPUSeries.N1,
+ CustomMachineType.CPUSeries.N2,
+ CustomMachineType.CPUSeries.N2D,
+ )
+ custom_type = CustomMachineType(zone, cpu_series, memory, core_count)
+
+ newest_debian = get_image_from_family(
+ project="debian-cloud", family="debian-10"
+ )
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+
+ return create_instance(project_id, zone, instance_name, disks, str(custom_type))
+#
diff --git a/samples/ingredients/instances/custom_machine_types/create_without_helper.py b/samples/ingredients/instances/custom_machine_types/create_without_helper.py
new file mode 100644
index 000000000..a17a979bb
--- /dev/null
+++ b/samples/ingredients/instances/custom_machine_types/create_without_helper.py
@@ -0,0 +1,60 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+
+from typing import List
+
+from google.cloud import compute_v1
+
+
+#
+def create_custom_instances_no_helper(
+ project_id: str, zone: str, instance_name: str, core_count: int, memory: int
+) -> List[compute_v1.Instance]:
+ """
+ Create 7 new VM instances without using a CustomMachineType helper function.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ core_count: number of CPU cores you want to use.
+ memory: the amount of memory for the VM instance, in megabytes.
+
+ Returns:
+ List of Instance objects.
+ """
+ newest_debian = get_image_from_family(
+ project="debian-cloud", family="debian-10"
+ )
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+ params = [
+ (f"{instance_name}_n1", f"zones/{zone}/machineTypes/custom-{core_count}-{memory}"),
+ (f"{instance_name}_n2", f"zones/{zone}/machineTypes/n2-custom-{core_count}-{memory}"),
+ (f"{instance_name}_n2d", f"zones/{zone}/machineTypes/n2d-custom-{core_count}-{memory}"),
+ (f"{instance_name}_e2", f"zones/{zone}/machineTypes/e2-custom-{core_count}-{memory}"),
+ (f"{instance_name}_e2_micro", f"zones/{zone}/machineTypes/e2-custom-micro-{memory}"),
+ (f"{instance_name}_e2_small", f"zones/{zone}/machineTypes/e2-custom-small-{memory}"),
+ (f"{instance_name}_e2_medium", f"zones/{zone}/machineTypes/e2-custom-medium-{memory}"),
+ ]
+ # The core_count and memory values are not validated anywhere and can be rejected by the API.
+ instances = [create_instance(project_id, zone, name, disks, type) for name, type in params]
+ return instances
+#
diff --git a/samples/ingredients/instances/custom_machine_types/helper_class.py b/samples/ingredients/instances/custom_machine_types/helper_class.py
new file mode 100644
index 000000000..616961943
--- /dev/null
+++ b/samples/ingredients/instances/custom_machine_types/helper_class.py
@@ -0,0 +1,211 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from collections import namedtuple
+from enum import Enum, unique
+
+
+#
+def gb_to_mb(value: int) -> int:
+ return value << 10
+
+
+class CustomMachineType:
+ """
+ Allows to create custom machine types to be used with the VM instances.
+ """
+
+ @unique
+ class CPUSeries(Enum):
+ N1 = "custom"
+ N2 = "n2-custom"
+ N2D = "n2d-custom"
+ E2 = "e2-custom"
+ E2_MICRO = "e2-custom-micro"
+ E2_SMALL = "e2-custom-small"
+ E2_MEDIUM = "e2-custom-medium"
+
+ TypeLimits = namedtuple(
+ "TypeLimits",
+ [
+ "allowed_cores",
+ "min_mem_per_core",
+ "max_mem_per_core",
+ "allow_extra_memory",
+ "extra_memory_limit",
+ ],
+ )
+
+ # The limits for various CPU types are described on:
+ # https://cloud.google.com/compute/docs/general-purpose-machines
+ LIMITS = {
+ CPUSeries.E2: TypeLimits(frozenset(range(2, 33, 2)), 512, 8192, False, 0),
+ CPUSeries.E2_MICRO: TypeLimits(frozenset(), 1024, 2048, False, 0),
+ CPUSeries.E2_SMALL: TypeLimits(frozenset(), 2048, 4096, False, 0),
+ CPUSeries.E2_MEDIUM: TypeLimits(frozenset(), 4096, 8192, False, 0),
+ CPUSeries.N2: TypeLimits(
+ frozenset(range(2, 33, 2)).union(set(range(36, 129, 4))),
+ 512,
+ 8192,
+ True,
+ gb_to_mb(624),
+ ),
+ CPUSeries.N2D: TypeLimits(
+ frozenset({2, 4, 8, 16, 32, 48, 64, 80, 96}), 512, 8192, True, gb_to_mb(768)
+ ),
+ CPUSeries.N1: TypeLimits(
+ frozenset({1}.union(range(2, 97, 2))), 922, 6656, True, gb_to_mb(624)
+ ),
+ }
+
+ def __init__(
+ self, zone: str, cpu_series: CPUSeries, memory_mb: int, core_count: int = 0
+ ):
+ self.zone = zone
+ self.cpu_series = cpu_series
+ self.limits = self.LIMITS[self.cpu_series]
+ # Shared machine types (e2-small, e2-medium and e2-micro) always have
+ # 2 vCPUs: https://cloud.google.com/compute/docs/general-purpose-machines#e2_limitations
+ self.core_count = 2 if self.is_shared() else core_count
+ self.memory_mb = memory_mb
+ self._checked = False
+ self._check_parameters()
+ self.extra_memory_used = self._check_extra_memory()
+
+ def is_shared(self):
+ return self.cpu_series in (
+ CustomMachineType.CPUSeries.E2_SMALL,
+ CustomMachineType.CPUSeries.E2_MICRO,
+ CustomMachineType.CPUSeries.E2_MEDIUM,
+ )
+
+ def _check_extra_memory(self) -> bool:
+ if self._checked:
+ return self.memory_mb > self.core_count * self.limits.max_mem_per_core
+ else:
+ raise RuntimeError("You need to call _check_parameters() before calling _check_extra_memory()")
+
+ def _check_parameters(self):
+ """
+ Check whether the requested parameters are allowed. Find more information about limitations of custom machine
+ types at: https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types
+ """
+ # Check the number of cores
+ if (
+ self.limits.allowed_cores
+ and self.core_count not in self.limits.allowed_cores
+ ):
+ raise RuntimeError(
+ f"Invalid number of cores requested. Allowed number of cores for {self.cpu_series.name} is: {sorted(self.limits.allowed_cores)}"
+ )
+
+ # Memory must be a multiple of 256 MB
+ if self.memory_mb % 256 != 0:
+ raise RuntimeError("Requested memory must be a multiple of 256 MB.")
+
+ # Check if the requested memory isn't too little
+ if self.memory_mb < self.core_count * self.limits.min_mem_per_core:
+ raise RuntimeError(
+ f"Requested memory is too low. Minimal memory for {self.cpu_series.name} is {self.limits.min_mem_per_core} MB per core."
+ )
+
+ # Check if the requested memory isn't too much
+ if self.memory_mb > self.core_count * self.limits.max_mem_per_core:
+ if self.limits.allow_extra_memory:
+ if self.memory_mb > self.limits.extra_memory_limit:
+ raise RuntimeError(
+ f"Requested memory is too large.. Maximum memory allowed for {self.cpu_series.name} is {self.limits.extra_memory_limit} MB."
+ )
+ else:
+ raise RuntimeError(
+ f"Requested memory is too large.. Maximum memory allowed for {self.cpu_series.name} is {self.limits.max_mem_per_core} MB per core."
+ )
+
+ self._checked = True
+
+ def __str__(self) -> str:
+ """
+ Return the custom machine type in form of a string acceptable by Compute Engine API.
+ """
+ if self.cpu_series in {
+ self.CPUSeries.E2_SMALL,
+ self.CPUSeries.E2_MICRO,
+ self.CPUSeries.E2_MEDIUM,
+ }:
+ return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.memory_mb}"
+
+ if self.extra_memory_used:
+ return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.core_count}-{self.memory_mb}-ext"
+
+ return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.core_count}-{self.memory_mb}"
+
+ def short_type_str(self) -> str:
+ """
+ Return machine type in a format without the zone. For example, n2-custom-0-10240.
+ This format is used to create instance templates.
+ """
+ return str(self).rsplit("/", maxsplit=1)[1]
+
+ @classmethod
+ def from_str(cls, machine_type: str):
+ """
+ Construct a new object from a string. The string needs to be a valid custom machine type like:
+ - https://www.googleapis.com/compute/v1/projects/diregapic-mestiv/zones/us-central1-b/machineTypes/e2-custom-4-8192
+ - zones/us-central1-b/machineTypes/e2-custom-4-8192
+ - e2-custom-4-8192 (in this case, the zone parameter will not be set)
+ """
+ zone = None
+ if machine_type.startswith("http"):
+ machine_type = machine_type[machine_type.find("zones/") :]
+
+ if machine_type.startswith("zones/"):
+ _, zone, _, machine_type = machine_type.split("/")
+
+ extra_mem = machine_type.endswith("-ext")
+
+ if machine_type.startswith("custom"):
+ cpu = cls.CPUSeries.N1
+ _, cores, memory = machine_type.rsplit("-", maxsplit=2)
+ else:
+ if extra_mem:
+ cpu_series, _, cores, memory, _ = machine_type.split("-")
+ else:
+ cpu_series, _, cores, memory = machine_type.split("-")
+ if cpu_series == "n2":
+ cpu = cls.CPUSeries.N2
+ elif cpu_series == "n2d":
+ cpu = cls.CPUSeries.N2D
+ elif cpu_series == "e2":
+ cpu = cls.CPUSeries.E2
+ if cores == "micro":
+ cpu = cls.CPUSeries.E2_MICRO
+ cores = 2
+ elif cores == "small":
+ cpu = cls.CPUSeries.E2_SMALL
+ cores = 2
+ elif cores == "medium":
+ cpu = cls.CPUSeries.E2_MEDIUM
+ cores = 2
+ else:
+ raise RuntimeError("Unknown CPU series.")
+
+ cores = int(cores)
+ memory = int(memory)
+
+ return cls(zone, cpu, memory, cores)
+#
diff --git a/samples/ingredients/instances/custom_machine_types/update_memory.py b/samples/ingredients/instances/custom_machine_types/update_memory.py
new file mode 100644
index 000000000..ee9ed2a75
--- /dev/null
+++ b/samples/ingredients/instances/custom_machine_types/update_memory.py
@@ -0,0 +1,89 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+import time
+
+from google.cloud import compute_v1
+
+
+#
+def add_extended_memory_to_instance(
+ project_id: str, zone: str, instance_name: str, new_memory: int
+):
+ """
+ Modify an existing VM to use extended memory.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ new_memory: the amount of memory for the VM instance, in megabytes.
+
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+ instance = instance_client.get(
+ project=project_id, zone=zone, instance=instance_name
+ )
+
+ if not ("n1-" in instance.machine_type or "n2-" in instance.machine_type or "n2d-" in instance.machine_type):
+ raise RuntimeError("Extra memory is available only for N1, N2 and N2D CPUs.")
+
+ # Make sure that the machine is turned off
+ if instance.status not in (
+ instance.Status.TERMINATED.name,
+ instance.Status.STOPPED.name,
+ ):
+ op = instance_client.stop_unary(
+ project=project_id, zone=zone, instance=instance_name
+ )
+ operation_client.wait(project=project_id, zone=zone, operation=op.name)
+ start = time.time()
+ while instance.status not in (
+ instance.Status.TERMINATED.name,
+ instance.Status.STOPPED.name,
+ ):
+ # Waiting for the instance to be turned off.
+ instance = instance_client.get(
+ project=project_id, zone=zone, instance=instance_name
+ )
+ time.sleep(2)
+ if time.time() - start >= 300: # 5 minutes
+ raise TimeoutError()
+
+ # Modify the machine definition, remember that extended memory is available only for N1, N2 and N2D CPUs
+ start, end = instance.machine_type.rsplit("-", maxsplit=1)
+ instance.machine_type = start + f"-{new_memory}-ext"
+ # TODO: If you prefer to use the CustomMachineType helper class, uncomment this code and comment the 2 lines above
+ # Using CustomMachineType helper
+ # cmt = CustomMachineType.from_str(instance.machine_type)
+ # cmt.memory_mb = new_memory
+ # cmt.extra_memory_used = True
+ # instance.machine_type = str(cmt)
+ op = instance_client.update_unary(
+ project=project_id,
+ zone=zone,
+ instance=instance_name,
+ instance_resource=instance,
+ )
+ operation_client.wait(project=project_id, zone=zone, operation=op.name)
+
+ return instance_client.get(project=project_id, zone=zone, instance=instance_name)
+#
diff --git a/samples/ingredients/instances/delete.py b/samples/ingredients/instances/delete.py
new file mode 100644
index 000000000..ee84a349c
--- /dev/null
+++ b/samples/ingredients/instances/delete.py
@@ -0,0 +1,56 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+import sys
+import time
+
+from google.cloud import compute_v1
+
+
+#
+def delete_instance(project_id: str, zone: str, machine_name: str) -> None:
+ """
+ Send an instance deletion request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: “us-west3-b”
+ machine_name: name of the machine you want to delete.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ print(f"Deleting {machine_name} from {zone}...")
+ operation = instance_client.delete_unary(
+ project=project_id, zone=zone, instance=machine_name
+ )
+ start = time.time()
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if time.time() - start >= 300: # 5 minutes
+ raise TimeoutError()
+ if operation.error:
+ print("Error during deletion:", operation.error, file=sys.stderr)
+ return
+ if operation.warnings:
+ print("Warning during deletion:", operation.warnings, file=sys.stderr)
+ print(f"Instance {machine_name} deleted.")
+ return
+#
diff --git a/samples/ingredients/instances/delete_protection/__init__.py b/samples/ingredients/instances/delete_protection/__init__.py
new file mode 100644
index 000000000..8fb7cb024
--- /dev/null
+++ b/samples/ingredients/instances/delete_protection/__init__.py
@@ -0,0 +1,19 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
diff --git a/samples/ingredients/instances/delete_protection/create.py b/samples/ingredients/instances/delete_protection/create.py
new file mode 100644
index 000000000..eb431ec7e
--- /dev/null
+++ b/samples/ingredients/instances/delete_protection/create.py
@@ -0,0 +1,44 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+from google.cloud import compute_v1
+
+
+#
+def create_protected_instance(project_id: str, zone: str, instance_name: str) -> compute_v1.Instance:
+ """
+ Create a new VM instance with Debian 10 operating system and delete protection
+ turned on.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+
+ Returns:
+ Instance object.
+ """
+ newest_debian = get_image_from_family(
+ project="debian-cloud", family="debian-11"
+ )
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+ instance = create_instance(project_id, zone, instance_name, disks, delete_protection=True)
+ return instance
+#
\ No newline at end of file
diff --git a/samples/ingredients/instances/delete_protection/get.py b/samples/ingredients/instances/delete_protection/get.py
new file mode 100644
index 000000000..f57b1624e
--- /dev/null
+++ b/samples/ingredients/instances/delete_protection/get.py
@@ -0,0 +1,38 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def get_delete_protection(project_id: str, zone: str, instance_name: str) -> bool:
+ """
+ Returns the state of delete protection flag of given instance.
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: “us-west3-b”
+ instance_name: name of the virtual machine to check.
+ Returns:
+ The boolean value of the delete protection setting.
+ """
+ instance_client = compute_v1.InstancesClient()
+ instance = instance_client.get(
+ project=project_id, zone=zone, instance=instance_name
+ )
+ return instance.deletion_protection
+#
diff --git a/samples/ingredients/instances/delete_protection/set.py b/samples/ingredients/instances/delete_protection/set.py
new file mode 100644
index 000000000..fd7bd4ca9
--- /dev/null
+++ b/samples/ingredients/instances/delete_protection/set.py
@@ -0,0 +1,47 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def set_delete_protection(
+ project_id: str, zone: str, instance_name: str, delete_protection: bool
+) -> None:
+ """
+ Updates the delete protection setting of given instance.
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: “us-west3-b”
+ instance_name: name of the instance to update.
+ delete_protection: boolean value indicating if the virtual machine should be
+ protected against deletion or not.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ request = compute_v1.SetDeletionProtectionInstanceRequest()
+ request.project = project_id
+ request.zone = zone
+ request.resource = instance_name
+ request.deletion_protection = delete_protection
+
+ operation = instance_client.set_deletion_protection_unary(request)
+ operation_client.wait(project=project_id, zone=zone, operation=operation.name)
+ return
+#
diff --git a/samples/ingredients/instances/list.py b/samples/ingredients/instances/list.py
new file mode 100644
index 000000000..089f7fdab
--- /dev/null
+++ b/samples/ingredients/instances/list.py
@@ -0,0 +1,44 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from typing import Iterable
+
+from google.cloud import compute_v1
+
+
+#
+def list_instances(project_id: str, zone: str) -> Iterable[compute_v1.Instance]:
+ """
+ List all instances in the given zone in the specified project.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: “us-west3-b”
+ Returns:
+ An iterable collection of Instance objects.
+ """
+ instance_client = compute_v1.InstancesClient()
+ instance_list = instance_client.list(project=project_id, zone=zone)
+
+ print(f"Instances found in zone {zone}:")
+ for instance in instance_list:
+ print(f" - {instance.name} ({instance.machine_type})")
+
+ return instance_list
+#
+
diff --git a/samples/ingredients/instances/list_all.py b/samples/ingredients/instances/list_all.py
new file mode 100644
index 000000000..ced8e7a1f
--- /dev/null
+++ b/samples/ingredients/instances/list_all.py
@@ -0,0 +1,58 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from typing import Dict, Iterable
+
+from google.cloud import compute_v1
+
+
+#
+def list_all_instances(
+ project_id: str,
+) -> Dict[str, Iterable[compute_v1.Instance]]:
+ """
+ Returns a dictionary of all instances present in a project, grouped by their zone.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ Returns:
+ A dictionary with zone names as keys (in form of "zones/{zone_name}") and
+ iterable collections of Instance objects as values.
+ """
+ instance_client = compute_v1.InstancesClient()
+ request = compute_v1.AggregatedListInstancesRequest()
+ request.project = project_id
+ # Use the `max_results` parameter to limit the number of results that the API returns per response page.
+ request.max_results = 50
+
+ agg_list = instance_client.aggregated_list(request=request)
+
+ all_instances = {}
+ print("Instances found:")
+ # Despite using the `max_results` parameter, you don't need to handle the pagination
+ # yourself. The returned `AggregatedListPager` object handles pagination
+ # automatically, returning separated pages as you iterate over the results.
+ for zone, response in agg_list:
+ if response.instances:
+ all_instances[zone] = response.instances
+ print(f" {zone}:")
+ for instance in response.instances:
+ print(f" - {instance.name} ({instance.machine_type})")
+ return all_instances
+#
+
diff --git a/samples/ingredients/instances/preemptible/__init__.py b/samples/ingredients/instances/preemptible/__init__.py
new file mode 100644
index 000000000..81d8b9be3
--- /dev/null
+++ b/samples/ingredients/instances/preemptible/__init__.py
@@ -0,0 +1,18 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
diff --git a/samples/ingredients/instances/preemptible/create.py b/samples/ingredients/instances/preemptible/create.py
new file mode 100644
index 000000000..46d611a5d
--- /dev/null
+++ b/samples/ingredients/instances/preemptible/create.py
@@ -0,0 +1,60 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+
+from google.cloud import compute_v1
+
+
+#
+def create_preemptible_instance(project_id: str, zone: str, instance_name: str) -> compute_v1.Instance:
+ """
+ Create a new preemptible VM instance with Debian 10 operating system.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+
+ Returns:
+ Instance object.
+ """
+ newest_debian = get_image_from_family(
+ project="debian-cloud", family="debian-11"
+ )
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+ instance = create_instance(project_id, zone, instance_name, disks, preemptible=True)
+ return instance
+#
diff --git a/samples/ingredients/instances/preemptible/get.py b/samples/ingredients/instances/preemptible/get.py
new file mode 100644
index 000000000..7ff9fc860
--- /dev/null
+++ b/samples/ingredients/instances/preemptible/get.py
@@ -0,0 +1,38 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def is_preemptible(project_id: str, zone: str, instance_name: str) -> bool:
+ """
+ Check if a given instance is preemptible or not.
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: "us-west3-b"
+ instance_name: name of the virtual machine to check.
+ Returns:
+ The preemptible status of the instance.
+ """
+ instance_client = compute_v1.InstancesClient()
+ instance = instance_client.get(
+ project=project_id, zone=zone, instance=instance_name
+ )
+ return instance.scheduling.preemptible
+#
diff --git a/samples/ingredients/instances/preemptible/preemption_history.py b/samples/ingredients/instances/preemptible/preemption_history.py
new file mode 100644
index 000000000..53b6a3da7
--- /dev/null
+++ b/samples/ingredients/instances/preemptible/preemption_history.py
@@ -0,0 +1,56 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+import datetime
+from typing import List, Tuple
+
+
+#
+def preemption_history(
+ project_id: str, zone: str, instance_name: str = None
+) -> List[Tuple[str, datetime.datetime]]:
+ """
+ Get a list of preemption operations from given zone in a project. Optionally limit
+ the results to instance name.
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: "us-west3-b"
+ instance_name: name of the virtual machine to look for.
+ Returns:
+ List of preemption operations in given zone.
+ """
+ if instance_name:
+ filter = (
+ f'operationType="compute.instances.preempted" '
+ f"AND targetLink:instances/{instance_name}"
+ )
+ else:
+ filter = 'operationType="compute.instances.preempted"'
+
+ history = []
+
+ for operation in list_zone_operations(project_id, zone, filter):
+ this_instance_name = operation.target_link.rsplit("/", maxsplit=1)[1]
+ if instance_name and this_instance_name == instance_name:
+ # The filter used is not 100% accurate, it's `contains` not `equals`
+ # So we need to check the name to make sure it's the one we want.
+ moment = datetime.datetime.fromisoformat(operation.insert_time)
+ history.append((instance_name, moment))
+
+ return history
+#
diff --git a/samples/ingredients/instances/reset.py b/samples/ingredients/instances/reset.py
new file mode 100644
index 000000000..a0d29a1d9
--- /dev/null
+++ b/samples/ingredients/instances/reset.py
@@ -0,0 +1,46 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+import time
+
+from google.cloud import compute_v1
+
+
+#
+def reset_instance(project_id: str, zone: str, instance_name: str) -> None:
+ """
+ Resets a stopped Google Compute Engine instance (with unencrypted disks).
+ Args:
+ project_id: project ID or project number of the Cloud project your instance belongs to.
+ zone: name of the zone your instance belongs to.
+ instance_name: name of the instance your want to reset.
+ """
+ instance_client = compute_v1.InstancesClient()
+ op_client = compute_v1.ZoneOperationsClient()
+
+ op = instance_client.reset_unary(
+ project=project_id, zone=zone, instance=instance_name
+ )
+
+ start = time.time()
+ while op.status != compute_v1.Operation.Status.DONE:
+ op = op_client.wait(operation=op.name, zone=zone, project=project_id)
+ if time.time() - start >= 300: # 5 minutes
+ raise TimeoutError()
+ return
+#
diff --git a/samples/ingredients/instances/start.py b/samples/ingredients/instances/start.py
new file mode 100644
index 000000000..a57359b10
--- /dev/null
+++ b/samples/ingredients/instances/start.py
@@ -0,0 +1,46 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+import time
+
+from google.cloud import compute_v1
+
+
+#
+def start_instance(project_id: str, zone: str, instance_name: str) -> None:
+ """
+ Starts a stopped Google Compute Engine instance (with unencrypted disks).
+ Args:
+ project_id: project ID or project number of the Cloud project your instance belongs to.
+ zone: name of the zone your instance belongs to.
+ instance_name: name of the instance your want to start.
+ """
+ instance_client = compute_v1.InstancesClient()
+ op_client = compute_v1.ZoneOperationsClient()
+
+ op = instance_client.start_unary(
+ project=project_id, zone=zone, instance=instance_name
+ )
+
+ start = time.time()
+ while op.status != compute_v1.Operation.Status.DONE:
+ op = op_client.wait(operation=op.name, zone=zone, project=project_id)
+ if time.time() - start >= 300: # 5 minutes
+ raise TimeoutError()
+ return
+#
diff --git a/samples/ingredients/instances/start_encrypted.py b/samples/ingredients/instances/start_encrypted.py
new file mode 100644
index 000000000..e90c56f2a
--- /dev/null
+++ b/samples/ingredients/instances/start_encrypted.py
@@ -0,0 +1,68 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+import time
+
+from google.cloud import compute_v1
+
+
+#
+def start_instance_with_encryption_key(
+ project_id: str, zone: str, instance_name: str, key: bytes
+):
+ """
+ Starts a stopped Google Compute Engine instance (with encrypted disks).
+ Args:
+ project_id: project ID or project number of the Cloud project your instance belongs to.
+ zone: name of the zone your instance belongs to.
+ instance_name: name of the instance your want to start.
+ key: bytes object representing a raw base64 encoded key to your machines boot disk.
+ For more information about disk encryption see:
+ https://cloud.google.com/compute/docs/disks/customer-supplied-encryption#specifications
+ """
+ instance_client = compute_v1.InstancesClient()
+ op_client = compute_v1.ZoneOperationsClient()
+
+ instance_data = instance_client.get(
+ project=project_id, zone=zone, instance=instance_name
+ )
+
+ # Prepare the information about disk encryption
+ disk_data = compute_v1.CustomerEncryptionKeyProtectedDisk()
+ disk_data.source = instance_data.disks[0].source
+ disk_data.disk_encryption_key = compute_v1.CustomerEncryptionKey()
+ # Use raw_key to send over the key to unlock the disk
+ # To use a key stored in KMS, you need to provide `kms_key_name` and `kms_key_service_account`
+ disk_data.disk_encryption_key.raw_key = key
+ enc_data = compute_v1.InstancesStartWithEncryptionKeyRequest()
+ enc_data.disks = [disk_data]
+
+ op = instance_client.start_with_encryption_key_unary(
+ project=project_id,
+ zone=zone,
+ instance=instance_name,
+ instances_start_with_encryption_key_request_resource=enc_data,
+ )
+
+ start = time.time()
+ while op.status != compute_v1.Operation.Status.DONE:
+ op = op_client.wait(operation=op.name, zone=zone, project=project_id)
+ if time.time() - start >= 300: # 5 minutes
+ raise TimeoutError()
+ return
+#
diff --git a/samples/ingredients/instances/stop.py b/samples/ingredients/instances/stop.py
new file mode 100644
index 000000000..903053348
--- /dev/null
+++ b/samples/ingredients/instances/stop.py
@@ -0,0 +1,46 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+import time
+
+from google.cloud import compute_v1
+
+
+#
+def stop_instance(project_id: str, zone: str, instance_name: str) -> None:
+ """
+ Stops a running Google Compute Engine instance.
+ Args:
+ project_id: project ID or project number of the Cloud project your instance belongs to.
+ zone: name of the zone your instance belongs to.
+ instance_name: name of the instance your want to stop.
+ """
+ instance_client = compute_v1.InstancesClient()
+ op_client = compute_v1.ZoneOperationsClient()
+
+ op = instance_client.stop_unary(
+ project=project_id, zone=zone, instance=instance_name
+ )
+
+ start = time.time()
+ while op.status != compute_v1.Operation.Status.DONE:
+ op = op_client.wait(operation=op.name, zone=zone, project=project_id)
+ if time.time() - start >= 300: # 5 minutes
+ raise TimeoutError()
+ return
+#
diff --git a/samples/ingredients/operations/__init__.py b/samples/ingredients/operations/__init__.py
new file mode 100644
index 000000000..81d8b9be3
--- /dev/null
+++ b/samples/ingredients/operations/__init__.py
@@ -0,0 +1,18 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
diff --git a/samples/ingredients/operations/list_zone_operations.py b/samples/ingredients/operations/list_zone_operations.py
new file mode 100644
index 000000000..7089f023f
--- /dev/null
+++ b/samples/ingredients/operations/list_zone_operations.py
@@ -0,0 +1,46 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+from google.cloud.compute_v1.services.zone_operations import pagers
+
+
+#
+def list_zone_operations(
+ project_id: str, zone: str, filter: str = ""
+) -> pagers.ListPager:
+ """
+ List all recent operations the happened in given zone in a project. Optionally filter those
+ operations by providing a filter. More about using the filter can be found here:
+ https://cloud.google.com/compute/docs/reference/rest/v1/zoneOperations/list
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: "us-west3-b"
+ filter: filter string to be used for this listing operation.
+ Returns:
+ List of preemption operations in given zone.
+ """
+ operation_client = compute_v1.ZoneOperationsClient()
+ request = compute_v1.ListZoneOperationsRequest()
+ request.project = project_id
+ request.zone = zone
+ request.filter = filter
+
+ return operation_client.list(request)
+#
\ No newline at end of file
diff --git a/samples/ingredients/operations/wait_for_operation.py b/samples/ingredients/operations/wait_for_operation.py
new file mode 100644
index 000000000..53913076e
--- /dev/null
+++ b/samples/ingredients/operations/wait_for_operation.py
@@ -0,0 +1,50 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def wait_for_operation(
+ operation: compute_v1.Operation, project_id: str
+) -> compute_v1.Operation:
+ """
+ This method waits for an operation to be completed. Calling this function
+ will block until the operation is finished.
+
+ Args:
+ operation: The Operation object representing the operation you want to
+ wait on.
+ project_id: project ID or project number of the Cloud project you want to use.
+
+ Returns:
+ Finished Operation object.
+ """
+ kwargs = {"project": project_id, "operation": operation.name}
+ if operation.zone:
+ client = compute_v1.ZoneOperationsClient()
+ # Operation.zone is a full URL address of a zone, so we need to extract just the name
+ kwargs["zone"] = operation.zone.rsplit("/", maxsplit=1)[1]
+ elif operation.region:
+ client = compute_v1.RegionOperationsClient()
+ # Operation.region is a full URL address of a region, so we need to extract just the name
+ kwargs["region"] = operation.region.rsplit("/", maxsplit=1)[1]
+ else:
+ client = compute_v1.GlobalOperationsClient()
+ return client.wait(**kwargs)
+#
diff --git a/samples/ingredients/usage_report/disable.py b/samples/ingredients/usage_report/disable.py
new file mode 100644
index 000000000..e8d1464cb
--- /dev/null
+++ b/samples/ingredients/usage_report/disable.py
@@ -0,0 +1,43 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def disable_usage_export(project_id: str) -> None:
+ """
+ Disable Compute Engine usage export bucket for the Cloud Project.
+
+ Args:
+ project_id: project ID or project number of the project to update.
+ """
+ projects_client = compute_v1.ProjectsClient()
+
+ # Setting `usage_export_location_resource` to an
+ # empty object will disable the usage report generation.
+ operation = projects_client.set_usage_export_bucket_unary(
+ project=project_id, usage_export_location_resource={}
+ )
+
+ op_client = compute_v1.GlobalOperationsClient()
+
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = op_client.wait(operation=operation.name, project=project_id)
+#
+
diff --git a/samples/ingredients/usage_report/get_bucket.py b/samples/ingredients/usage_report/get_bucket.py
new file mode 100644
index 000000000..8b5a3b0b4
--- /dev/null
+++ b/samples/ingredients/usage_report/get_bucket.py
@@ -0,0 +1,55 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def get_usage_export_bucket(project_id: str) -> compute_v1.UsageExportLocation:
+ """
+ Retrieve Compute Engine usage export bucket for the Cloud project.
+ Replaces the empty value returned by the API with the default value used
+ to generate report file names.
+
+ Args:
+ project_id: project ID or project number of the project to update.
+ Returns:
+ UsageExportLocation object describing the current usage export settings
+ for project project_id.
+ """
+ projects_client = compute_v1.ProjectsClient()
+ project_data = projects_client.get(project=project_id)
+
+ uel = project_data.usage_export_location
+
+ if not uel.bucket_name:
+ # The usage reports are disabled.
+ return uel
+
+ if not uel.report_name_prefix:
+ # Although the server sent the empty string value, the next usage report
+ # generated with these settings still has the default prefix value
+ # "usage_gce". (see https://cloud.google.com/compute/docs/reference/rest/v1/projects/get)
+ print(
+ "Report name prefix not set, replacing with default value of "
+ "`usage_gce`."
+ )
+ uel.report_name_prefix = "usage_gce"
+ return uel
+#
+
diff --git a/samples/ingredients/usage_report/set_bucket.py b/samples/ingredients/usage_report/set_bucket.py
new file mode 100644
index 000000000..7a948c8b7
--- /dev/null
+++ b/samples/ingredients/usage_report/set_bucket.py
@@ -0,0 +1,61 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This is an ingredient file. It is not meant to be run directly. Check the samples/snippets
+# folder for complete code samples that are ready to be used.
+# Disabling flake8 for the ingredients file, as it would fail F821 - undefined name check.
+# flake8: noqa
+from google.cloud import compute_v1
+
+
+#
+def set_usage_export_bucket(
+ project_id: str, bucket_name: str, report_name_prefix: str = ""
+) -> None:
+ """
+ Set Compute Engine usage export bucket for the Cloud project.
+ This sample presents how to interpret the default value for the
+ report name prefix parameter.
+
+ Args:
+ project_id: project ID or project number of the project to update.
+ bucket_name: Google Cloud Storage bucket used to store Compute Engine
+ usage reports. An existing Google Cloud Storage bucket is required.
+ report_name_prefix: Prefix of the usage report name which defaults to an empty string
+ to showcase default values behaviour.
+ """
+ usage_export_location = compute_v1.UsageExportLocation()
+ usage_export_location.bucket_name = bucket_name
+ usage_export_location.report_name_prefix = report_name_prefix
+
+ if not report_name_prefix:
+ # Sending an empty value for report_name_prefix results in the
+ # next usage report being generated with the default prefix value
+ # "usage_gce". (ref: https://cloud.google.com/compute/docs/reference/rest/v1/projects/setUsageExportBucket)
+ print(
+ "Setting report_name_prefix to empty value causes the report "
+ "to have the default prefix of `usage_gce`."
+ )
+
+ projects_client = compute_v1.ProjectsClient()
+ operation = projects_client.set_usage_export_bucket_unary(
+ project=project_id, usage_export_location_resource=usage_export_location
+ )
+
+ op_client = compute_v1.GlobalOperationsClient()
+
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = op_client.wait(operation=operation.name, project=project_id)
+#
+
diff --git a/samples/recipes/__init__.py b/samples/recipes/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/recipes/firewall/__init__.py b/samples/recipes/firewall/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/recipes/firewall/create.py b/samples/recipes/firewall/create.py
new file mode 100644
index 000000000..8d76598fa
--- /dev/null
+++ b/samples/recipes/firewall/create.py
@@ -0,0 +1,21 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+#
diff --git a/samples/recipes/firewall/delete.py b/samples/recipes/firewall/delete.py
new file mode 100644
index 000000000..6c3752fa6
--- /dev/null
+++ b/samples/recipes/firewall/delete.py
@@ -0,0 +1,21 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+#
diff --git a/samples/recipes/firewall/list.py b/samples/recipes/firewall/list.py
new file mode 100644
index 000000000..fbd0149f6
--- /dev/null
+++ b/samples/recipes/firewall/list.py
@@ -0,0 +1,21 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+#
diff --git a/samples/recipes/firewall/main.py b/samples/recipes/firewall/main.py
new file mode 100644
index 000000000..c8a4d83b0
--- /dev/null
+++ b/samples/recipes/firewall/main.py
@@ -0,0 +1,58 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+
+
+#
+
+#
+
+#
+
+#
+
+#
+
+if __name__ == "__main__":
+ import google.auth
+ import google.auth.exceptions
+
+ try:
+ default_project_id = google.auth.default()[1]
+ print(f"Using project {default_project_id}.")
+ except google.auth.exceptions.DefaultCredentialsError:
+ print(
+ "Please use `gcloud auth application-default login` "
+ "or set GOOGLE_APPLICATION_CREDENTIALS to use this script."
+ )
+ else:
+ import uuid
+
+ rule_name = "firewall-sample-" + uuid.uuid4().hex[:10]
+ print(f"Creating firewall rule {rule_name}...")
+ # The rule will be created with default priority of 1000.
+ create_firewall_rule(default_project_id, rule_name)
+ try:
+ print("Rule created:")
+ print(get_firewall_rule(default_project_id, rule_name))
+ print("Updating rule priority to 10...")
+ patch_firewall_priority(default_project_id, rule_name, 10)
+ print("Rule updated: ")
+ print(get_firewall_rule(default_project_id, rule_name))
+ print(f"Deleting rule {rule_name}...")
+ finally:
+ delete_firewall_rule(default_project_id, rule_name)
+ print("Done.")
diff --git a/samples/recipes/firewall/patch.py b/samples/recipes/firewall/patch.py
new file mode 100644
index 000000000..543157e1a
--- /dev/null
+++ b/samples/recipes/firewall/patch.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/images/__init__.py b/samples/recipes/images/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/recipes/images/get.py b/samples/recipes/images/get.py
new file mode 100644
index 000000000..4524e8f2f
--- /dev/null
+++ b/samples/recipes/images/get.py
@@ -0,0 +1,28 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+#
+#
+
+
+#
+#
+
+
+#
+#
+#
diff --git a/samples/recipes/images/list.py b/samples/recipes/images/list.py
new file mode 100644
index 000000000..80d3074cd
--- /dev/null
+++ b/samples/recipes/images/list.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/images/pagination.py b/samples/recipes/images/pagination.py
new file mode 100644
index 000000000..aa58b4f86
--- /dev/null
+++ b/samples/recipes/images/pagination.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#
+#
+import google.cloud.compute_v1 as compute_v1
+
+#
+#
+
+
+#
+def print_images_list(project: str) -> str:
+ """
+ Prints a list of all non-deprecated image names available in given project.
+
+ Args:
+ project: project ID or project number of the Cloud project you want to list images from.
+
+ Returns:
+ The output as a string.
+ """
+ images_client = compute_v1.ImagesClient()
+ # Listing only non-deprecated images to reduce the size of the reply.
+ images_list_request = compute_v1.ListImagesRequest(
+ project=project, max_results=100, filter="deprecated.state != DEPRECATED"
+ )
+ output = []
+
+ # Although the `max_results` parameter is specified in the request, the iterable returned
+ # by the `list()` method hides the pagination mechanic. The library makes multiple
+ # requests to the API for you, so you can simply iterate over all the images.
+ for img in images_client.list(request=images_list_request):
+ print(f" - {img.name}")
+ output.append(f" - {img.name}")
+ return "\n".join(output)
+
+
+#
+
+
+#
+def print_images_list_by_page(project: str, page_size: int = 10) -> str:
+ """
+ Prints a list of all non-deprecated image names available in a given project,
+ divided into pages as returned by the Compute Engine API.
+
+ Args:
+ project: project ID or project number of the Cloud project you want to list images from.
+ page_size: size of the pages you want the API to return on each call.
+
+ Returns:
+ Output as a string.
+ """
+ images_client = compute_v1.ImagesClient()
+ # Listing only non-deprecated images to reduce the size of the reply.
+ images_list_request = compute_v1.ListImagesRequest(
+ project=project, max_results=page_size, filter="deprecated.state != DEPRECATED"
+ )
+ output = []
+
+ # Use the `pages` attribute of returned iterable to have more granular control of
+ # iteration over paginated results from the API. Each time you want to access the
+ # next page, the library retrieves that page from the API.
+ for page_num, page in enumerate(
+ images_client.list(request=images_list_request).pages, start=1
+ ):
+ print(f"Page {page_num}: ")
+ output.append(f"Page {page_num}: ")
+ for img in page.items:
+ print(f" - {img.name}")
+ output.append(f" - {img.name}")
+ return "\n".join(output)
+
+
+#
+
+
+if __name__ == "__main__":
+ print("=================== Flat list of images ===================")
+ print_images_list("windows-sql-cloud")
+ print("================= Paginated list of images ================")
+ print_images_list_by_page("windows-sql-cloud", 5)
diff --git a/samples/recipes/instance_templates/__init__.py b/samples/recipes/instance_templates/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/recipes/instance_templates/create.py b/samples/recipes/instance_templates/create.py
new file mode 100644
index 000000000..6c313c2d2
--- /dev/null
+++ b/samples/recipes/instance_templates/create.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instance_templates/create_from_instance.py b/samples/recipes/instance_templates/create_from_instance.py
new file mode 100644
index 000000000..751416fe3
--- /dev/null
+++ b/samples/recipes/instance_templates/create_from_instance.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instance_templates/create_with_subnet.py b/samples/recipes/instance_templates/create_with_subnet.py
new file mode 100644
index 000000000..85639db00
--- /dev/null
+++ b/samples/recipes/instance_templates/create_with_subnet.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instance_templates/delete.py b/samples/recipes/instance_templates/delete.py
new file mode 100644
index 000000000..bf774c57d
--- /dev/null
+++ b/samples/recipes/instance_templates/delete.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instance_templates/get.py b/samples/recipes/instance_templates/get.py
new file mode 100644
index 000000000..3036e7348
--- /dev/null
+++ b/samples/recipes/instance_templates/get.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instance_templates/list.py b/samples/recipes/instance_templates/list.py
new file mode 100644
index 000000000..6ce5c5b73
--- /dev/null
+++ b/samples/recipes/instance_templates/list.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instances/__init__.py b/samples/recipes/instances/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/recipes/instances/create.py b/samples/recipes/instances/create.py
new file mode 100644
index 000000000..b51a2e737
--- /dev/null
+++ b/samples/recipes/instances/create.py
@@ -0,0 +1,48 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+#
+
+#
+#
+
+if __name__ == "__main__":
+ import uuid
+ import google.auth
+ import google.auth.exceptions
+
+ try:
+ default_project_id = google.auth.default()[1]
+ except google.auth.exceptions.DefaultCredentialsError:
+ print(
+ "Please use `gcloud auth application-default login` "
+ "or set GOOGLE_APPLICATION_CREDENTIALS to use this script."
+ )
+ else:
+ instance_name = "quickstart-" + uuid.uuid4().hex[:10]
+ instance_zone = "europe-central2-b"
+
+ newest_debian = get_image_from_family(
+ project="debian-cloud", family="debian-10"
+ )
+ disk_type = f"zones/{instance_zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+
+ create_instance(default_project_id, instance_zone, instance_name, disks)
diff --git a/samples/recipes/instances/create_start_instance/__init__.py b/samples/recipes/instances/create_start_instance/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/recipes/instances/create_start_instance/create_from_custom_image.py b/samples/recipes/instances/create_start_instance/create_from_custom_image.py
new file mode 100644
index 000000000..e50d60367
--- /dev/null
+++ b/samples/recipes/instances/create_start_instance/create_from_custom_image.py
@@ -0,0 +1,29 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+
+#
+
+
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/create_start_instance/create_from_public_image.py b/samples/recipes/instances/create_start_instance/create_from_public_image.py
new file mode 100644
index 000000000..6f6f0ee04
--- /dev/null
+++ b/samples/recipes/instances/create_start_instance/create_from_public_image.py
@@ -0,0 +1,29 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+
+#
+
+
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/create_start_instance/create_from_snapshot.py b/samples/recipes/instances/create_start_instance/create_from_snapshot.py
new file mode 100644
index 000000000..2047eeb57
--- /dev/null
+++ b/samples/recipes/instances/create_start_instance/create_from_snapshot.py
@@ -0,0 +1,26 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/create_start_instance/create_with_additional_disk.py b/samples/recipes/instances/create_start_instance/create_with_additional_disk.py
new file mode 100644
index 000000000..ab9baa6e4
--- /dev/null
+++ b/samples/recipes/instances/create_start_instance/create_with_additional_disk.py
@@ -0,0 +1,33 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+#
+#
+
+#
+
+
+#
+
+
+#
+
+
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/create_start_instance/create_with_snapshotted_data_disk.py b/samples/recipes/instances/create_start_instance/create_with_snapshotted_data_disk.py
new file mode 100644
index 000000000..858e61884
--- /dev/null
+++ b/samples/recipes/instances/create_start_instance/create_with_snapshotted_data_disk.py
@@ -0,0 +1,33 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+#
+#
+
+#
+
+
+#
+
+
+#
+
+
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/create_with_subnet.py b/samples/recipes/instances/create_with_subnet.py
new file mode 100644
index 000000000..906edca50
--- /dev/null
+++ b/samples/recipes/instances/create_with_subnet.py
@@ -0,0 +1,29 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+
+#
+
+
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/custom_hostname/create.py b/samples/recipes/instances/custom_hostname/create.py
new file mode 100644
index 000000000..55f3b47e6
--- /dev/null
+++ b/samples/recipes/instances/custom_hostname/create.py
@@ -0,0 +1,29 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+
+#
+
+
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/custom_hostname/get.py b/samples/recipes/instances/custom_hostname/get.py
new file mode 100644
index 000000000..d69cce045
--- /dev/null
+++ b/samples/recipes/instances/custom_hostname/get.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instances/custom_machine_types/__init__.py b/samples/recipes/instances/custom_machine_types/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/recipes/instances/custom_machine_types/create_shared_with_helper.py b/samples/recipes/instances/custom_machine_types/create_shared_with_helper.py
new file mode 100644
index 000000000..6adc80098
--- /dev/null
+++ b/samples/recipes/instances/custom_machine_types/create_shared_with_helper.py
@@ -0,0 +1,32 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+
+#
+
+
+#
+
+
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/custom_machine_types/create_with_helper.py b/samples/recipes/instances/custom_machine_types/create_with_helper.py
new file mode 100644
index 000000000..0ea883cf5
--- /dev/null
+++ b/samples/recipes/instances/custom_machine_types/create_with_helper.py
@@ -0,0 +1,34 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+
+#
+
+
+#
+
+
+#
+
+
+#
+
+
+#
+
+#
diff --git a/samples/recipes/instances/custom_machine_types/create_without_helper.py b/samples/recipes/instances/custom_machine_types/create_without_helper.py
new file mode 100644
index 000000000..e88388a82
--- /dev/null
+++ b/samples/recipes/instances/custom_machine_types/create_without_helper.py
@@ -0,0 +1,29 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+
+#
+
+
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/custom_machine_types/extra_mem_no_helper.py b/samples/recipes/instances/custom_machine_types/extra_mem_no_helper.py
new file mode 100644
index 000000000..68fdc2759
--- /dev/null
+++ b/samples/recipes/instances/custom_machine_types/extra_mem_no_helper.py
@@ -0,0 +1,29 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+
+#
+
+
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/custom_machine_types/helper_class.py b/samples/recipes/instances/custom_machine_types/helper_class.py
new file mode 100644
index 000000000..e5a48c0c9
--- /dev/null
+++ b/samples/recipes/instances/custom_machine_types/helper_class.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instances/custom_machine_types/update_memory.py b/samples/recipes/instances/custom_machine_types/update_memory.py
new file mode 100644
index 000000000..5817cd987
--- /dev/null
+++ b/samples/recipes/instances/custom_machine_types/update_memory.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instances/delete.py b/samples/recipes/instances/delete.py
new file mode 100644
index 000000000..68fc7f554
--- /dev/null
+++ b/samples/recipes/instances/delete.py
@@ -0,0 +1,21 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/delete_protection/__init__.py b/samples/recipes/instances/delete_protection/__init__.py
new file mode 100644
index 000000000..a3ded82a3
--- /dev/null
+++ b/samples/recipes/instances/delete_protection/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
diff --git a/samples/recipes/instances/delete_protection/create.py b/samples/recipes/instances/delete_protection/create.py
new file mode 100644
index 000000000..f1bb3a9b3
--- /dev/null
+++ b/samples/recipes/instances/delete_protection/create.py
@@ -0,0 +1,29 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+
+#
+
+
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/delete_protection/get.py b/samples/recipes/instances/delete_protection/get.py
new file mode 100644
index 000000000..1d7697dd1
--- /dev/null
+++ b/samples/recipes/instances/delete_protection/get.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instances/delete_protection/set.py b/samples/recipes/instances/delete_protection/set.py
new file mode 100644
index 000000000..785e8f781
--- /dev/null
+++ b/samples/recipes/instances/delete_protection/set.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instances/from_instance_template/__init__.py b/samples/recipes/instances/from_instance_template/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/recipes/instances/from_instance_template/create_from_template.py b/samples/recipes/instances/from_instance_template/create_from_template.py
new file mode 100644
index 000000000..c296366cc
--- /dev/null
+++ b/samples/recipes/instances/from_instance_template/create_from_template.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instances/from_instance_template/create_from_template_with_overrides.py b/samples/recipes/instances/from_instance_template/create_from_template_with_overrides.py
new file mode 100644
index 000000000..27d1b2ae0
--- /dev/null
+++ b/samples/recipes/instances/from_instance_template/create_from_template_with_overrides.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instances/list.py b/samples/recipes/instances/list.py
new file mode 100644
index 000000000..92aff46b1
--- /dev/null
+++ b/samples/recipes/instances/list.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instances/list_all.py b/samples/recipes/instances/list_all.py
new file mode 100644
index 000000000..e1fafd7f2
--- /dev/null
+++ b/samples/recipes/instances/list_all.py
@@ -0,0 +1,20 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/instances/preemptible/__init__.py b/samples/recipes/instances/preemptible/__init__.py
new file mode 100644
index 000000000..a3ded82a3
--- /dev/null
+++ b/samples/recipes/instances/preemptible/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
diff --git a/samples/recipes/instances/preemptible/create_preemptible.py b/samples/recipes/instances/preemptible/create_preemptible.py
new file mode 100644
index 000000000..a61615412
--- /dev/null
+++ b/samples/recipes/instances/preemptible/create_preemptible.py
@@ -0,0 +1,29 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+
+#
+
+
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/preemptible/is_preemptible.py b/samples/recipes/instances/preemptible/is_preemptible.py
new file mode 100644
index 000000000..d57031c83
--- /dev/null
+++ b/samples/recipes/instances/preemptible/is_preemptible.py
@@ -0,0 +1,21 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+#
diff --git a/samples/recipes/instances/preemptible/preemption_history.py b/samples/recipes/instances/preemptible/preemption_history.py
new file mode 100644
index 000000000..0c9a9a8ce
--- /dev/null
+++ b/samples/recipes/instances/preemptible/preemption_history.py
@@ -0,0 +1,24 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+
+
+#
+
+#
diff --git a/samples/recipes/instances/reset.py b/samples/recipes/instances/reset.py
new file mode 100644
index 000000000..0842ed544
--- /dev/null
+++ b/samples/recipes/instances/reset.py
@@ -0,0 +1,21 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/start.py b/samples/recipes/instances/start.py
new file mode 100644
index 000000000..9ea6be08a
--- /dev/null
+++ b/samples/recipes/instances/start.py
@@ -0,0 +1,21 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/start_encrypted.py b/samples/recipes/instances/start_encrypted.py
new file mode 100644
index 000000000..6833c644e
--- /dev/null
+++ b/samples/recipes/instances/start_encrypted.py
@@ -0,0 +1,21 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+
+#
+#
diff --git a/samples/recipes/instances/stop.py b/samples/recipes/instances/stop.py
new file mode 100644
index 000000000..7dda8bcfa
--- /dev/null
+++ b/samples/recipes/instances/stop.py
@@ -0,0 +1,21 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+
+#
+#
diff --git a/samples/recipes/operations/__init__.py b/samples/recipes/operations/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/recipes/operations/operation_check.py b/samples/recipes/operations/operation_check.py
new file mode 100644
index 000000000..8913e7324
--- /dev/null
+++ b/samples/recipes/operations/operation_check.py
@@ -0,0 +1,33 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+#
+#
+
+#
+#
diff --git a/samples/recipes/usage_report/__init__.py b/samples/recipes/usage_report/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/recipes/usage_report/usage_reports.py b/samples/recipes/usage_report/usage_reports.py
new file mode 100644
index 000000000..4a293b800
--- /dev/null
+++ b/samples/recipes/usage_report/usage_reports.py
@@ -0,0 +1,45 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+"""
+A sample script showing how to handle default values when communicating
+with the Compute Engine API and how to configure usage reports using the API.
+"""
+#
+#
+#
+#
+#
+
+#
+#
+#
+
+
+#
+#
+
+#
+
+#
+#
+
+#
+#
+
+
+#
+#
+
+#
diff --git a/samples/requirements-test.txt b/samples/requirements-test.txt
index 5737e3584..45720ccd4 100644
--- a/samples/requirements-test.txt
+++ b/samples/requirements-test.txt
@@ -1,4 +1,5 @@
pytest==7.0.1
+pytest-parallel==0.1.1
flaky==3.7.0
google-cloud-storage==2.1.0; python_version == '3.6'
google-cloud-storage==2.1.0; python_version >= '3.7'
\ No newline at end of file
diff --git a/samples/sgs.py b/samples/sgs.py
index f7d4f43c8..f8278f7b5 100644
--- a/samples/sgs.py
+++ b/samples/sgs.py
@@ -45,9 +45,9 @@
# directory and apply your changes there.
"""
-DEFAULT_OUTPUT_PATH = Path("sgs_test_fixtures/output")
-INGREDIENTS_PATH = Path("sgs_test_fixtures/ingredients")
-RECIPES_PATH = Path("sgs_test_fixtures/recipes")
+DEFAULT_OUTPUT_PATH = Path("snippets")
+INGREDIENTS_PATH = Path("ingredients")
+RECIPES_PATH = Path("recipes")
@dataclass
@@ -133,7 +133,10 @@ def load_ingredient(path: Path) -> Ingredient:
ingredient_name = INGREDIENTS_START.match(line).group(1)
in_ingredient = True
else:
- warnings.warn(f"The ingredient in {path} has no closing tag.", SyntaxWarning)
+ if in_ingredient:
+ warnings.warn(
+ f"The ingredient in {path} has no closing tag.", SyntaxWarning
+ )
return Ingredient(
name=ingredient_name,
text="".join(ingredient_lines),
@@ -164,7 +167,7 @@ def load_recipes(path: Path) -> dict:
if ipath.is_dir():
recipes.update(load_recipes(ipath))
elif ipath.is_file():
- recipes[ipath] = load_recipe(ipath)
+ recipes[ipath.absolute()] = load_recipe(ipath)
return recipes
@@ -254,10 +257,9 @@ def save_rendered_recipe(
output_dir: Path = DEFAULT_OUTPUT_PATH,
recipes_path: Path = RECIPES_PATH,
) -> Path:
- output_dir.mkdir(exist_ok=True)
-
+ output_dir.mkdir(parents=True, exist_ok=True)
output_path = output_dir / recipe_path.relative_to(recipes_path)
- output_path.parent.mkdir(exist_ok=True)
+ output_path.parent.mkdir(parents=True, exist_ok=True)
with output_path.open(mode="w") as out_file:
out_file.write(rendered_recipe)
@@ -282,7 +284,12 @@ def generate(
for path, recipe in recipes.items():
rendered = render_recipe(recipe, ingredients)
- out = save_rendered_recipe(path, rendered, output_dir=Path(args.output_dir))
+ out = save_rendered_recipe(
+ path.absolute(),
+ rendered,
+ recipes_path=recipes_path.absolute(),
+ output_dir=Path(args.output_dir),
+ )
updated_paths.add(str(out))
print("Generated files:")
diff --git a/samples/snippets/__init__.py b/samples/snippets/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/snippets/firewall/__init__.py b/samples/snippets/firewall/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/snippets/firewall/create.py b/samples/snippets/firewall/create.py
new file mode 100644
index 000000000..5bcf1c5fc
--- /dev/null
+++ b/samples/snippets/firewall/create.py
@@ -0,0 +1,74 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_firewall_create]
+from google.cloud import compute_v1
+
+
+def create_firewall_rule(
+ project_id: str, firewall_rule_name: str, network: str = "global/networks/default"
+) -> compute_v1.Firewall:
+ """
+ Creates a simple firewall rule allowing for incoming HTTP and HTTPS access from the entire Internet.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ firewall_rule_name: name of the rule that is created.
+ network: name of the network the rule will be applied to. Available name formats:
+ * https://www.googleapis.com/compute/v1/projects/{project_id}/global/networks/{network}
+ * projects/{project_id}/global/networks/{network}
+ * global/networks/{network}
+ """
+ firewall_rule = compute_v1.Firewall()
+ firewall_rule.name = firewall_rule_name
+ firewall_rule.direction = "INGRESS"
+
+ allowed_ports = compute_v1.Allowed()
+ allowed_ports.I_p_protocol = "tcp"
+ allowed_ports.ports = ["80", "443"]
+
+ firewall_rule.allowed = [allowed_ports]
+ firewall_rule.source_ranges = ["0.0.0.0/0"]
+ firewall_rule.network = network
+ firewall_rule.description = "Allowing TCP traffic on port 80 and 443 from Internet."
+
+ firewall_rule.target_tags = ["web"]
+
+ # Note that the default value of priority for the firewall API is 1000.
+ # If you check the value of `firewall_rule.priority` at this point it
+ # will be equal to 0, however it is not treated as "set" by the library and thus
+ # the default will be applied to the new rule. If you want to create a rule that
+ # has priority == 0, you need to explicitly set it so:
+
+ # firewall_rule.priority = 0
+
+ firewall_client = compute_v1.FirewallsClient()
+ op = firewall_client.insert_unary(
+ project=project_id, firewall_resource=firewall_rule
+ )
+
+ op_client = compute_v1.GlobalOperationsClient()
+ op_client.wait(project=project_id, operation=op.name)
+
+ return firewall_client.get(project=project_id, firewall=firewall_rule_name)
+
+
+# [END compute_firewall_create]
diff --git a/samples/snippets/firewall/delete.py b/samples/snippets/firewall/delete.py
new file mode 100644
index 000000000..8dbea8709
--- /dev/null
+++ b/samples/snippets/firewall/delete.py
@@ -0,0 +1,44 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_firewall_delete]
+from google.cloud import compute_v1
+
+
+def delete_firewall_rule(project_id: str, firewall_rule_name: str):
+ """
+ Deleted a firewall rule from the project.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ firewall_rule_name: name of the firewall rule you want to delete.
+ """
+ firewall_client = compute_v1.FirewallsClient()
+ operation = firewall_client.delete_unary(
+ project=project_id, firewall=firewall_rule_name
+ )
+
+ operation_client = compute_v1.GlobalOperationsClient()
+ operation_client.wait(project=project_id, operation=operation.name)
+ return
+
+
+# [END compute_firewall_delete]
diff --git a/samples/snippets/firewall/list.py b/samples/snippets/firewall/list.py
new file mode 100644
index 000000000..d4553ac12
--- /dev/null
+++ b/samples/snippets/firewall/list.py
@@ -0,0 +1,48 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_firewall_list]
+from typing import Iterable
+
+from google.cloud import compute_v1
+
+
+def list_firewall_rules(project_id: str) -> Iterable[compute_v1.Firewall]:
+ """
+ Return a list of all the firewall rules in specified project. Also prints the
+ list of firewall names and their descriptions.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+
+ Returns:
+ A flat list of all firewall rules defined for given project.
+ """
+ firewall_client = compute_v1.FirewallsClient()
+ firewalls_list = firewall_client.list(project=project_id)
+
+ for firewall in firewalls_list:
+ print(f" - {firewall.name}: {firewall.description}")
+
+ return firewalls_list
+
+
+# [END compute_firewall_list]
diff --git a/samples/snippets/sample_firewall.py b/samples/snippets/firewall/main.py
similarity index 82%
rename from samples/snippets/sample_firewall.py
rename to samples/snippets/firewall/main.py
index c2bdd3fa7..d8b47a338 100644
--- a/samples/snippets/sample_firewall.py
+++ b/samples/snippets/firewall/main.py
@@ -1,65 +1,32 @@
-# Copyright 2021 Google LLC
+# Copyright 2022 Google LLC
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
-from typing import Iterable
-
-# [START compute_firewall_list]
-# [START compute_firewall_create]
-# [START compute_firewall_patch]
-# [START compute_firewall_delete]
-import google.cloud.compute_v1 as compute_v1
-
-# [END compute_firewall_delete]
-# [END compute_firewall_patch]
-# [END compute_firewall_create]
-# [END compute_firewall_list]
-
-
-# [START compute_firewall_list]
-def list_firewall_rules(project_id: str) -> Iterable:
- """
- Return a list of all the firewall rules in specified project. Also prints the
- list of firewall names and their descriptions.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
-
- Returns:
- A flat list of all firewall rules defined for given project.
- """
- firewall_client = compute_v1.FirewallsClient()
- firewalls_list = firewall_client.list(project=project_id)
-
- for firewall in firewalls_list:
- print(f" - {firewall.name}: {firewall.description}")
-
- return firewalls_list
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
-# [END compute_firewall_list]
-
+from typing import Iterable
-def get_firewall_rule(project_id: str, firewall_rule_name: str) -> compute_v1.Firewall:
- firewall_client = compute_v1.FirewallsClient()
- return firewall_client.get(project=project_id, firewall=firewall_rule_name)
+from google.cloud import compute_v1
-# [START compute_firewall_create]
def create_firewall_rule(
project_id: str, firewall_rule_name: str, network: str = "global/networks/default"
-):
+) -> compute_v1.Firewall:
"""
Creates a simple firewall rule allowing for incoming HTTP and HTTPS access from the entire Internet.
@@ -102,30 +69,20 @@ def create_firewall_rule(
op_client = compute_v1.GlobalOperationsClient()
op_client.wait(project=project_id, operation=op.name)
- return
-
-
-# [END compute_firewall_create]
+ return firewall_client.get(project=project_id, firewall=firewall_rule_name)
-# [START compute_firewall_patch]
-def patch_firewall_priority(project_id: str, firewall_rule_name: str, priority: int):
+def delete_firewall_rule(project_id: str, firewall_rule_name: str):
"""
- Modifies the priority of a given firewall rule.
+ Deleted a firewall rule from the project.
Args:
project_id: project ID or project number of the Cloud project you want to use.
- firewall_rule_name: name of the rule you want to modify.
- priority: the new priority to be set for the rule.
+ firewall_rule_name: name of the firewall rule you want to delete.
"""
- firewall_rule = compute_v1.Firewall()
- firewall_rule.priority = priority
-
- # The patch operation doesn't require the full definition of a Firewall object. It will only update
- # the values that were set in it, in this case it will only change the priority.
firewall_client = compute_v1.FirewallsClient()
- operation = firewall_client.patch_unary(
- project=project_id, firewall=firewall_rule_name, firewall_resource=firewall_rule
+ operation = firewall_client.delete_unary(
+ project=project_id, firewall=firewall_rule_name
)
operation_client = compute_v1.GlobalOperationsClient()
@@ -133,21 +90,48 @@ def patch_firewall_priority(project_id: str, firewall_rule_name: str, priority:
return
-# [END compute_firewall_patch]
+def get_firewall_rule(project_id: str, firewall_rule_name: str) -> compute_v1.Firewall:
+ firewall_client = compute_v1.FirewallsClient()
+ return firewall_client.get(project=project_id, firewall=firewall_rule_name)
-# [START compute_firewall_delete]
-def delete_firewall_rule(project_id: str, firewall_rule_name: str):
+def list_firewall_rules(project_id: str) -> Iterable[compute_v1.Firewall]:
"""
- Deleted a firewall rule from the project.
+ Return a list of all the firewall rules in specified project. Also prints the
+ list of firewall names and their descriptions.
Args:
project_id: project ID or project number of the Cloud project you want to use.
- firewall_rule_name: name of the firewall rule you want to delete.
+
+ Returns:
+ A flat list of all firewall rules defined for given project.
"""
firewall_client = compute_v1.FirewallsClient()
- operation = firewall_client.delete_unary(
- project=project_id, firewall=firewall_rule_name
+ firewalls_list = firewall_client.list(project=project_id)
+
+ for firewall in firewalls_list:
+ print(f" - {firewall.name}: {firewall.description}")
+
+ return firewalls_list
+
+
+def patch_firewall_priority(project_id: str, firewall_rule_name: str, priority: int):
+ """
+ Modifies the priority of a given firewall rule.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ firewall_rule_name: name of the rule you want to modify.
+ priority: the new priority to be set for the rule.
+ """
+ firewall_rule = compute_v1.Firewall()
+ firewall_rule.priority = priority
+
+ # The patch operation doesn't require the full definition of a Firewall object. It will only update
+ # the values that were set in it, in this case it will only change the priority.
+ firewall_client = compute_v1.FirewallsClient()
+ operation = firewall_client.patch_unary(
+ project=project_id, firewall=firewall_rule_name, firewall_resource=firewall_rule
)
operation_client = compute_v1.GlobalOperationsClient()
@@ -155,9 +139,6 @@ def delete_firewall_rule(project_id: str, firewall_rule_name: str):
return
-# [END compute_firewall_delete]
-
-
if __name__ == "__main__":
import google.auth
import google.auth.exceptions
diff --git a/samples/snippets/firewall/patch.py b/samples/snippets/firewall/patch.py
new file mode 100644
index 000000000..e5f2a96d6
--- /dev/null
+++ b/samples/snippets/firewall/patch.py
@@ -0,0 +1,50 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_firewall_patch]
+from google.cloud import compute_v1
+
+
+def patch_firewall_priority(project_id: str, firewall_rule_name: str, priority: int):
+ """
+ Modifies the priority of a given firewall rule.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ firewall_rule_name: name of the rule you want to modify.
+ priority: the new priority to be set for the rule.
+ """
+ firewall_rule = compute_v1.Firewall()
+ firewall_rule.priority = priority
+
+ # The patch operation doesn't require the full definition of a Firewall object. It will only update
+ # the values that were set in it, in this case it will only change the priority.
+ firewall_client = compute_v1.FirewallsClient()
+ operation = firewall_client.patch_unary(
+ project=project_id, firewall=firewall_rule_name, firewall_resource=firewall_rule
+ )
+
+ operation_client = compute_v1.GlobalOperationsClient()
+ operation_client.wait(project=project_id, operation=operation.name)
+ return
+
+
+# [END compute_firewall_patch]
diff --git a/samples/snippets/images/__init__.py b/samples/snippets/images/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/snippets/images/get.py b/samples/snippets/images/get.py
new file mode 100644
index 000000000..94c8f3af4
--- /dev/null
+++ b/samples/snippets/images/get.py
@@ -0,0 +1,55 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_images_get_from_family]
+# [START compute_images_get]
+from google.cloud import compute_v1
+
+# [END compute_images_get]
+
+
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(project=project, family=family)
+ return newest_image
+
+
+# [END compute_images_get_from_family]
+
+
+# [START compute_images_get]
+def get_image(project_id: str, image_name: str) -> compute_v1.Image:
+ """
+ Retrieve detailed information about a single image from a project.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to list images from.
+ image_name: name of the image you want to get details of.
+
+ Returns:
+ An instance of compute_v1.Image object with information about specified image.
+ """
+ image_client = compute_v1.ImagesClient()
+ return image_client.get(project=project_id, image=image_name)
+
+
+# [END compute_images_get]
diff --git a/samples/snippets/images/list.py b/samples/snippets/images/list.py
new file mode 100644
index 000000000..361829533
--- /dev/null
+++ b/samples/snippets/images/list.py
@@ -0,0 +1,42 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_images_get_list]
+from typing import Iterable
+
+from google.cloud import compute_v1
+
+
+def list_images(project_id: str) -> Iterable[compute_v1.Image]:
+ """
+ Retrieve a list of images available in given project.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to list images from.
+
+ Returns:
+ An iterable collection of compute_v1.Image objects.
+ """
+ image_client = compute_v1.ImagesClient()
+ return image_client.list(project=project_id)
+
+
+# [END compute_images_get_list]
diff --git a/samples/snippets/sample_pagination.py b/samples/snippets/images/pagination.py
similarity index 85%
rename from samples/snippets/sample_pagination.py
rename to samples/snippets/images/pagination.py
index e2590b541..7ac6d0b6e 100644
--- a/samples/snippets/sample_pagination.py
+++ b/samples/snippets/images/pagination.py
@@ -14,6 +14,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
# [START compute_images_list_page]
# [START compute_images_list]
import google.cloud.compute_v1 as compute_v1
@@ -23,7 +29,7 @@
# [START compute_images_list]
-def print_images_list(project: str) -> None:
+def print_images_list(project: str) -> str:
"""
Prints a list of all non-deprecated image names available in given project.
@@ -31,26 +37,29 @@ def print_images_list(project: str) -> None:
project: project ID or project number of the Cloud project you want to list images from.
Returns:
- None.
+ The output as a string.
"""
images_client = compute_v1.ImagesClient()
# Listing only non-deprecated images to reduce the size of the reply.
images_list_request = compute_v1.ListImagesRequest(
project=project, max_results=100, filter="deprecated.state != DEPRECATED"
)
+ output = []
# Although the `max_results` parameter is specified in the request, the iterable returned
# by the `list()` method hides the pagination mechanic. The library makes multiple
# requests to the API for you, so you can simply iterate over all the images.
for img in images_client.list(request=images_list_request):
print(f" - {img.name}")
+ output.append(f" - {img.name}")
+ return "\n".join(output)
# [END compute_images_list]
# [START compute_images_list_page]
-def print_images_list_by_page(project: str, page_size: int = 10) -> None:
+def print_images_list_by_page(project: str, page_size: int = 10) -> str:
"""
Prints a list of all non-deprecated image names available in a given project,
divided into pages as returned by the Compute Engine API.
@@ -60,13 +69,14 @@ def print_images_list_by_page(project: str, page_size: int = 10) -> None:
page_size: size of the pages you want the API to return on each call.
Returns:
- None.
+ Output as a string.
"""
images_client = compute_v1.ImagesClient()
# Listing only non-deprecated images to reduce the size of the reply.
images_list_request = compute_v1.ListImagesRequest(
project=project, max_results=page_size, filter="deprecated.state != DEPRECATED"
)
+ output = []
# Use the `pages` attribute of returned iterable to have more granular control of
# iteration over paginated results from the API. Each time you want to access the
@@ -75,8 +85,11 @@ def print_images_list_by_page(project: str, page_size: int = 10) -> None:
images_client.list(request=images_list_request).pages, start=1
):
print(f"Page {page_num}: ")
+ output.append(f"Page {page_num}: ")
for img in page.items:
print(f" - {img.name}")
+ output.append(f" - {img.name}")
+ return "\n".join(output)
# [END compute_images_list_page]
diff --git a/samples/snippets/instance_templates/__init__.py b/samples/snippets/instance_templates/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/snippets/instance_templates/create.py b/samples/snippets/instance_templates/create.py
new file mode 100644
index 000000000..f328bbfc1
--- /dev/null
+++ b/samples/snippets/instance_templates/create.py
@@ -0,0 +1,78 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_template_create]
+from google.cloud import compute_v1
+
+
+def create_template(project_id: str, template_name: str) -> compute_v1.InstanceTemplate:
+ """
+ Create a new instance template with the provided name and a specific
+ instance configuration.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you use.
+ template_name: name of the new template to create.
+
+ Returns:
+ InstanceTemplate object that represents the new instance template.
+ """
+ # The template describes the size and source image of the boot disk
+ # to attach to the instance.
+ disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = (
+ "projects/debian-cloud/global/images/family/debian-11"
+ )
+ initialize_params.disk_size_gb = 250
+ disk.initialize_params = initialize_params
+ disk.auto_delete = True
+ disk.boot = True
+
+ # The template connects the instance to the `default` network,
+ # without specifying a subnetwork.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = "global/networks/default"
+
+ # The template lets the instance use an external IP address.
+ access_config = compute_v1.AccessConfig()
+ access_config.name = "External NAT"
+ access_config.type_ = "ONE_TO_ONE_NAT"
+ access_config.network_tier = "PREMIUM"
+ network_interface.access_configs = [access_config]
+
+ template = compute_v1.InstanceTemplate()
+ template.name = template_name
+ template.properties.disks = [disk]
+ template.properties.machine_type = "e2-standard-4"
+ template.properties.network_interfaces = [network_interface]
+
+ template_client = compute_v1.InstanceTemplatesClient()
+ operation_client = compute_v1.GlobalOperationsClient()
+ op = template_client.insert_unary(
+ project=project_id, instance_template_resource=template
+ )
+ operation_client.wait(project=project_id, operation=op.name)
+
+ return template_client.get(project=project_id, instance_template=template_name)
+
+
+# [END compute_template_create]
diff --git a/samples/snippets/instance_templates/create_from_instance.py b/samples/snippets/instance_templates/create_from_instance.py
new file mode 100644
index 000000000..20afc7154
--- /dev/null
+++ b/samples/snippets/instance_templates/create_from_instance.py
@@ -0,0 +1,68 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_template_create_from_instance]
+from google.cloud import compute_v1
+
+
+def create_template_from_instance(
+ project_id: str, instance: str, template_name: str
+) -> compute_v1.InstanceTemplate:
+ """
+ Create a new instance template based on an existing instance.
+ This new template specifies a different boot disk.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you use.
+ instance: the instance to base the new template on. This value uses
+ the following format: "projects/{project}/zones/{zone}/instances/{instance_name}"
+ template_name: name of the new template to create.
+
+ Returns:
+ InstanceTemplate object that represents the new instance template.
+ """
+ disk = compute_v1.DiskInstantiationConfig()
+ # Device name must match the name of a disk attached to the instance you are
+ # basing your template on.
+ disk.device_name = "disk-1"
+ # Replace the original boot disk image used in your instance with a Rocky Linux image.
+ disk.instantiate_from = "CUSTOM_IMAGE"
+ disk.custom_image = "projects/rocky-linux-cloud/global/images/family/rocky-linux-8"
+ # Override the auto_delete setting.
+ disk.auto_delete = True
+
+ template = compute_v1.InstanceTemplate()
+ template.name = template_name
+ template.source_instance = instance
+ template.source_instance_params = compute_v1.SourceInstanceParams()
+ template.source_instance_params.disk_configs = [disk]
+
+ template_client = compute_v1.InstanceTemplatesClient()
+ operation_client = compute_v1.GlobalOperationsClient()
+ op = template_client.insert_unary(
+ project=project_id, instance_template_resource=template
+ )
+ operation_client.wait(project=project_id, operation=op.name)
+
+ return template_client.get(project=project_id, instance_template=template_name)
+
+
+# [END compute_template_create_from_instance]
diff --git a/samples/snippets/instance_templates/create_with_subnet.py b/samples/snippets/instance_templates/create_with_subnet.py
new file mode 100644
index 000000000..ea6ddc191
--- /dev/null
+++ b/samples/snippets/instance_templates/create_with_subnet.py
@@ -0,0 +1,77 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_template_create_with_subnet]
+from google.cloud import compute_v1
+
+
+def create_template_with_subnet(
+ project_id: str, network: str, subnetwork: str, template_name: str
+) -> compute_v1.InstanceTemplate:
+ """
+ Create an instance template that uses a provided subnet.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you use.
+ network: the network to be used in the new template. This value uses
+ the following format: "projects/{project}/global/networks/{network}"
+ subnetwork: the subnetwork to be used in the new template. This value
+ uses the following format: "projects/{project}/regions/{region}/subnetworks/{subnetwork}"
+ template_name: name of the new template to create.
+
+ Returns:
+ InstanceTemplate object that represents the new instance template.
+ """
+ # The template describes the size and source image of the book disk to
+ # attach to the instance.
+ disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = (
+ "projects/debian-cloud/global/images/family/debian-11"
+ )
+ initialize_params.disk_size_gb = 250
+ disk.initialize_params = initialize_params
+ disk.auto_delete = True
+ disk.boot = True
+
+ template = compute_v1.InstanceTemplate()
+ template.name = template_name
+ template.properties = compute_v1.InstanceProperties()
+ template.properties.disks = [disk]
+ template.properties.machine_type = "e2-standard-4"
+
+ # The template connects the instance to the specified network and subnetwork.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.network = network
+ network_interface.subnetwork = subnetwork
+ template.properties.network_interfaces = [network_interface]
+
+ template_client = compute_v1.InstanceTemplatesClient()
+ operation_client = compute_v1.GlobalOperationsClient()
+ op = template_client.insert_unary(
+ project=project_id, instance_template_resource=template
+ )
+ operation_client.wait(project=project_id, operation=op.name)
+
+ return template_client.get(project=project_id, instance_template=template_name)
+
+
+# [END compute_template_create_with_subnet]
diff --git a/samples/snippets/instance_templates/delete.py b/samples/snippets/instance_templates/delete.py
new file mode 100644
index 000000000..b0700c9ab
--- /dev/null
+++ b/samples/snippets/instance_templates/delete.py
@@ -0,0 +1,43 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_template_delete]
+from google.cloud import compute_v1
+
+
+def delete_instance_template(project_id: str, template_name: str):
+ """
+ Delete an instance template.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you use.
+ template_name: name of the template to delete.
+ """
+ template_client = compute_v1.InstanceTemplatesClient()
+ operation_client = compute_v1.GlobalOperationsClient()
+ op = template_client.delete_unary(
+ project=project_id, instance_template=template_name
+ )
+ operation_client.wait(project=project_id, operation=op.name)
+ return
+
+
+# [END compute_template_delete]
diff --git a/samples/snippets/instance_templates/get.py b/samples/snippets/instance_templates/get.py
new file mode 100644
index 000000000..439b3bea9
--- /dev/null
+++ b/samples/snippets/instance_templates/get.py
@@ -0,0 +1,44 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_template_get]
+from google.cloud import compute_v1
+
+
+def get_instance_template(
+ project_id: str, template_name: str
+) -> compute_v1.InstanceTemplate:
+ """
+ Retrieve an instance template, which you can use to create virtual machine
+ (VM) instances and managed instance groups (MIGs).
+
+ Args:
+ project_id: project ID or project number of the Cloud project you use.
+ template_name: name of the template to retrieve.
+
+ Returns:
+ InstanceTemplate object that represents the retrieved template.
+ """
+ template_client = compute_v1.InstanceTemplatesClient()
+ return template_client.get(project=project_id, instance_template=template_name)
+
+
+# [END compute_template_get]
diff --git a/samples/snippets/instance_templates/list.py b/samples/snippets/instance_templates/list.py
new file mode 100644
index 000000000..495686c62
--- /dev/null
+++ b/samples/snippets/instance_templates/list.py
@@ -0,0 +1,42 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_template_list]
+from typing import Iterable
+
+from google.cloud import compute_v1
+
+
+def list_instance_templates(project_id: str) -> Iterable[compute_v1.InstanceTemplate]:
+ """
+ Get a list of InstanceTemplate objects available in a project.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you use.
+
+ Returns:
+ Iterable list of InstanceTemplate objects.
+ """
+ template_client = compute_v1.InstanceTemplatesClient()
+ return template_client.list(project=project_id)
+
+
+# [END compute_template_list]
diff --git a/samples/snippets/instances/__init__.py b/samples/snippets/instances/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/snippets/instances/create.py b/samples/snippets/instances/create.py
new file mode 100644
index 000000000..73d2d806c
--- /dev/null
+++ b/samples/snippets/instances/create.py
@@ -0,0 +1,195 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_instances_create]
+import re
+import sys
+from typing import List
+
+from google.cloud import compute_v1
+
+
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(project=project, family=family)
+ return newest_image
+
+
+def disk_from_image(
+ disk_type: str, disk_size_gb: int, boot: bool, source_image: str
+) -> compute_v1.AttachedDisk:
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
+ of the publicly available images or an image from one of your projects.
+ This value uses the following format: "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified image.
+ """
+ boot_disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = source_image
+ initialize_params.disk_size_gb = disk_size_gb
+ initialize_params.disk_type = disk_type
+ boot_disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ boot_disk.auto_delete = True
+ boot_disk.boot = boot
+ return boot_disk
+
+
+def create_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
+ """
+ Send an instance creation request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ machine_type: machine type of the VM being created. This value uses the
+ following format: "zones/{zone}/machineTypes/{type_name}".
+ For example: "zones/europe-west3-c/machineTypes/f1-micro"
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ # Use the network interface provided in the network_link argument.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
+
+ # Collect information into the Instance object.
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
+ instance.network_interfaces = [network_interface]
+
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Shielded Instance settings
+ # Values presented here are the defaults.
+ # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
+ # instance.shielded_instance_config.enable_secure_boot = False
+ # instance.shielded_instance_config.enable_vtpm = True
+ # instance.shielded_instance_config.enable_integrity_monitoring = True
+
+ # Prepare the request to insert an instance.
+ request = compute_v1.InsertInstanceRequest()
+ request.zone = zone
+ request.project = project_id
+ request.instance_resource = instance
+
+ # Wait for the create operation to complete.
+ print(f"Creating the {instance_name} instance in {zone}...")
+
+ operation = instance_client.insert_unary(request=request)
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if operation.error:
+ print("Error during creation:", operation.error, file=sys.stderr)
+ if operation.warnings:
+ print("Warning during creation:", operation.warnings, file=sys.stderr)
+ print(f"Instance {instance_name} created.")
+ return instance
+
+
+# [END compute_instances_create]
+
+if __name__ == "__main__":
+ import uuid
+ import google.auth
+ import google.auth.exceptions
+
+ try:
+ default_project_id = google.auth.default()[1]
+ except google.auth.exceptions.DefaultCredentialsError:
+ print(
+ "Please use `gcloud auth application-default login` "
+ "or set GOOGLE_APPLICATION_CREDENTIALS to use this script."
+ )
+ else:
+ instance_name = "quickstart-" + uuid.uuid4().hex[:10]
+ instance_zone = "europe-central2-b"
+
+ newest_debian = get_image_from_family(
+ project="debian-cloud", family="debian-10"
+ )
+ disk_type = f"zones/{instance_zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+
+ create_instance(default_project_id, instance_zone, instance_name, disks)
diff --git a/samples/snippets/instances/create_start_instance/__init__.py b/samples/snippets/instances/create_start_instance/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/snippets/instances/create_start_instance/create_from_custom_image.py b/samples/snippets/instances/create_start_instance/create_from_custom_image.py
new file mode 100644
index 000000000..0cea57407
--- /dev/null
+++ b/samples/snippets/instances/create_start_instance/create_from_custom_image.py
@@ -0,0 +1,193 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_instances_create_from_custom_image]
+import re
+import sys
+from typing import List
+
+from google.cloud import compute_v1
+
+
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(project=project, family=family)
+ return newest_image
+
+
+def disk_from_image(
+ disk_type: str, disk_size_gb: int, boot: bool, source_image: str
+) -> compute_v1.AttachedDisk:
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
+ of the publicly available images or an image from one of your projects.
+ This value uses the following format: "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified image.
+ """
+ boot_disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = source_image
+ initialize_params.disk_size_gb = disk_size_gb
+ initialize_params.disk_type = disk_type
+ boot_disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ boot_disk.auto_delete = True
+ boot_disk.boot = boot
+ return boot_disk
+
+
+def create_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
+ """
+ Send an instance creation request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ machine_type: machine type of the VM being created. This value uses the
+ following format: "zones/{zone}/machineTypes/{type_name}".
+ For example: "zones/europe-west3-c/machineTypes/f1-micro"
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ # Use the network interface provided in the network_link argument.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
+
+ # Collect information into the Instance object.
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
+ instance.network_interfaces = [network_interface]
+
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Shielded Instance settings
+ # Values presented here are the defaults.
+ # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
+ # instance.shielded_instance_config.enable_secure_boot = False
+ # instance.shielded_instance_config.enable_vtpm = True
+ # instance.shielded_instance_config.enable_integrity_monitoring = True
+
+ # Prepare the request to insert an instance.
+ request = compute_v1.InsertInstanceRequest()
+ request.zone = zone
+ request.project = project_id
+ request.instance_resource = instance
+
+ # Wait for the create operation to complete.
+ print(f"Creating the {instance_name} instance in {zone}...")
+
+ operation = instance_client.insert_unary(request=request)
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if operation.error:
+ print("Error during creation:", operation.error, file=sys.stderr)
+ if operation.warnings:
+ print("Warning during creation:", operation.warnings, file=sys.stderr)
+ print(f"Instance {instance_name} created.")
+ return instance
+
+
+def create_from_custom_image(
+ project_id: str, zone: str, instance_name: str, custom_image_link: str
+) -> compute_v1.Instance:
+ """
+ Create a new VM instance with custom image used as its boot disk.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ custom_image_link: link to the custom image you want to use in the form of:
+ "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ Instance object.
+ """
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, custom_image_link)]
+ instance = create_instance(project_id, zone, instance_name, disks)
+ return instance
+
+
+# [END compute_instances_create_from_custom_image]
diff --git a/samples/snippets/instances/create_start_instance/create_from_public_image.py b/samples/snippets/instances/create_start_instance/create_from_public_image.py
new file mode 100644
index 000000000..0d309604a
--- /dev/null
+++ b/samples/snippets/instances/create_start_instance/create_from_public_image.py
@@ -0,0 +1,192 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_instances_create_from_image]
+import re
+import sys
+from typing import List
+
+from google.cloud import compute_v1
+
+
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(project=project, family=family)
+ return newest_image
+
+
+def disk_from_image(
+ disk_type: str, disk_size_gb: int, boot: bool, source_image: str
+) -> compute_v1.AttachedDisk:
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
+ of the publicly available images or an image from one of your projects.
+ This value uses the following format: "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified image.
+ """
+ boot_disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = source_image
+ initialize_params.disk_size_gb = disk_size_gb
+ initialize_params.disk_type = disk_type
+ boot_disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ boot_disk.auto_delete = True
+ boot_disk.boot = boot
+ return boot_disk
+
+
+def create_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
+ """
+ Send an instance creation request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ machine_type: machine type of the VM being created. This value uses the
+ following format: "zones/{zone}/machineTypes/{type_name}".
+ For example: "zones/europe-west3-c/machineTypes/f1-micro"
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ # Use the network interface provided in the network_link argument.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
+
+ # Collect information into the Instance object.
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
+ instance.network_interfaces = [network_interface]
+
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Shielded Instance settings
+ # Values presented here are the defaults.
+ # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
+ # instance.shielded_instance_config.enable_secure_boot = False
+ # instance.shielded_instance_config.enable_vtpm = True
+ # instance.shielded_instance_config.enable_integrity_monitoring = True
+
+ # Prepare the request to insert an instance.
+ request = compute_v1.InsertInstanceRequest()
+ request.zone = zone
+ request.project = project_id
+ request.instance_resource = instance
+
+ # Wait for the create operation to complete.
+ print(f"Creating the {instance_name} instance in {zone}...")
+
+ operation = instance_client.insert_unary(request=request)
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if operation.error:
+ print("Error during creation:", operation.error, file=sys.stderr)
+ if operation.warnings:
+ print("Warning during creation:", operation.warnings, file=sys.stderr)
+ print(f"Instance {instance_name} created.")
+ return instance
+
+
+def create_from_public_image(
+ project_id: str, zone: str, instance_name: str
+) -> compute_v1.Instance:
+ """
+ Create a new VM instance with Debian 10 operating system.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+
+ Returns:
+ Instance object.
+ """
+ newest_debian = get_image_from_family(project="debian-cloud", family="debian-10")
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+ instance = create_instance(project_id, zone, instance_name, disks)
+ return instance
+
+
+# [END compute_instances_create_from_image]
diff --git a/samples/snippets/instances/create_start_instance/create_from_snapshot.py b/samples/snippets/instances/create_start_instance/create_from_snapshot.py
new file mode 100644
index 000000000..bc7b01c26
--- /dev/null
+++ b/samples/snippets/instances/create_start_instance/create_from_snapshot.py
@@ -0,0 +1,185 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_instances_create_from_snapshot]
+import re
+import sys
+from typing import List
+
+from google.cloud import compute_v1
+
+
+def disk_from_snapshot(
+ disk_type: str, disk_size_gb: int, boot: bool, disk_snapshot: str
+) -> compute_v1.AttachedDisk():
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses a disk snapshot as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ disk_snapshot: disk snapshot to use when creating this disk. You must have read access to this disk.
+ This value uses the following format: "projects/{project_name}/global/snapshots/{snapshot_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified snapshot.
+ """
+ disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_snapshot = disk_snapshot
+ initialize_params.disk_type = disk_type
+ initialize_params.disk_size_gb = disk_size_gb
+ disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ disk.auto_delete = True
+ disk.boot = boot
+ return disk
+
+
+def create_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
+ """
+ Send an instance creation request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ machine_type: machine type of the VM being created. This value uses the
+ following format: "zones/{zone}/machineTypes/{type_name}".
+ For example: "zones/europe-west3-c/machineTypes/f1-micro"
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ # Use the network interface provided in the network_link argument.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
+
+ # Collect information into the Instance object.
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
+ instance.network_interfaces = [network_interface]
+
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Shielded Instance settings
+ # Values presented here are the defaults.
+ # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
+ # instance.shielded_instance_config.enable_secure_boot = False
+ # instance.shielded_instance_config.enable_vtpm = True
+ # instance.shielded_instance_config.enable_integrity_monitoring = True
+
+ # Prepare the request to insert an instance.
+ request = compute_v1.InsertInstanceRequest()
+ request.zone = zone
+ request.project = project_id
+ request.instance_resource = instance
+
+ # Wait for the create operation to complete.
+ print(f"Creating the {instance_name} instance in {zone}...")
+
+ operation = instance_client.insert_unary(request=request)
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if operation.error:
+ print("Error during creation:", operation.error, file=sys.stderr)
+ if operation.warnings:
+ print("Warning during creation:", operation.warnings, file=sys.stderr)
+ print(f"Instance {instance_name} created.")
+ return instance
+
+
+def create_from_snapshot(
+ project_id: str, zone: str, instance_name: str, snapshot_link: str
+):
+ """
+ Create a new VM instance with boot disk created from a snapshot.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ snapshot_link: link to the snapshot you want to use as the source of your
+ boot disk in the form of: "projects/{project_name}/global/snapshots/{snapshot_name}"
+
+ Returns:
+ Instance object.
+ """
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_snapshot(disk_type, 11, True, snapshot_link)]
+ instance = create_instance(project_id, zone, instance_name, disks)
+ return instance
+
+
+# [END compute_instances_create_from_snapshot]
diff --git a/samples/snippets/instances/create_start_instance/create_with_additional_disk.py b/samples/snippets/instances/create_start_instance/create_with_additional_disk.py
new file mode 100644
index 000000000..7945638de
--- /dev/null
+++ b/samples/snippets/instances/create_start_instance/create_with_additional_disk.py
@@ -0,0 +1,222 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_instances_create_from_image_plus_empty_disk]
+import re
+import sys
+from typing import List
+
+from google.cloud import compute_v1
+
+
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(project=project, family=family)
+ return newest_image
+
+
+def disk_from_image(
+ disk_type: str, disk_size_gb: int, boot: bool, source_image: str
+) -> compute_v1.AttachedDisk:
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
+ of the publicly available images or an image from one of your projects.
+ This value uses the following format: "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified image.
+ """
+ boot_disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = source_image
+ initialize_params.disk_size_gb = disk_size_gb
+ initialize_params.disk_type = disk_type
+ boot_disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ boot_disk.auto_delete = True
+ boot_disk.boot = boot
+ return boot_disk
+
+
+def empty_disk(disk_type: str, disk_size_gb: int) -> compute_v1.AttachedDisk():
+ """
+ Create an AttachedDisk object to be used in VM instance creation. The created disk contains
+ no data and requires formatting before it can be used.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+
+ Returns:
+ AttachedDisk object configured to be created as an empty disk.
+ """
+ disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.disk_type = disk_type
+ initialize_params.disk_size_gb = disk_size_gb
+ disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ disk.auto_delete = True
+ disk.boot = False
+ return disk
+
+
+def create_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
+ """
+ Send an instance creation request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ machine_type: machine type of the VM being created. This value uses the
+ following format: "zones/{zone}/machineTypes/{type_name}".
+ For example: "zones/europe-west3-c/machineTypes/f1-micro"
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ # Use the network interface provided in the network_link argument.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
+
+ # Collect information into the Instance object.
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
+ instance.network_interfaces = [network_interface]
+
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Shielded Instance settings
+ # Values presented here are the defaults.
+ # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
+ # instance.shielded_instance_config.enable_secure_boot = False
+ # instance.shielded_instance_config.enable_vtpm = True
+ # instance.shielded_instance_config.enable_integrity_monitoring = True
+
+ # Prepare the request to insert an instance.
+ request = compute_v1.InsertInstanceRequest()
+ request.zone = zone
+ request.project = project_id
+ request.instance_resource = instance
+
+ # Wait for the create operation to complete.
+ print(f"Creating the {instance_name} instance in {zone}...")
+
+ operation = instance_client.insert_unary(request=request)
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if operation.error:
+ print("Error during creation:", operation.error, file=sys.stderr)
+ if operation.warnings:
+ print("Warning during creation:", operation.warnings, file=sys.stderr)
+ print(f"Instance {instance_name} created.")
+ return instance
+
+
+def create_with_additional_disk(
+ project_id: str, zone: str, instance_name: str
+) -> compute_v1.Instance:
+ """
+ Create a new VM instance with Debian 10 operating system and a 11 GB additional
+ empty disk.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+
+ Returns:
+ Instance object.
+ """
+ newest_debian = get_image_from_family(project="debian-cloud", family="debian-10")
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [
+ disk_from_image(disk_type, 10, True, newest_debian.self_link),
+ empty_disk(disk_type, 11),
+ ]
+ instance = create_instance(project_id, zone, instance_name, disks)
+ return instance
+
+
+# [END compute_instances_create_from_image_plus_empty_disk]
diff --git a/samples/snippets/instances/create_start_instance/create_with_snapshotted_data_disk.py b/samples/snippets/instances/create_start_instance/create_with_snapshotted_data_disk.py
new file mode 100644
index 000000000..134f41c01
--- /dev/null
+++ b/samples/snippets/instances/create_start_instance/create_with_snapshotted_data_disk.py
@@ -0,0 +1,229 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_instances_create_from_image_plus_snapshot_disk]
+import re
+import sys
+from typing import List
+
+from google.cloud import compute_v1
+
+
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(project=project, family=family)
+ return newest_image
+
+
+def disk_from_image(
+ disk_type: str, disk_size_gb: int, boot: bool, source_image: str
+) -> compute_v1.AttachedDisk:
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
+ of the publicly available images or an image from one of your projects.
+ This value uses the following format: "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified image.
+ """
+ boot_disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = source_image
+ initialize_params.disk_size_gb = disk_size_gb
+ initialize_params.disk_type = disk_type
+ boot_disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ boot_disk.auto_delete = True
+ boot_disk.boot = boot
+ return boot_disk
+
+
+def disk_from_snapshot(
+ disk_type: str, disk_size_gb: int, boot: bool, disk_snapshot: str
+) -> compute_v1.AttachedDisk():
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses a disk snapshot as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ disk_snapshot: disk snapshot to use when creating this disk. You must have read access to this disk.
+ This value uses the following format: "projects/{project_name}/global/snapshots/{snapshot_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified snapshot.
+ """
+ disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_snapshot = disk_snapshot
+ initialize_params.disk_type = disk_type
+ initialize_params.disk_size_gb = disk_size_gb
+ disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ disk.auto_delete = True
+ disk.boot = boot
+ return disk
+
+
+def create_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
+ """
+ Send an instance creation request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ machine_type: machine type of the VM being created. This value uses the
+ following format: "zones/{zone}/machineTypes/{type_name}".
+ For example: "zones/europe-west3-c/machineTypes/f1-micro"
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ # Use the network interface provided in the network_link argument.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
+
+ # Collect information into the Instance object.
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
+ instance.network_interfaces = [network_interface]
+
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Shielded Instance settings
+ # Values presented here are the defaults.
+ # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
+ # instance.shielded_instance_config.enable_secure_boot = False
+ # instance.shielded_instance_config.enable_vtpm = True
+ # instance.shielded_instance_config.enable_integrity_monitoring = True
+
+ # Prepare the request to insert an instance.
+ request = compute_v1.InsertInstanceRequest()
+ request.zone = zone
+ request.project = project_id
+ request.instance_resource = instance
+
+ # Wait for the create operation to complete.
+ print(f"Creating the {instance_name} instance in {zone}...")
+
+ operation = instance_client.insert_unary(request=request)
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if operation.error:
+ print("Error during creation:", operation.error, file=sys.stderr)
+ if operation.warnings:
+ print("Warning during creation:", operation.warnings, file=sys.stderr)
+ print(f"Instance {instance_name} created.")
+ return instance
+
+
+def create_with_snapshotted_data_disk(
+ project_id: str, zone: str, instance_name: str, snapshot_link: str
+):
+ """
+ Create a new VM instance with Debian 10 operating system and data disk created from snapshot.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ snapshot_link: link to the snapshot you want to use as the source of your
+ data disk in the form of: "projects/{project_name}/global/snapshots/{snapshot_name}"
+
+ Returns:
+ Instance object.
+ """
+ newest_debian = get_image_from_family(project="debian-cloud", family="debian-10")
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [
+ disk_from_image(disk_type, 10, True, newest_debian.self_link),
+ disk_from_snapshot(disk_type, 11, False, snapshot_link),
+ ]
+ instance = create_instance(project_id, zone, instance_name, disks)
+ return instance
+
+
+# [END compute_instances_create_from_image_plus_snapshot_disk]
diff --git a/samples/snippets/instances/create_with_subnet.py b/samples/snippets/instances/create_with_subnet.py
new file mode 100644
index 000000000..63e46d0cc
--- /dev/null
+++ b/samples/snippets/instances/create_with_subnet.py
@@ -0,0 +1,205 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_instances_create_with_subnet]
+import re
+import sys
+from typing import List
+
+from google.cloud import compute_v1
+
+
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(project=project, family=family)
+ return newest_image
+
+
+def disk_from_image(
+ disk_type: str, disk_size_gb: int, boot: bool, source_image: str
+) -> compute_v1.AttachedDisk:
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
+ of the publicly available images or an image from one of your projects.
+ This value uses the following format: "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified image.
+ """
+ boot_disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = source_image
+ initialize_params.disk_size_gb = disk_size_gb
+ initialize_params.disk_type = disk_type
+ boot_disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ boot_disk.auto_delete = True
+ boot_disk.boot = boot
+ return boot_disk
+
+
+def create_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
+ """
+ Send an instance creation request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ machine_type: machine type of the VM being created. This value uses the
+ following format: "zones/{zone}/machineTypes/{type_name}".
+ For example: "zones/europe-west3-c/machineTypes/f1-micro"
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ # Use the network interface provided in the network_link argument.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
+
+ # Collect information into the Instance object.
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
+ instance.network_interfaces = [network_interface]
+
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Shielded Instance settings
+ # Values presented here are the defaults.
+ # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
+ # instance.shielded_instance_config.enable_secure_boot = False
+ # instance.shielded_instance_config.enable_vtpm = True
+ # instance.shielded_instance_config.enable_integrity_monitoring = True
+
+ # Prepare the request to insert an instance.
+ request = compute_v1.InsertInstanceRequest()
+ request.zone = zone
+ request.project = project_id
+ request.instance_resource = instance
+
+ # Wait for the create operation to complete.
+ print(f"Creating the {instance_name} instance in {zone}...")
+
+ operation = instance_client.insert_unary(request=request)
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if operation.error:
+ print("Error during creation:", operation.error, file=sys.stderr)
+ if operation.warnings:
+ print("Warning during creation:", operation.warnings, file=sys.stderr)
+ print(f"Instance {instance_name} created.")
+ return instance
+
+
+def create_with_subnet(
+ project_id: str, zone: str, instance_name: str, network_link: str, subnet_link: str
+) -> compute_v1.Instance:
+ """
+ Create a new VM instance with Debian 10 operating system in specified network and subnetwork.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+
+ Returns:
+ Instance object.
+ """
+ newest_debian = get_image_from_family(project="debian-cloud", family="debian-10")
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+ instance = create_instance(
+ project_id,
+ zone,
+ instance_name,
+ disks,
+ network_link=network_link,
+ subnetwork_link=subnet_link,
+ )
+ return instance
+
+
+# [END compute_instances_create_with_subnet]
diff --git a/samples/snippets/instances/custom_hostname/create.py b/samples/snippets/instances/custom_hostname/create.py
new file mode 100644
index 000000000..c600f6c17
--- /dev/null
+++ b/samples/snippets/instances/custom_hostname/create.py
@@ -0,0 +1,195 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_instances_create_custom_hostname]
+import re
+import sys
+from typing import List
+
+from google.cloud import compute_v1
+
+
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(project=project, family=family)
+ return newest_image
+
+
+def disk_from_image(
+ disk_type: str, disk_size_gb: int, boot: bool, source_image: str
+) -> compute_v1.AttachedDisk:
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
+ of the publicly available images or an image from one of your projects.
+ This value uses the following format: "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified image.
+ """
+ boot_disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = source_image
+ initialize_params.disk_size_gb = disk_size_gb
+ initialize_params.disk_type = disk_type
+ boot_disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ boot_disk.auto_delete = True
+ boot_disk.boot = boot
+ return boot_disk
+
+
+def create_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
+ """
+ Send an instance creation request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ machine_type: machine type of the VM being created. This value uses the
+ following format: "zones/{zone}/machineTypes/{type_name}".
+ For example: "zones/europe-west3-c/machineTypes/f1-micro"
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ # Use the network interface provided in the network_link argument.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
+
+ # Collect information into the Instance object.
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
+ instance.network_interfaces = [network_interface]
+
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Shielded Instance settings
+ # Values presented here are the defaults.
+ # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
+ # instance.shielded_instance_config.enable_secure_boot = False
+ # instance.shielded_instance_config.enable_vtpm = True
+ # instance.shielded_instance_config.enable_integrity_monitoring = True
+
+ # Prepare the request to insert an instance.
+ request = compute_v1.InsertInstanceRequest()
+ request.zone = zone
+ request.project = project_id
+ request.instance_resource = instance
+
+ # Wait for the create operation to complete.
+ print(f"Creating the {instance_name} instance in {zone}...")
+
+ operation = instance_client.insert_unary(request=request)
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if operation.error:
+ print("Error during creation:", operation.error, file=sys.stderr)
+ if operation.warnings:
+ print("Warning during creation:", operation.warnings, file=sys.stderr)
+ print(f"Instance {instance_name} created.")
+ return instance
+
+
+def create_instance_custom_hostname(
+ project_id: str, zone: str, instance_name: str, hostname: str
+) -> compute_v1.Instance:
+ """
+ Create a new VM instance with Debian 10 operating system and a custom hostname.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ hostname: the hostname you want to use for the new instance.
+
+ Returns:
+ Instance object.
+ """
+ newest_debian = get_image_from_family(project="debian-cloud", family="debian-11")
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+ instance = create_instance(
+ project_id, zone, instance_name, disks, custom_hostname=hostname
+ )
+ return instance
+
+
+# [END compute_instances_create_custom_hostname]
diff --git a/samples/snippets/instances/custom_hostname/get.py b/samples/snippets/instances/custom_hostname/get.py
new file mode 100644
index 000000000..673d5c810
--- /dev/null
+++ b/samples/snippets/instances/custom_hostname/get.py
@@ -0,0 +1,45 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_instances_get_hostname]
+from google.cloud import compute_v1
+
+
+def get_hostname(project_id: str, zone: str, instance_name: str) -> str:
+ """
+ Retrieve the hostname of given instance.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: "us-west3-b"
+ instance_name: name of the virtual machine to check.
+
+ Returns:
+ The hostname of an instance.
+ """
+ instance_client = compute_v1.InstancesClient()
+ instance = instance_client.get(
+ project=project_id, zone=zone, instance=instance_name
+ )
+ return instance.hostname
+
+
+# [END compute_instances_get_hostname]
diff --git a/samples/snippets/instances/custom_machine_types/__init__.py b/samples/snippets/instances/custom_machine_types/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/snippets/instances/custom_machine_types/create_shared_with_helper.py b/samples/snippets/instances/custom_machine_types/create_shared_with_helper.py
new file mode 100644
index 000000000..16d107883
--- /dev/null
+++ b/samples/snippets/instances/custom_machine_types/create_shared_with_helper.py
@@ -0,0 +1,390 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_custom_machine_type_create_shared_with_helper]
+from collections import namedtuple
+from enum import Enum
+from enum import unique
+import re
+import sys
+from typing import List
+
+from google.cloud import compute_v1
+
+
+def gb_to_mb(value: int) -> int:
+ return value << 10
+
+
+class CustomMachineType:
+ """
+ Allows to create custom machine types to be used with the VM instances.
+ """
+
+ @unique
+ class CPUSeries(Enum):
+ N1 = "custom"
+ N2 = "n2-custom"
+ N2D = "n2d-custom"
+ E2 = "e2-custom"
+ E2_MICRO = "e2-custom-micro"
+ E2_SMALL = "e2-custom-small"
+ E2_MEDIUM = "e2-custom-medium"
+
+ TypeLimits = namedtuple(
+ "TypeLimits",
+ [
+ "allowed_cores",
+ "min_mem_per_core",
+ "max_mem_per_core",
+ "allow_extra_memory",
+ "extra_memory_limit",
+ ],
+ )
+
+ LIMITS = {
+ CPUSeries.E2: TypeLimits(frozenset(range(2, 33, 2)), 512, 8192, False, 0),
+ CPUSeries.E2_MICRO: TypeLimits(frozenset(), 1024, 2048, False, 0),
+ CPUSeries.E2_SMALL: TypeLimits(frozenset(), 2048, 4096, False, 0),
+ CPUSeries.E2_MEDIUM: TypeLimits(frozenset(), 4096, 8192, False, 0),
+ CPUSeries.N2: TypeLimits(
+ frozenset(range(2, 33, 2)).union(set(range(36, 129, 4))),
+ 512,
+ 8192,
+ True,
+ gb_to_mb(624),
+ ),
+ CPUSeries.N2D: TypeLimits(
+ frozenset({2, 4, 8, 16, 32, 48, 64, 80, 96}), 512, 8192, True, gb_to_mb(768)
+ ),
+ CPUSeries.N1: TypeLimits(
+ frozenset({1}.union(range(2, 97, 2))), 922, 6656, True, gb_to_mb(624)
+ ),
+ }
+
+ def __init__(
+ self, zone: str, cpu_series: CPUSeries, memory_mb: int, core_count: int = 0
+ ):
+ self.zone = zone
+ self.cpu_series = cpu_series
+ self.limits = self.LIMITS[self.cpu_series]
+ self.core_count = 2 if self.is_shared() else core_count
+ self.memory_mb = memory_mb
+
+ self._check()
+ self.extra_memory_used = self._check_extra_memory()
+
+ def is_shared(self):
+ return self.cpu_series in (
+ CustomMachineType.CPUSeries.E2_SMALL,
+ CustomMachineType.CPUSeries.E2_MICRO,
+ CustomMachineType.CPUSeries.E2_MEDIUM,
+ )
+
+ def _check_extra_memory(self) -> bool:
+ # Assuming this runs after _check() and the total memory requested is correct
+ return self.memory_mb > self.core_count * self.limits.max_mem_per_core
+
+ def _check(self):
+ """
+ Check whether the requested parameters are allowed. Find more information about limitations of custom machine
+ types at: https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types
+ """
+ # Check the number of cores
+ if (
+ self.limits.allowed_cores
+ and self.core_count not in self.limits.allowed_cores
+ ):
+ raise RuntimeError(
+ f"Invalid number of cores requested. Allowed number of cores for {self.cpu_series.name} is: {sorted(self.limits.allowed_cores)}"
+ )
+
+ # Memory must be a multiple of 256 MB
+ if self.memory_mb % 256 != 0:
+ raise RuntimeError("Requested memory must be a multiple of 256 MB.")
+
+ # Check if the requested memory isn't too little
+ if self.memory_mb < self.core_count * self.limits.min_mem_per_core:
+ raise RuntimeError(
+ f"Requested memory is too low. Minimal memory for {self.cpu_series.name} is {self.limits.min_mem_per_core} MB per core."
+ )
+
+ # Check if the requested memory isn't too much
+ if self.memory_mb > self.core_count * self.limits.max_mem_per_core:
+ if self.limits.allow_extra_memory:
+ if self.memory_mb > self.limits.extra_memory_limit:
+ raise RuntimeError(
+ f"Requested memory is too large.. Maximum memory allowed for {self.cpu_series.name} is {self.limits.extra_memory_limit} MB."
+ )
+ else:
+ raise RuntimeError(
+ f"Requested memory is too large.. Maximum memory allowed for {self.cpu_series.name} is {self.limits.max_mem_per_core} MB per core."
+ )
+
+ def __str__(self) -> str:
+ """
+ Return the custom machine type in form of a string acceptable by Compute Engine API.
+ """
+ if self.cpu_series in {
+ self.CPUSeries.E2_SMALL,
+ self.CPUSeries.E2_MICRO,
+ self.CPUSeries.E2_MEDIUM,
+ }:
+ return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.memory_mb}"
+
+ if self.extra_memory_used:
+ return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.core_count}-{self.memory_mb}-ext"
+
+ return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.core_count}-{self.memory_mb}"
+
+ def short_type_str(self) -> str:
+ """
+ Return machine type in a format without the zone. For example, n2-custom-0-10240.
+ This format is used to create instance templates.
+ """
+ return str(self).rsplit("/", maxsplit=1)[1]
+
+ @classmethod
+ def from_str(cls, machine_type: str):
+ """
+ Construct a new object from a string. The string needs to be a valid custom machine type like:
+ - https://www.googleapis.com/compute/v1/projects/diregapic-mestiv/zones/us-central1-b/machineTypes/e2-custom-4-8192
+ - zones/us-central1-b/machineTypes/e2-custom-4-8192
+ - e2-custom-4-8192 (in this case, the zone parameter will not be set)
+ """
+ zone = None
+ if machine_type.startswith("http"):
+ machine_type = machine_type[machine_type.find("zones/") :]
+
+ if machine_type.startswith("zones/"):
+ _, zone, _, machine_type = machine_type.split("/")
+
+ extra_mem = machine_type.endswith("-ext")
+
+ if machine_type.startswith("custom"):
+ cpu = cls.CPUSeries.N1
+ _, cores, memory = machine_type.rsplit("-", maxsplit=2)
+ else:
+ if extra_mem:
+ cpu_series, _, cores, memory, _ = machine_type.split("-")
+ else:
+ cpu_series, _, cores, memory = machine_type.split("-")
+ if cpu_series == "n2":
+ cpu = cls.CPUSeries.N2
+ elif cpu_series == "n2d":
+ cpu = cls.CPUSeries.N2D
+ elif cpu_series == "e2":
+ cpu = cls.CPUSeries.E2
+ if cores == "micro":
+ cpu = cls.CPUSeries.E2_MICRO
+ cores = 2
+ elif cores == "small":
+ cpu = cls.CPUSeries.E2_SMALL
+ cores = 2
+ elif cores == "medium":
+ cpu = cls.CPUSeries.E2_MEDIUM
+ cores = 2
+ else:
+ raise RuntimeError("Unknown CPU series.")
+
+ cores = int(cores)
+ memory = int(memory)
+
+ return cls(zone, cpu, memory, cores)
+
+
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(project=project, family=family)
+ return newest_image
+
+
+def disk_from_image(
+ disk_type: str, disk_size_gb: int, boot: bool, source_image: str
+) -> compute_v1.AttachedDisk:
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
+ of the publicly available images or an image from one of your projects.
+ This value uses the following format: "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified image.
+ """
+ boot_disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = source_image
+ initialize_params.disk_size_gb = disk_size_gb
+ initialize_params.disk_type = disk_type
+ boot_disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ boot_disk.auto_delete = True
+ boot_disk.boot = boot
+ return boot_disk
+
+
+def create_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
+ """
+ Send an instance creation request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ machine_type: machine type of the VM being created. This value uses the
+ following format: "zones/{zone}/machineTypes/{type_name}".
+ For example: "zones/europe-west3-c/machineTypes/f1-micro"
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ # Use the network interface provided in the network_link argument.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
+
+ # Collect information into the Instance object.
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
+ instance.network_interfaces = [network_interface]
+
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Shielded Instance settings
+ # Values presented here are the defaults.
+ # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
+ # instance.shielded_instance_config.enable_secure_boot = False
+ # instance.shielded_instance_config.enable_vtpm = True
+ # instance.shielded_instance_config.enable_integrity_monitoring = True
+
+ # Prepare the request to insert an instance.
+ request = compute_v1.InsertInstanceRequest()
+ request.zone = zone
+ request.project = project_id
+ request.instance_resource = instance
+
+ # Wait for the create operation to complete.
+ print(f"Creating the {instance_name} instance in {zone}...")
+
+ operation = instance_client.insert_unary(request=request)
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if operation.error:
+ print("Error during creation:", operation.error, file=sys.stderr)
+ if operation.warnings:
+ print("Warning during creation:", operation.warnings, file=sys.stderr)
+ print(f"Instance {instance_name} created.")
+ return instance
+
+
+def create_custom_shared_core_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ cpu_series: CustomMachineType.CPUSeries,
+ memory: int,
+) -> compute_v1.Instance:
+ """
+ Create a new VM instance with a custom type using shared CPUs.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ cpu_series: the type of CPU you want to use. Pick one value from the CustomMachineType.CPUSeries enum.
+ For example: CustomMachineType.CPUSeries.E2_MICRO
+ memory: the amount of memory for the VM instance, in megabytes.
+
+ Return:
+ Instance object.
+ """
+ assert cpu_series in (
+ CustomMachineType.CPUSeries.E2_MICRO,
+ CustomMachineType.CPUSeries.E2_SMALL,
+ CustomMachineType.CPUSeries.E2_MEDIUM,
+ )
+ custom_type = CustomMachineType(zone, cpu_series, memory)
+
+ newest_debian = get_image_from_family(project="debian-cloud", family="debian-10")
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+
+ return create_instance(project_id, zone, instance_name, disks, str(custom_type))
+
+
+# [END compute_custom_machine_type_create_shared_with_helper]
diff --git a/samples/snippets/sample_custom_types.py b/samples/snippets/instances/custom_machine_types/create_with_helper.py
similarity index 54%
rename from samples/snippets/sample_custom_types.py
rename to samples/snippets/instances/custom_machine_types/create_with_helper.py
index 38ad64b81..79e7d1a2a 100644
--- a/samples/snippets/sample_custom_types.py
+++ b/samples/snippets/instances/custom_machine_types/create_with_helper.py
@@ -1,4 +1,4 @@
-# Copyright 2021 Google LLC
+# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -11,20 +11,25 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-# [START compute_custom_machine_type_create ]
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_custom_machine_type_create_with_helper]
from collections import namedtuple
-from enum import Enum, unique
+from enum import Enum
+from enum import unique
+import re
import sys
-import time
-from typing import Union
+from typing import List
from google.cloud import compute_v1
-# [END compute_custom_machine_type_create ]
-
-
-# [START compute_custom_machine_type_helper_class ]
def gb_to_mb(value: int) -> int:
return value << 10
@@ -206,16 +211,58 @@ def from_str(cls, machine_type: str):
return cls(zone, cpu, memory, cores)
-# [END compute_custom_machine_type_helper_class ]
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(project=project, family=family)
+ return newest_image
+
+
+def disk_from_image(
+ disk_type: str, disk_size_gb: int, boot: bool, source_image: str
+) -> compute_v1.AttachedDisk:
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
+ of the publicly available images or an image from one of your projects.
+ This value uses the following format: "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified image.
+ """
+ boot_disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = source_image
+ initialize_params.disk_size_gb = disk_size_gb
+ initialize_params.disk_type = disk_type
+ boot_disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ boot_disk.auto_delete = True
+ boot_disk.boot = boot
+ return boot_disk
-# [START compute_custom_machine_type_create ]
def create_instance(
project_id: str,
zone: str,
instance_name: str,
- machine_type: Union[str, "CustomMachineType"],
-):
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
"""
Send an instance creation request to the Compute Engine API and wait for it to complete.
@@ -226,39 +273,63 @@ def create_instance(
machine_type: machine type of the VM being created. This value uses the
following format: "zones/{zone}/machineTypes/{type_name}".
For example: "zones/europe-west3-c/machineTypes/f1-micro"
- OR
- It can be a CustomMachineType object, describing a custom type
- you want to use.
-
- Return:
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
Instance object.
"""
instance_client = compute_v1.InstancesClient()
operation_client = compute_v1.ZoneOperationsClient()
- # Describe the size and source image of the boot disk to attach to the instance.
- disk = compute_v1.AttachedDisk()
- initialize_params = compute_v1.AttachedDiskInitializeParams()
- initialize_params.source_image = (
- "projects/debian-cloud/global/images/family/debian-10"
- )
- initialize_params.disk_size_gb = 10
- disk.initialize_params = initialize_params
- disk.auto_delete = True
- disk.boot = True
- disk.type_ = compute_v1.AttachedDisk.Type.PERSISTENT.name
-
- # Use the network interface provided in the network_name argument.
+ # Use the network interface provided in the network_link argument.
network_interface = compute_v1.NetworkInterface()
- network_interface.name = "global/networks/default"
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
# Collect information into the Instance object.
instance = compute_v1.Instance()
instance.name = instance_name
- instance.disks = [disk]
- instance.machine_type = str(machine_type)
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
instance.network_interfaces = [network_interface]
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Shielded Instance settings
+ # Values presented here are the defaults.
+ # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
+ # instance.shielded_instance_config.enable_secure_boot = False
+ # instance.shielded_instance_config.enable_vtpm = True
+ # instance.shielded_instance_config.enable_integrity_monitoring = True
+
# Prepare the request to insert an instance.
request = compute_v1.InsertInstanceRequest()
request.zone = zone
@@ -266,9 +337,8 @@ def create_instance(
request.instance_resource = instance
# Wait for the create operation to complete.
- print(
- f"Creating the {instance_name} instance of type {instance.machine_type} in {zone}..."
- )
+ print(f"Creating the {instance_name} instance in {zone}...")
+
operation = instance_client.insert_unary(request=request)
while operation.status != compute_v1.Operation.Status.DONE:
operation = operation_client.wait(
@@ -279,13 +349,9 @@ def create_instance(
if operation.warnings:
print("Warning during creation:", operation.warnings, file=sys.stderr)
print(f"Instance {instance_name} created.")
- return instance_client.get(project=project_id, zone=zone, instance=instance.name)
+ return instance
-# [END compute_custom_machine_type_create ]
-
-
-# [START compute_custom_machine_type_create_with_helper ]
def create_custom_instance(
project_id: str,
zone: str,
@@ -316,216 +382,12 @@ def create_custom_instance(
CustomMachineType.CPUSeries.N2D,
)
custom_type = CustomMachineType(zone, cpu_series, memory, core_count)
- return create_instance(project_id, zone, instance_name, custom_type)
-
-
-# [END compute_custom_machine_type_create_with_helper ]
-
-
-# [START compute_custom_machine_type_create_shared_with_helper ]
-def create_custom_shared_core_instance(
- project_id: str,
- zone: str,
- instance_name: str,
- cpu_series: CustomMachineType.CPUSeries,
- memory: int,
-):
- """
- Create a new VM instance with a custom type using shared CPUs.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone to create the instance in. For example: "us-west3-b"
- instance_name: name of the new virtual machine (VM) instance.
- cpu_series: the type of CPU you want to use. Pick one value from the CustomMachineType.CPUSeries enum.
- For example: CustomMachineType.CPUSeries.E2_MICRO
- memory: the amount of memory for the VM instance, in megabytes.
-
- Return:
- Instance object.
- """
- assert cpu_series in (
- CustomMachineType.CPUSeries.E2_MICRO,
- CustomMachineType.CPUSeries.E2_SMALL,
- CustomMachineType.CPUSeries.E2_MEDIUM,
- )
- custom_type = CustomMachineType(zone, cpu_series, memory)
- return create_instance(project_id, zone, instance_name, custom_type)
-
-
-# [END compute_custom_machine_type_create_shared_with_helper ]
-
-
-# [START compute_custom_machine_type_create_without_helper ]
-def create_custom_instances_no_helper(
- project_id: str, zone: str, instance_name: str, core_count: int, memory: int
-):
- """
- Create new VM instances without using a CustomMachineType helper function.
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone to create the instance in. For example: "us-west3-b"
- instance_name: name of the new virtual machine (VM) instance.
- core_count: number of CPU cores you want to use.
- memory: the amount of memory for the VM instance, in megabytes.
-
- Returns:
- List of Instance objects.
- """
- # The core_count and memory values are not validated anywhere and can be rejected by the API.
- instances = [
- create_instance(
- project_id,
- zone,
- f"{instance_name}_n1",
- f"zones/{zone}/machineTypes/custom-{core_count}-{memory}",
- ),
- create_instance(
- project_id,
- zone,
- f"{instance_name}_n2",
- f"zones/{zone}/machineTypes/n2-custom-{core_count}-{memory}",
- ),
- create_instance(
- project_id,
- zone,
- f"{instance_name}_n2d",
- f"zones/{zone}/machineTypes/n2d-custom-{core_count}-{memory}",
- ),
- create_instance(
- project_id,
- zone,
- f"{instance_name}_e2",
- f"zones/{zone}/machineTypes/e2-custom-{core_count}-{memory}",
- ),
- create_instance(
- project_id,
- zone,
- f"{instance_name}_e2_micro",
- f"zones/{zone}/machineTypes/e2-custom-micro-{memory}",
- ),
- create_instance(
- project_id,
- zone,
- f"{instance_name}_e2_small",
- f"zones/{zone}/machineTypes/e2-custom-small-{memory}",
- ),
- create_instance(
- project_id,
- zone,
- f"{instance_name}_e2_medium",
- f"zones/{zone}/machineTypes/e2-custom-medium-{memory}",
- ),
- ]
- return instances
-
-
-# [END compute_custom_machine_type_create_without_helper ]
-
-
-# [START compute_custom_machine_type_extra_mem_no_helper ]
-def create_custom_instances_extra_mem_no_helper(
- project_id: str, zone: str, instance_name: str, core_count: int, memory: int
-):
- """
- Create new VM instances with extra memory without using a CustomMachineType helper class.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone to create the instance in. For example: "us-west3-b"
- instance_name: name of the new virtual machine (VM) instance.
- core_count: number of CPU cores you want to use.
- memory: the amount of memory for the VM instance, in megabytes.
-
- Returns:
- List of Instance objects.
- """
- # The core_count and memory values are not validated anywhere and can be rejected by the API.
- instances = [
- create_instance(
- project_id,
- zone,
- f"{instance_name}_n1_extra_mem",
- f"zones/{zone}/machineTypes/custom-{core_count}-{memory}-ext",
- ),
- create_instance(
- project_id,
- zone,
- f"{instance_name}_n2_extra_mem",
- f"zones/{zone}/machineTypes/n2-custom-{core_count}-{memory}-ext",
- ),
- create_instance(
- project_id,
- zone,
- f"{instance_name}_n2d_extra_mem",
- f"zones/{zone}/machineTypes/n2d-custom-{core_count}-{memory}-ext",
- ),
- ]
- return instances
-
-
-# [END compute_custom_machine_type_extra_mem_no_helper ]
-
-
-# [START compute_custom_machine_type_update_memory ]
-def add_extended_memory_to_instance(
- project_id: str, zone: str, instance_name: str, new_memory: int
-):
- """
- Modify an existing VM to use extended memory.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone to create the instance in. For example: "us-west3-b"
- instance_name: name of the new virtual machine (VM) instance.
- new_memory: the amount of memory for the VM instance, in megabytes.
-
- Returns:
- Instance object.
- """
- instance_client = compute_v1.InstancesClient()
- operation_client = compute_v1.ZoneOperationsClient()
- instance = instance_client.get(
- project=project_id, zone=zone, instance=instance_name
- )
-
- # Make sure that the machine is turned off
- if instance.status not in (
- instance.Status.TERMINATED.name,
- instance.Status.STOPPED.name,
- ):
- op = instance_client.stop_unary(
- project=project_id, zone=zone, instance=instance_name
- )
- operation_client.wait(project=project_id, zone=zone, operation=op.name)
- while instance.status not in (
- instance.Status.TERMINATED.name,
- instance.Status.STOPPED.name,
- ):
- # Waiting for the instance to be turned off.
- instance = instance_client.get(
- project=project_id, zone=zone, instance=instance_name
- )
- time.sleep(2)
-
- # Modify the machine definition, remember that extended memory is available only for N1, N2 and N2D CPUs
- start, end = instance.machine_type.rsplit("-", maxsplit=1)
- instance.machine_type = start + f"-{new_memory}-ext"
- # Using CustomMachineType helper
- # cmt = CustomMachineType.from_str(instance.machine_type)
- # cmt.memory_mb = new_memory
- # cmt.extra_memory_used = True
- # instance.machine_type = str(cmt)
- op = instance_client.update_unary(
- project=project_id,
- zone=zone,
- instance=instance_name,
- instance_resource=instance,
- )
- operation_client.wait(project=project_id, zone=zone, operation=op.name)
+ newest_debian = get_image_from_family(project="debian-cloud", family="debian-10")
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
- return instance_client.get(project=project_id, zone=zone, instance=instance_name)
+ return create_instance(project_id, zone, instance_name, disks, str(custom_type))
-# [END compute_custom_machine_type_update_memory ]
+# [END compute_custom_machine_type_create_with_helper]
diff --git a/samples/snippets/instances/custom_machine_types/create_without_helper.py b/samples/snippets/instances/custom_machine_types/create_without_helper.py
new file mode 100644
index 000000000..5f04cc79f
--- /dev/null
+++ b/samples/snippets/instances/custom_machine_types/create_without_helper.py
@@ -0,0 +1,245 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_custom_machine_type_create_without_helper]
+import re
+import sys
+from typing import List
+
+from google.cloud import compute_v1
+
+
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(project=project, family=family)
+ return newest_image
+
+
+def disk_from_image(
+ disk_type: str, disk_size_gb: int, boot: bool, source_image: str
+) -> compute_v1.AttachedDisk:
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
+ of the publicly available images or an image from one of your projects.
+ This value uses the following format: "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified image.
+ """
+ boot_disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = source_image
+ initialize_params.disk_size_gb = disk_size_gb
+ initialize_params.disk_type = disk_type
+ boot_disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ boot_disk.auto_delete = True
+ boot_disk.boot = boot
+ return boot_disk
+
+
+def create_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
+ """
+ Send an instance creation request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ machine_type: machine type of the VM being created. This value uses the
+ following format: "zones/{zone}/machineTypes/{type_name}".
+ For example: "zones/europe-west3-c/machineTypes/f1-micro"
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ # Use the network interface provided in the network_link argument.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
+
+ # Collect information into the Instance object.
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
+ instance.network_interfaces = [network_interface]
+
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Shielded Instance settings
+ # Values presented here are the defaults.
+ # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
+ # instance.shielded_instance_config.enable_secure_boot = False
+ # instance.shielded_instance_config.enable_vtpm = True
+ # instance.shielded_instance_config.enable_integrity_monitoring = True
+
+ # Prepare the request to insert an instance.
+ request = compute_v1.InsertInstanceRequest()
+ request.zone = zone
+ request.project = project_id
+ request.instance_resource = instance
+
+ # Wait for the create operation to complete.
+ print(f"Creating the {instance_name} instance in {zone}...")
+
+ operation = instance_client.insert_unary(request=request)
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if operation.error:
+ print("Error during creation:", operation.error, file=sys.stderr)
+ if operation.warnings:
+ print("Warning during creation:", operation.warnings, file=sys.stderr)
+ print(f"Instance {instance_name} created.")
+ return instance
+
+
+def create_custom_instances_no_helper(
+ project_id: str, zone: str, instance_name: str, core_count: int, memory: int
+) -> List[compute_v1.Instance]:
+ """
+ Create new VM instances without using a CustomMachineType helper function.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ core_count: number of CPU cores you want to use.
+ memory: the amount of memory for the VM instance, in megabytes.
+
+ Returns:
+ List of Instance objects.
+ """
+ newest_debian = get_image_from_family(project="debian-cloud", family="debian-10")
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+ # The core_count and memory values are not validated anywhere and can be rejected by the API.
+ instances = [
+ create_instance(
+ project_id,
+ zone,
+ f"{instance_name}_n1",
+ disks,
+ f"zones/{zone}/machineTypes/custom-{core_count}-{memory}",
+ ),
+ create_instance(
+ project_id,
+ zone,
+ f"{instance_name}_n2",
+ disks,
+ f"zones/{zone}/machineTypes/n2-custom-{core_count}-{memory}",
+ ),
+ create_instance(
+ project_id,
+ zone,
+ f"{instance_name}_n2d",
+ disks,
+ f"zones/{zone}/machineTypes/n2d-custom-{core_count}-{memory}",
+ ),
+ create_instance(
+ project_id,
+ zone,
+ f"{instance_name}_e2",
+ disks,
+ f"zones/{zone}/machineTypes/e2-custom-{core_count}-{memory}",
+ ),
+ create_instance(
+ project_id,
+ zone,
+ f"{instance_name}_e2_micro",
+ disks,
+ f"zones/{zone}/machineTypes/e2-custom-micro-{memory}",
+ ),
+ create_instance(
+ project_id,
+ zone,
+ f"{instance_name}_e2_small",
+ disks,
+ f"zones/{zone}/machineTypes/e2-custom-small-{memory}",
+ ),
+ create_instance(
+ project_id,
+ zone,
+ f"{instance_name}_e2_medium",
+ disks,
+ f"zones/{zone}/machineTypes/e2-custom-medium-{memory}",
+ ),
+ ]
+ return instances
+
+
+# [END compute_custom_machine_type_create_without_helper]
diff --git a/samples/snippets/instances/custom_machine_types/extra_mem_no_helper.py b/samples/snippets/instances/custom_machine_types/extra_mem_no_helper.py
new file mode 100644
index 000000000..a2667437e
--- /dev/null
+++ b/samples/snippets/instances/custom_machine_types/extra_mem_no_helper.py
@@ -0,0 +1,217 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_custom_machine_type_extra_mem_no_helper]
+import re
+import sys
+from typing import List
+
+from google.cloud import compute_v1
+
+
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(project=project, family=family)
+ return newest_image
+
+
+def disk_from_image(
+ disk_type: str, disk_size_gb: int, boot: bool, source_image: str
+) -> compute_v1.AttachedDisk:
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
+ of the publicly available images or an image from one of your projects.
+ This value uses the following format: "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified image.
+ """
+ boot_disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = source_image
+ initialize_params.disk_size_gb = disk_size_gb
+ initialize_params.disk_type = disk_type
+ boot_disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ boot_disk.auto_delete = True
+ boot_disk.boot = boot
+ return boot_disk
+
+
+def create_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
+ """
+ Send an instance creation request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ machine_type: machine type of the VM being created. This value uses the
+ following format: "zones/{zone}/machineTypes/{type_name}".
+ For example: "zones/europe-west3-c/machineTypes/f1-micro"
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ # Use the network interface provided in the network_link argument.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
+
+ # Collect information into the Instance object.
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
+ instance.network_interfaces = [network_interface]
+
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Shielded Instance settings
+ # Values presented here are the defaults.
+ # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
+ # instance.shielded_instance_config.enable_secure_boot = False
+ # instance.shielded_instance_config.enable_vtpm = True
+ # instance.shielded_instance_config.enable_integrity_monitoring = True
+
+ # Prepare the request to insert an instance.
+ request = compute_v1.InsertInstanceRequest()
+ request.zone = zone
+ request.project = project_id
+ request.instance_resource = instance
+
+ # Wait for the create operation to complete.
+ print(f"Creating the {instance_name} instance in {zone}...")
+
+ operation = instance_client.insert_unary(request=request)
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if operation.error:
+ print("Error during creation:", operation.error, file=sys.stderr)
+ if operation.warnings:
+ print("Warning during creation:", operation.warnings, file=sys.stderr)
+ print(f"Instance {instance_name} created.")
+ return instance
+
+
+def create_custom_instances_extra_mem_no_helper(
+ project_id: str, zone: str, instance_name: str, core_count: int, memory: int
+) -> List[compute_v1.Instance]:
+ """
+ Create new VM instances with extra memory without using a CustomMachineType helper class.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ core_count: number of CPU cores you want to use.
+ memory: the amount of memory for the VM instance, in megabytes.
+
+ Returns:
+ List of Instance objects.
+ """
+ newest_debian = get_image_from_family(project="debian-cloud", family="debian-10")
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+ # The core_count and memory values are not validated anywhere and can be rejected by the API.
+ instances = [
+ create_instance(
+ project_id,
+ zone,
+ f"{instance_name}_n1_extra_mem",
+ disks,
+ f"zones/{zone}/machineTypes/custom-{core_count}-{memory}-ext",
+ ),
+ create_instance(
+ project_id,
+ zone,
+ f"{instance_name}_n2_extra_mem",
+ disks,
+ f"zones/{zone}/machineTypes/n2-custom-{core_count}-{memory}-ext",
+ ),
+ create_instance(
+ project_id,
+ zone,
+ f"{instance_name}_n2d_extra_mem",
+ disks,
+ f"zones/{zone}/machineTypes/n2d-custom-{core_count}-{memory}-ext",
+ ),
+ ]
+ return instances
+
+
+# [END compute_custom_machine_type_extra_mem_no_helper]
diff --git a/samples/snippets/instances/custom_machine_types/helper_class.py b/samples/snippets/instances/custom_machine_types/helper_class.py
new file mode 100644
index 000000000..acd867c0f
--- /dev/null
+++ b/samples/snippets/instances/custom_machine_types/helper_class.py
@@ -0,0 +1,209 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_custom_machine_type_helper_class]
+from collections import namedtuple
+from enum import Enum
+from enum import unique
+
+
+def gb_to_mb(value: int) -> int:
+ return value << 10
+
+
+class CustomMachineType:
+ """
+ Allows to create custom machine types to be used with the VM instances.
+ """
+
+ @unique
+ class CPUSeries(Enum):
+ N1 = "custom"
+ N2 = "n2-custom"
+ N2D = "n2d-custom"
+ E2 = "e2-custom"
+ E2_MICRO = "e2-custom-micro"
+ E2_SMALL = "e2-custom-small"
+ E2_MEDIUM = "e2-custom-medium"
+
+ TypeLimits = namedtuple(
+ "TypeLimits",
+ [
+ "allowed_cores",
+ "min_mem_per_core",
+ "max_mem_per_core",
+ "allow_extra_memory",
+ "extra_memory_limit",
+ ],
+ )
+
+ LIMITS = {
+ CPUSeries.E2: TypeLimits(frozenset(range(2, 33, 2)), 512, 8192, False, 0),
+ CPUSeries.E2_MICRO: TypeLimits(frozenset(), 1024, 2048, False, 0),
+ CPUSeries.E2_SMALL: TypeLimits(frozenset(), 2048, 4096, False, 0),
+ CPUSeries.E2_MEDIUM: TypeLimits(frozenset(), 4096, 8192, False, 0),
+ CPUSeries.N2: TypeLimits(
+ frozenset(range(2, 33, 2)).union(set(range(36, 129, 4))),
+ 512,
+ 8192,
+ True,
+ gb_to_mb(624),
+ ),
+ CPUSeries.N2D: TypeLimits(
+ frozenset({2, 4, 8, 16, 32, 48, 64, 80, 96}), 512, 8192, True, gb_to_mb(768)
+ ),
+ CPUSeries.N1: TypeLimits(
+ frozenset({1}.union(range(2, 97, 2))), 922, 6656, True, gb_to_mb(624)
+ ),
+ }
+
+ def __init__(
+ self, zone: str, cpu_series: CPUSeries, memory_mb: int, core_count: int = 0
+ ):
+ self.zone = zone
+ self.cpu_series = cpu_series
+ self.limits = self.LIMITS[self.cpu_series]
+ self.core_count = 2 if self.is_shared() else core_count
+ self.memory_mb = memory_mb
+
+ self._check()
+ self.extra_memory_used = self._check_extra_memory()
+
+ def is_shared(self):
+ return self.cpu_series in (
+ CustomMachineType.CPUSeries.E2_SMALL,
+ CustomMachineType.CPUSeries.E2_MICRO,
+ CustomMachineType.CPUSeries.E2_MEDIUM,
+ )
+
+ def _check_extra_memory(self) -> bool:
+ # Assuming this runs after _check() and the total memory requested is correct
+ return self.memory_mb > self.core_count * self.limits.max_mem_per_core
+
+ def _check(self):
+ """
+ Check whether the requested parameters are allowed. Find more information about limitations of custom machine
+ types at: https://cloud.google.com/compute/docs/general-purpose-machines#custom_machine_types
+ """
+ # Check the number of cores
+ if (
+ self.limits.allowed_cores
+ and self.core_count not in self.limits.allowed_cores
+ ):
+ raise RuntimeError(
+ f"Invalid number of cores requested. Allowed number of cores for {self.cpu_series.name} is: {sorted(self.limits.allowed_cores)}"
+ )
+
+ # Memory must be a multiple of 256 MB
+ if self.memory_mb % 256 != 0:
+ raise RuntimeError("Requested memory must be a multiple of 256 MB.")
+
+ # Check if the requested memory isn't too little
+ if self.memory_mb < self.core_count * self.limits.min_mem_per_core:
+ raise RuntimeError(
+ f"Requested memory is too low. Minimal memory for {self.cpu_series.name} is {self.limits.min_mem_per_core} MB per core."
+ )
+
+ # Check if the requested memory isn't too much
+ if self.memory_mb > self.core_count * self.limits.max_mem_per_core:
+ if self.limits.allow_extra_memory:
+ if self.memory_mb > self.limits.extra_memory_limit:
+ raise RuntimeError(
+ f"Requested memory is too large.. Maximum memory allowed for {self.cpu_series.name} is {self.limits.extra_memory_limit} MB."
+ )
+ else:
+ raise RuntimeError(
+ f"Requested memory is too large.. Maximum memory allowed for {self.cpu_series.name} is {self.limits.max_mem_per_core} MB per core."
+ )
+
+ def __str__(self) -> str:
+ """
+ Return the custom machine type in form of a string acceptable by Compute Engine API.
+ """
+ if self.cpu_series in {
+ self.CPUSeries.E2_SMALL,
+ self.CPUSeries.E2_MICRO,
+ self.CPUSeries.E2_MEDIUM,
+ }:
+ return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.memory_mb}"
+
+ if self.extra_memory_used:
+ return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.core_count}-{self.memory_mb}-ext"
+
+ return f"zones/{self.zone}/machineTypes/{self.cpu_series.value}-{self.core_count}-{self.memory_mb}"
+
+ def short_type_str(self) -> str:
+ """
+ Return machine type in a format without the zone. For example, n2-custom-0-10240.
+ This format is used to create instance templates.
+ """
+ return str(self).rsplit("/", maxsplit=1)[1]
+
+ @classmethod
+ def from_str(cls, machine_type: str):
+ """
+ Construct a new object from a string. The string needs to be a valid custom machine type like:
+ - https://www.googleapis.com/compute/v1/projects/diregapic-mestiv/zones/us-central1-b/machineTypes/e2-custom-4-8192
+ - zones/us-central1-b/machineTypes/e2-custom-4-8192
+ - e2-custom-4-8192 (in this case, the zone parameter will not be set)
+ """
+ zone = None
+ if machine_type.startswith("http"):
+ machine_type = machine_type[machine_type.find("zones/") :]
+
+ if machine_type.startswith("zones/"):
+ _, zone, _, machine_type = machine_type.split("/")
+
+ extra_mem = machine_type.endswith("-ext")
+
+ if machine_type.startswith("custom"):
+ cpu = cls.CPUSeries.N1
+ _, cores, memory = machine_type.rsplit("-", maxsplit=2)
+ else:
+ if extra_mem:
+ cpu_series, _, cores, memory, _ = machine_type.split("-")
+ else:
+ cpu_series, _, cores, memory = machine_type.split("-")
+ if cpu_series == "n2":
+ cpu = cls.CPUSeries.N2
+ elif cpu_series == "n2d":
+ cpu = cls.CPUSeries.N2D
+ elif cpu_series == "e2":
+ cpu = cls.CPUSeries.E2
+ if cores == "micro":
+ cpu = cls.CPUSeries.E2_MICRO
+ cores = 2
+ elif cores == "small":
+ cpu = cls.CPUSeries.E2_SMALL
+ cores = 2
+ elif cores == "medium":
+ cpu = cls.CPUSeries.E2_MEDIUM
+ cores = 2
+ else:
+ raise RuntimeError("Unknown CPU series.")
+
+ cores = int(cores)
+ memory = int(memory)
+
+ return cls(zone, cpu, memory, cores)
+
+
+# [END compute_custom_machine_type_helper_class]
diff --git a/samples/snippets/instances/custom_machine_types/update_memory.py b/samples/snippets/instances/custom_machine_types/update_memory.py
new file mode 100644
index 000000000..5a168e784
--- /dev/null
+++ b/samples/snippets/instances/custom_machine_types/update_memory.py
@@ -0,0 +1,87 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_custom_machine_type_update_memory]
+import time
+
+from google.cloud import compute_v1
+
+
+def add_extended_memory_to_instance(
+ project_id: str, zone: str, instance_name: str, new_memory: int
+):
+ """
+ Modify an existing VM to use extended memory.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ new_memory: the amount of memory for the VM instance, in megabytes.
+
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+ instance = instance_client.get(
+ project=project_id, zone=zone, instance=instance_name
+ )
+
+ # Make sure that the machine is turned off
+ if instance.status not in (
+ instance.Status.TERMINATED.name,
+ instance.Status.STOPPED.name,
+ ):
+ op = instance_client.stop_unary(
+ project=project_id, zone=zone, instance=instance_name
+ )
+ operation_client.wait(project=project_id, zone=zone, operation=op.name)
+ while instance.status not in (
+ instance.Status.TERMINATED.name,
+ instance.Status.STOPPED.name,
+ ):
+ # Waiting for the instance to be turned off.
+ instance = instance_client.get(
+ project=project_id, zone=zone, instance=instance_name
+ )
+ time.sleep(2)
+
+ # Modify the machine definition, remember that extended memory is available only for N1, N2 and N2D CPUs
+ start, end = instance.machine_type.rsplit("-", maxsplit=1)
+ instance.machine_type = start + f"-{new_memory}-ext"
+ # Using CustomMachineType helper
+ # cmt = CustomMachineType.from_str(instance.machine_type)
+ # cmt.memory_mb = new_memory
+ # cmt.extra_memory_used = True
+ # instance.machine_type = str(cmt)
+ op = instance_client.update_unary(
+ project=project_id,
+ zone=zone,
+ instance=instance_name,
+ instance_resource=instance,
+ )
+ operation_client.wait(project=project_id, zone=zone, operation=op.name)
+
+ return instance_client.get(project=project_id, zone=zone, instance=instance_name)
+
+
+# [END compute_custom_machine_type_update_memory]
diff --git a/samples/snippets/instances/delete.py b/samples/snippets/instances/delete.py
new file mode 100644
index 000000000..be8c714fe
--- /dev/null
+++ b/samples/snippets/instances/delete.py
@@ -0,0 +1,56 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_instances_delete]
+import sys
+
+from google.cloud import compute_v1
+
+
+def delete_instance(project_id: str, zone: str, machine_name: str) -> None:
+ """
+ Send an instance deletion request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: “us-west3-b”
+ machine_name: name of the machine you want to delete.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ print(f"Deleting {machine_name} from {zone}...")
+ operation = instance_client.delete_unary(
+ project=project_id, zone=zone, instance=machine_name
+ )
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if operation.error:
+ print("Error during deletion:", operation.error, file=sys.stderr)
+ if operation.warnings:
+ print("Warning during deletion:", operation.warnings, file=sys.stderr)
+ print(f"Instance {machine_name} deleted.")
+ return
+
+
+# [END compute_instances_delete]
diff --git a/samples/snippets/instances/delete_protection/__init__.py b/samples/snippets/instances/delete_protection/__init__.py
new file mode 100644
index 000000000..a3ded82a3
--- /dev/null
+++ b/samples/snippets/instances/delete_protection/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
diff --git a/samples/snippets/instances/delete_protection/create.py b/samples/snippets/instances/delete_protection/create.py
new file mode 100644
index 000000000..b4b21b7fc
--- /dev/null
+++ b/samples/snippets/instances/delete_protection/create.py
@@ -0,0 +1,195 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_delete_protection_create]
+import re
+import sys
+from typing import List
+
+from google.cloud import compute_v1
+
+
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(project=project, family=family)
+ return newest_image
+
+
+def disk_from_image(
+ disk_type: str, disk_size_gb: int, boot: bool, source_image: str
+) -> compute_v1.AttachedDisk:
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
+ of the publicly available images or an image from one of your projects.
+ This value uses the following format: "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified image.
+ """
+ boot_disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = source_image
+ initialize_params.disk_size_gb = disk_size_gb
+ initialize_params.disk_type = disk_type
+ boot_disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ boot_disk.auto_delete = True
+ boot_disk.boot = boot
+ return boot_disk
+
+
+def create_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
+ """
+ Send an instance creation request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ machine_type: machine type of the VM being created. This value uses the
+ following format: "zones/{zone}/machineTypes/{type_name}".
+ For example: "zones/europe-west3-c/machineTypes/f1-micro"
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ # Use the network interface provided in the network_link argument.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
+
+ # Collect information into the Instance object.
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
+ instance.network_interfaces = [network_interface]
+
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Shielded Instance settings
+ # Values presented here are the defaults.
+ # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
+ # instance.shielded_instance_config.enable_secure_boot = False
+ # instance.shielded_instance_config.enable_vtpm = True
+ # instance.shielded_instance_config.enable_integrity_monitoring = True
+
+ # Prepare the request to insert an instance.
+ request = compute_v1.InsertInstanceRequest()
+ request.zone = zone
+ request.project = project_id
+ request.instance_resource = instance
+
+ # Wait for the create operation to complete.
+ print(f"Creating the {instance_name} instance in {zone}...")
+
+ operation = instance_client.insert_unary(request=request)
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if operation.error:
+ print("Error during creation:", operation.error, file=sys.stderr)
+ if operation.warnings:
+ print("Warning during creation:", operation.warnings, file=sys.stderr)
+ print(f"Instance {instance_name} created.")
+ return instance
+
+
+def create_protected_instance(
+ project_id: str, zone: str, instance_name: str
+) -> compute_v1.Instance:
+ """
+ Create a new VM instance with Debian 10 operating system and delete protection
+ turned on.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+
+ Returns:
+ Instance object.
+ """
+ newest_debian = get_image_from_family(project="debian-cloud", family="debian-11")
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+ instance = create_instance(
+ project_id, zone, instance_name, disks, delete_protection=True
+ )
+ return instance
+
+
+# [END compute_delete_protection_create]
diff --git a/samples/snippets/instances/delete_protection/get.py b/samples/snippets/instances/delete_protection/get.py
new file mode 100644
index 000000000..d6ecfa398
--- /dev/null
+++ b/samples/snippets/instances/delete_protection/get.py
@@ -0,0 +1,43 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_delete_protection_get]
+from google.cloud import compute_v1
+
+
+def get_delete_protection(project_id: str, zone: str, instance_name: str) -> bool:
+ """
+ Returns the state of delete protection flag of given instance.
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: “us-west3-b”
+ instance_name: name of the virtual machine to check.
+ Returns:
+ The state of the delete protection setting.
+ """
+ instance_client = compute_v1.InstancesClient()
+ instance = instance_client.get(
+ project=project_id, zone=zone, instance=instance_name
+ )
+ return instance.deletion_protection
+
+
+# [END compute_delete_protection_get]
diff --git a/samples/snippets/instances/delete_protection/set.py b/samples/snippets/instances/delete_protection/set.py
new file mode 100644
index 000000000..e25269317
--- /dev/null
+++ b/samples/snippets/instances/delete_protection/set.py
@@ -0,0 +1,52 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_delete_protection_set]
+from google.cloud import compute_v1
+
+
+def set_delete_protection(
+ project_id: str, zone: str, instance_name: str, delete_protection: bool
+):
+ """
+ Updates the delete protection setting of given instance.
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: “us-west3-b”
+ instance_name: name of the virtual machine to update.
+ delete_protection: boolean value indicating if the virtual machine should be
+ protected against deletion or not.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ request = compute_v1.SetDeletionProtectionInstanceRequest()
+ request.project = project_id
+ request.zone = zone
+ request.resource = instance_name
+ request.deletion_protection = delete_protection
+
+ operation = instance_client.set_deletion_protection_unary(request)
+ operation_client.wait(project=project_id, zone=zone, operation=operation.name)
+ return
+
+
+# [END compute_delete_protection_set]
diff --git a/samples/snippets/instances/from_instance_template/__init__.py b/samples/snippets/instances/from_instance_template/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/snippets/instances/from_instance_template/create_from_template.py b/samples/snippets/instances/from_instance_template/create_from_template.py
new file mode 100644
index 000000000..6310cfd11
--- /dev/null
+++ b/samples/snippets/instances/from_instance_template/create_from_template.py
@@ -0,0 +1,61 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_instances_create_from_template]
+from google.cloud import compute_v1
+
+
+def create_instance_from_template(
+ project_id: str, zone: str, instance_name: str, instance_template_url: str
+) -> compute_v1.Instance:
+ """
+ Creates a Compute Engine VM instance from an instance template.
+
+ Args:
+ project_id: ID or number of the project you want to use.
+ zone: Name of the zone you want to check, for example: us-west3-b
+ instance_name: Name of the new instance.
+ instance_template_url: URL of the instance template used for creating the new instance.
+ It can be a full or partial URL.
+ Examples:
+ - https://www.googleapis.com/compute/v1/projects/project/global/instanceTemplates/example-instance-template
+ - projects/project/global/instanceTemplates/example-instance-template
+ - global/instanceTemplates/example-instance-template
+
+ Returns:
+ Instance object.
+ """
+ operation_client = compute_v1.ZoneOperationsClient()
+ instance_client = compute_v1.InstancesClient()
+
+ instance_insert_request = compute_v1.InsertInstanceRequest()
+ instance_insert_request.project = project_id
+ instance_insert_request.zone = zone
+ instance_insert_request.source_instance_template = instance_template_url
+ instance_insert_request.instance_resource.name = instance_name
+
+ op = instance_client.insert_unary(instance_insert_request)
+ operation_client.wait(project=project_id, zone=zone, operation=op.name)
+
+ return instance_client.get(project=project_id, zone=zone, instance=instance_name)
+
+
+# [END compute_instances_create_from_template]
diff --git a/samples/snippets/sample_instance_from_template.py b/samples/snippets/instances/from_instance_template/create_from_template_with_overrides.py
similarity index 67%
rename from samples/snippets/sample_instance_from_template.py
rename to samples/snippets/instances/from_instance_template/create_from_template_with_overrides.py
index 30ef65dba..6f76d3290 100644
--- a/samples/snippets/sample_instance_from_template.py
+++ b/samples/snippets/instances/from_instance_template/create_from_template_with_overrides.py
@@ -1,4 +1,4 @@
-# Copyright 2021 Google LLC
+# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -11,53 +11,18 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+# flake8: noqa
-# [START compute_instances_create_from_template]
-# [START compute_instances_create_from_template_with_overrides]
-from google.cloud import compute_v1
-
-# [END compute_instances_create_from_template_with_overrides]
-
-
-def create_instance_from_template(
- project_id: str, zone: str, instance_name: str, instance_template_url: str
-) -> compute_v1.Instance:
- """
- Creates a Compute Engine VM instance from an instance template.
-
- Args:
- project_id: ID or number of the project you want to use.
- zone: Name of the zone you want to check, for example: us-west3-b
- instance_name: Name of the new instance.
- instance_template_url: URL of the instance template used for creating the new instance.
- It can be a full or partial URL.
- Examples:
- - https://www.googleapis.com/compute/v1/projects/project/global/instanceTemplates/example-instance-template
- - projects/project/global/instanceTemplates/example-instance-template
- - global/instanceTemplates/example-instance-template
-
- Returns:
- Instance object.
- """
- operation_client = compute_v1.ZoneOperationsClient()
- instance_client = compute_v1.InstancesClient()
- instance_insert_request = compute_v1.InsertInstanceRequest()
- instance_insert_request.project = project_id
- instance_insert_request.zone = zone
- instance_insert_request.source_instance_template = instance_template_url
- instance_insert_request.instance_resource.name = instance_name
-
- op = instance_client.insert_unary(instance_insert_request)
- operation_client.wait(project=project_id, zone=zone, operation=op.name)
-
- return instance_client.get(project=project_id, zone=zone, instance=instance_name)
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
-# [END compute_instances_create_from_template]
+# [START compute_instances_create_from_template_with_overrides]
+from google.cloud import compute_v1
-# [START compute_instances_create_from_template_with_overrides]
def create_instance_from_template_with_overrides(
project_id: str,
zone: str,
@@ -80,7 +45,7 @@ def create_instance_from_template_with_overrides(
- "zones/europe-west3-c/machineTypes/f1-micro"
- You can find the list of available machine types using:
https://cloud.google.com/sdk/gcloud/reference/compute/machine-types/list
- newDiskSourceImage: Path the the disk image you want to use for your new
+ new_disk_source_image: Path the the disk image you want to use for your new
disk. This can be one of the public images
(like "projects/debian-cloud/global/images/family/debian-10")
or a private image you have access to.
diff --git a/samples/snippets/instances/list.py b/samples/snippets/instances/list.py
new file mode 100644
index 000000000..45830c72e
--- /dev/null
+++ b/samples/snippets/instances/list.py
@@ -0,0 +1,48 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_instances_list]
+from typing import Iterable
+
+from google.cloud import compute_v1
+
+
+def list_instances(project_id: str, zone: str) -> Iterable[compute_v1.Instance]:
+ """
+ List all instances in the given zone in the specified project.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: “us-west3-b”
+ Returns:
+ An iterable collection of Instance objects.
+ """
+ instance_client = compute_v1.InstancesClient()
+ instance_list = instance_client.list(project=project_id, zone=zone)
+
+ print(f"Instances found in zone {zone}:")
+ for instance in instance_list:
+ print(f" - {instance.name} ({instance.machine_type})")
+
+ return instance_list
+
+
+# [END compute_instances_list]
diff --git a/samples/snippets/instances/list_all.py b/samples/snippets/instances/list_all.py
new file mode 100644
index 000000000..9549de0f4
--- /dev/null
+++ b/samples/snippets/instances/list_all.py
@@ -0,0 +1,62 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_instances_list_all]
+from typing import Dict, Iterable
+
+from google.cloud import compute_v1
+
+
+def list_all_instances(
+ project_id: str,
+) -> Dict[str, Iterable[compute_v1.Instance]]:
+ """
+ Return a dictionary of all instances present in a project, grouped by their zone.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ Returns:
+ A dictionary with zone names as keys (in form of "zones/{zone_name}") and
+ iterable collections of Instance objects as values.
+ """
+ instance_client = compute_v1.InstancesClient()
+ # Use the `max_results` parameter to limit the number of results that the API returns per response page.
+ request = compute_v1.AggregatedListInstancesRequest()
+ request.project = project_id
+ request.max_results = 50
+
+ agg_list = instance_client.aggregated_list(request=request)
+
+ all_instances = {}
+ print("Instances found:")
+ # Despite using the `max_results` parameter, you don't need to handle the pagination
+ # yourself. The returned `AggregatedListPager` object handles pagination
+ # automatically, returning separated pages as you iterate over the results.
+ for zone, response in agg_list:
+ if response.instances:
+ all_instances[zone] = response.instances
+ print(f" {zone}:")
+ for instance in response.instances:
+ print(f" - {instance.name} ({instance.machine_type})")
+ return all_instances
+
+
+# [END compute_instances_list_all]
diff --git a/samples/snippets/instances/preemptible/__init__.py b/samples/snippets/instances/preemptible/__init__.py
new file mode 100644
index 000000000..a3ded82a3
--- /dev/null
+++ b/samples/snippets/instances/preemptible/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
diff --git a/samples/snippets/instances/preemptible/create_preemptible.py b/samples/snippets/instances/preemptible/create_preemptible.py
new file mode 100644
index 000000000..2f4569bc8
--- /dev/null
+++ b/samples/snippets/instances/preemptible/create_preemptible.py
@@ -0,0 +1,192 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_preemptible_create]
+import re
+import sys
+from typing import List
+
+from google.cloud import compute_v1
+
+
+def get_image_from_family(project: str, family: str) -> compute_v1.Image:
+ image_client = compute_v1.ImagesClient()
+ # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
+ newest_image = image_client.get_from_family(project=project, family=family)
+ return newest_image
+
+
+def disk_from_image(
+ disk_type: str, disk_size_gb: int, boot: bool, source_image: str
+) -> compute_v1.AttachedDisk:
+ """
+ Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
+ source for the new disk.
+
+ Args:
+ disk_type: the type of disk you want to create. This value uses the following format:
+ "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
+ For example: "zones/us-west3-b/diskTypes/pd-ssd"
+ disk_size_gb: size of the new disk in gigabytes
+ boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
+ source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
+ of the publicly available images or an image from one of your projects.
+ This value uses the following format: "projects/{project_name}/global/images/{image_name}"
+
+ Returns:
+ AttachedDisk object configured to be created using the specified image.
+ """
+ boot_disk = compute_v1.AttachedDisk()
+ initialize_params = compute_v1.AttachedDiskInitializeParams()
+ initialize_params.source_image = source_image
+ initialize_params.disk_size_gb = disk_size_gb
+ initialize_params.disk_type = disk_type
+ boot_disk.initialize_params = initialize_params
+ # Remember to set auto_delete to True if you want the disk to be deleted when you delete
+ # your VM instance.
+ boot_disk.auto_delete = True
+ boot_disk.boot = boot
+ return boot_disk
+
+
+def create_instance(
+ project_id: str,
+ zone: str,
+ instance_name: str,
+ disks: List[compute_v1.AttachedDisk],
+ machine_type: str = "n1-standard-1",
+ network_link: str = "global/networks/default",
+ subnetwork_link: str = None,
+ preemptible: bool = False,
+ custom_hostname: str = None,
+ delete_protection: bool = False,
+) -> compute_v1.Instance:
+ """
+ Send an instance creation request to the Compute Engine API and wait for it to complete.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+ machine_type: machine type of the VM being created. This value uses the
+ following format: "zones/{zone}/machineTypes/{type_name}".
+ For example: "zones/europe-west3-c/machineTypes/f1-micro"
+ disks: a list of compute_v1.AttachedDisk objects describing the disks
+ you want to attach to your new instance.
+ network_link: name of the network you want the new instance to use.
+ For example: "global/networks/default" represents the network
+ named "default", which is created automatically for each project.
+ subnetwork_link: name of the subnetwork you want the new instance to use.
+ This value uses the following format:
+ "regions/{region}/subnetworks/{subnetwork_name}"
+ preemptible: boolean value indicating if the new instance should be preemptible
+ or not.
+ custom_hostname: Custom hostname of the new VM instance.
+ Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
+ delete_protection: boolean value indicating if the new virtual machine should be
+ protected against deletion or not.
+ Returns:
+ Instance object.
+ """
+ instance_client = compute_v1.InstancesClient()
+ operation_client = compute_v1.ZoneOperationsClient()
+
+ # Use the network interface provided in the network_link argument.
+ network_interface = compute_v1.NetworkInterface()
+ network_interface.name = network_link
+ if subnetwork_link:
+ network_interface.subnetwork = subnetwork_link
+
+ # Collect information into the Instance object.
+ instance = compute_v1.Instance()
+ instance.name = instance_name
+ instance.disks = disks
+ if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
+ instance.machine_type = machine_type
+ else:
+ instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
+
+ instance.network_interfaces = [network_interface]
+
+ if preemptible:
+ # Set the preemptible setting
+ instance.scheduling = compute_v1.Scheduling()
+ instance.scheduling.preemptible = True
+
+ if custom_hostname is not None:
+ # Set the custom hostname for the instance
+ instance.hostname = custom_hostname
+
+ if delete_protection:
+ # Set the delete protection bit
+ instance.deletion_protection = True
+
+ # Shielded Instance settings
+ # Values presented here are the defaults.
+ # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
+ # instance.shielded_instance_config.enable_secure_boot = False
+ # instance.shielded_instance_config.enable_vtpm = True
+ # instance.shielded_instance_config.enable_integrity_monitoring = True
+
+ # Prepare the request to insert an instance.
+ request = compute_v1.InsertInstanceRequest()
+ request.zone = zone
+ request.project = project_id
+ request.instance_resource = instance
+
+ # Wait for the create operation to complete.
+ print(f"Creating the {instance_name} instance in {zone}...")
+
+ operation = instance_client.insert_unary(request=request)
+ while operation.status != compute_v1.Operation.Status.DONE:
+ operation = operation_client.wait(
+ operation=operation.name, zone=zone, project=project_id
+ )
+ if operation.error:
+ print("Error during creation:", operation.error, file=sys.stderr)
+ if operation.warnings:
+ print("Warning during creation:", operation.warnings, file=sys.stderr)
+ print(f"Instance {instance_name} created.")
+ return instance
+
+
+def create_preemptible_instance(
+ project_id: str, zone: str, instance_name: str
+) -> compute_v1.Instance:
+ """
+ Create a new preemptible VM instance with Debian 10 operating system.
+
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone to create the instance in. For example: "us-west3-b"
+ instance_name: name of the new virtual machine (VM) instance.
+
+ Returns:
+ Instance object.
+ """
+ newest_debian = get_image_from_family(project="debian-cloud", family="debian-11")
+ disk_type = f"zones/{zone}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+ instance = create_instance(project_id, zone, instance_name, disks, preemptible=True)
+ return instance
+
+
+# [END compute_preemptible_create]
diff --git a/samples/snippets/instances/preemptible/is_preemptible.py b/samples/snippets/instances/preemptible/is_preemptible.py
new file mode 100644
index 000000000..8a0c966fd
--- /dev/null
+++ b/samples/snippets/instances/preemptible/is_preemptible.py
@@ -0,0 +1,43 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_preemptible_check]
+from google.cloud import compute_v1
+
+
+def is_preemptible(project_id: str, zone: str, instance_name: str) -> bool:
+ """
+ Check if a given instance is preemptible or not.
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: "us-west3-b"
+ instance_name: name of the virtual machine to check.
+ Returns:
+ The preemptible status of the instance.
+ """
+ instance_client = compute_v1.InstancesClient()
+ instance = instance_client.get(
+ project=project_id, zone=zone, instance=instance_name
+ )
+ return instance.scheduling.preemptible
+
+
+# [END compute_preemptible_check]
diff --git a/samples/snippets/instances/preemptible/preemption_history.py b/samples/snippets/instances/preemptible/preemption_history.py
new file mode 100644
index 000000000..23a1f7974
--- /dev/null
+++ b/samples/snippets/instances/preemptible/preemption_history.py
@@ -0,0 +1,87 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_preemptible_history]
+import datetime
+from typing import List, Tuple
+
+from google.cloud import compute_v1
+from google.cloud.compute_v1.services.zone_operations import pagers
+
+
+def list_zone_operations(
+ project_id: str, zone: str, filter: str = ""
+) -> pagers.ListPager:
+ """
+ List all recent operations the happened in given zone in a project. Optionally filter those
+ operations by providing a filter. More about using the filter can be found here:
+ https://cloud.google.com/compute/docs/reference/rest/v1/zoneOperations/list
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: "us-west3-b"
+ filter: filter string to be used for this listing operation.
+ Returns:
+ List of preemption operations in given zone.
+ """
+ operation_client = compute_v1.ZoneOperationsClient()
+ request = compute_v1.ListZoneOperationsRequest()
+ request.project = project_id
+ request.zone = zone
+ request.filter = filter
+
+ return operation_client.list(request)
+
+
+def preemption_history(
+ project_id: str, zone: str, instance_name: str = None
+) -> List[Tuple[str, datetime.datetime]]:
+ """
+ Get a list of preemption operations from given zone in a project. Optionally limit
+ the results to instance name.
+ Args:
+ project_id: project ID or project number of the Cloud project you want to use.
+ zone: name of the zone you want to use. For example: "us-west3-b"
+ instance_name: name of the virtual machine to look for.
+ Returns:
+ List of preemption operations in given zone.
+ """
+ if instance_name:
+ filter = (
+ f'operationType="compute.instances.preempted" '
+ f"AND targetLink:instances/{instance_name}"
+ )
+ else:
+ filter = 'operationType="compute.instances.preempted"'
+
+ history = []
+
+ for operation in list_zone_operations(project_id, zone, filter):
+ this_instance_name = operation.target_link.rsplit("/", maxsplit=1)[1]
+ if instance_name and this_instance_name == instance_name:
+ # The filter used is not 100% accurate, it's `contains` not `equals`
+ # So we need to check the name to make sure it's the one we want.
+ moment = datetime.datetime.fromisoformat(operation.insert_time)
+ history.append((instance_name, moment))
+
+ return history
+
+
+# [END compute_preemptible_history]
diff --git a/samples/snippets/instances/reset.py b/samples/snippets/instances/reset.py
new file mode 100644
index 000000000..74bb94c2f
--- /dev/null
+++ b/samples/snippets/instances/reset.py
@@ -0,0 +1,46 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_reset_instance]
+from google.cloud import compute_v1
+
+
+def reset_instance(project_id: str, zone: str, instance_name: str):
+ """
+ Resets a stopped Google Compute Engine instance (with unencrypted disks).
+ Args:
+ project_id: project ID or project number of the Cloud project your instance belongs to.
+ zone: name of the zone your instance belongs to.
+ instance_name: name of the instance your want to reset.
+ """
+ instance_client = compute_v1.InstancesClient()
+ op_client = compute_v1.ZoneOperationsClient()
+
+ op = instance_client.reset_unary(
+ project=project_id, zone=zone, instance=instance_name
+ )
+
+ while op.status != compute_v1.Operation.Status.DONE:
+ op = op_client.wait(operation=op.name, zone=zone, project=project_id)
+ return
+
+
+# [END compute_reset_instance]
diff --git a/samples/snippets/instances/start.py b/samples/snippets/instances/start.py
new file mode 100644
index 000000000..9de984bef
--- /dev/null
+++ b/samples/snippets/instances/start.py
@@ -0,0 +1,46 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_start_instance]
+from google.cloud import compute_v1
+
+
+def start_instance(project_id: str, zone: str, instance_name: str):
+ """
+ Starts a stopped Google Compute Engine instance (with unencrypted disks).
+ Args:
+ project_id: project ID or project number of the Cloud project your instance belongs to.
+ zone: name of the zone your instance belongs to.
+ instance_name: name of the instance your want to start.
+ """
+ instance_client = compute_v1.InstancesClient()
+ op_client = compute_v1.ZoneOperationsClient()
+
+ op = instance_client.start_unary(
+ project=project_id, zone=zone, instance=instance_name
+ )
+
+ while op.status != compute_v1.Operation.Status.DONE:
+ op = op_client.wait(operation=op.name, zone=zone, project=project_id)
+ return
+
+
+# [END compute_start_instance]
diff --git a/samples/snippets/instances/start_encrypted.py b/samples/snippets/instances/start_encrypted.py
new file mode 100644
index 000000000..c0d5c14e8
--- /dev/null
+++ b/samples/snippets/instances/start_encrypted.py
@@ -0,0 +1,68 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_start_enc_instance]
+from google.cloud import compute_v1
+
+
+def start_instance_with_encryption_key(
+ project_id: str, zone: str, instance_name: str, key: bytes
+):
+ """
+ Starts a stopped Google Compute Engine instance (with encrypted disks).
+ Args:
+ project_id: project ID or project number of the Cloud project your instance belongs to.
+ zone: name of the zone your instance belongs to.
+ instance_name: name of the instance your want to start.
+ key: bytes object representing a raw base64 encoded key to your machines boot disk.
+ For more information about disk encryption see:
+ https://cloud.google.com/compute/docs/disks/customer-supplied-encryption#specifications
+ """
+ instance_client = compute_v1.InstancesClient()
+ op_client = compute_v1.ZoneOperationsClient()
+
+ instance_data = instance_client.get(
+ project=project_id, zone=zone, instance=instance_name
+ )
+
+ # Prepare the information about disk encryption
+ disk_data = compute_v1.CustomerEncryptionKeyProtectedDisk()
+ disk_data.source = instance_data.disks[0].source
+ disk_data.disk_encryption_key = compute_v1.CustomerEncryptionKey()
+ # Use raw_key to send over the key to unlock the disk
+ # To use a key stored in KMS, you need to provide `kms_key_name` and `kms_key_service_account`
+ disk_data.disk_encryption_key.raw_key = key
+ enc_data = compute_v1.InstancesStartWithEncryptionKeyRequest()
+ enc_data.disks = [disk_data]
+
+ op = instance_client.start_with_encryption_key_unary(
+ project=project_id,
+ zone=zone,
+ instance=instance_name,
+ instances_start_with_encryption_key_request_resource=enc_data,
+ )
+
+ while op.status != compute_v1.Operation.Status.DONE:
+ op = op_client.wait(operation=op.name, zone=zone, project=project_id)
+ return
+
+
+# [END compute_start_enc_instance]
diff --git a/samples/snippets/instances/stop.py b/samples/snippets/instances/stop.py
new file mode 100644
index 000000000..cf155c74c
--- /dev/null
+++ b/samples/snippets/instances/stop.py
@@ -0,0 +1,46 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_stop_instance]
+from google.cloud import compute_v1
+
+
+def stop_instance(project_id: str, zone: str, instance_name: str):
+ """
+ Stops a stopped Google Compute Engine instance.
+ Args:
+ project_id: project ID or project number of the Cloud project your instance belongs to.
+ zone: name of the zone your instance belongs to.
+ instance_name: name of the instance your want to stop.
+ """
+ instance_client = compute_v1.InstancesClient()
+ op_client = compute_v1.ZoneOperationsClient()
+
+ op = instance_client.stop_unary(
+ project=project_id, zone=zone, instance=instance_name
+ )
+
+ while op.status != compute_v1.Operation.Status.DONE:
+ op = op_client.wait(operation=op.name, zone=zone, project=project_id)
+ return
+
+
+# [END compute_stop_instance]
diff --git a/samples/snippets/operations/__init__.py b/samples/snippets/operations/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/snippets/operations/operation_check.py b/samples/snippets/operations/operation_check.py
new file mode 100644
index 000000000..d136372c3
--- /dev/null
+++ b/samples/snippets/operations/operation_check.py
@@ -0,0 +1,68 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
+
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
+# [START compute_instances_operation_check]
+from google.cloud import compute_v1
+
+
+def wait_for_operation(
+ operation: compute_v1.Operation, project_id: str
+) -> compute_v1.Operation:
+ """
+ This method waits for an operation to be completed. Calling this function
+ will block until the operation is finished.
+
+ Args:
+ operation: The Operation object representing the operation you want to
+ wait on.
+ project_id: project ID or project number of the Cloud project you want to use.
+
+ Returns:
+ Finished Operation object.
+ """
+ kwargs = {"project": project_id, "operation": operation.name}
+ if operation.zone:
+ client = compute_v1.ZoneOperationsClient()
+ # Operation.zone is a full URL address of a zone, so we need to extract just the name
+ kwargs["zone"] = operation.zone.rsplit("/", maxsplit=1)[1]
+ elif operation.region:
+ client = compute_v1.RegionOperationsClient()
+ # Operation.region is a full URL address of a region, so we need to extract just the name
+ kwargs["region"] = operation.region.rsplit("/", maxsplit=1)[1]
+ else:
+ client = compute_v1.GlobalOperationsClient()
+ return client.wait(**kwargs)
+
+
+# [END compute_instances_operation_check]
diff --git a/samples/snippets/quickstart.py b/samples/snippets/quickstart.py
deleted file mode 100644
index 3303cc317..000000000
--- a/samples/snippets/quickstart.py
+++ /dev/null
@@ -1,278 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright 2021 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-"""
-A sample script showing how to create, list and delete Google Compute Engine
-instances using the google-cloud-compute library. It can be run from command
-line to create, list and delete an instance in a given project in a given zone.
-"""
-
-# [START compute_instances_create]
-# [START compute_instances_delete]
-import re
-import sys
-
-# [START compute_instances_list]
-# [START compute_instances_list_all]
-# [START compute_instances_operation_check]
-import typing
-
-import google.cloud.compute_v1 as compute_v1
-
-# [END compute_instances_operation_check]
-# [END compute_instances_list_all]
-# [END compute_instances_list]
-# [END compute_instances_delete]
-# [END compute_instances_create]
-
-
-# [START compute_instances_list]
-def list_instances(project_id: str, zone: str) -> typing.Iterable[compute_v1.Instance]:
- """
- List all instances in the given zone in the specified project.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone you want to use. For example: “us-west3-b”
- Returns:
- An iterable collection of Instance objects.
- """
- instance_client = compute_v1.InstancesClient()
- instance_list = instance_client.list(project=project_id, zone=zone)
-
- print(f"Instances found in zone {zone}:")
- for instance in instance_list:
- print(f" - {instance.name} ({instance.machine_type})")
-
- return instance_list
-
-
-# [END compute_instances_list]
-
-
-# [START compute_instances_list_all]
-def list_all_instances(
- project_id: str,
-) -> typing.Dict[str, typing.Iterable[compute_v1.Instance]]:
- """
- Return a dictionary of all instances present in a project, grouped by their zone.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- Returns:
- A dictionary with zone names as keys (in form of "zones/{zone_name}") and
- iterable collections of Instance objects as values.
- """
- instance_client = compute_v1.InstancesClient()
- # Use the `max_results` parameter to limit the number of results that the API returns per response page.
- request = compute_v1.AggregatedListInstancesRequest(
- project=project_id, max_results=5
- )
- agg_list = instance_client.aggregated_list(request=request)
- all_instances = {}
- print("Instances found:")
- # Despite using the `max_results` parameter, you don't need to handle the pagination
- # yourself. The returned `AggregatedListPager` object handles pagination
- # automatically, returning separated pages as you iterate over the results.
- for zone, response in agg_list:
- if response.instances:
- all_instances[zone] = response.instances
- print(f" {zone}:")
- for instance in response.instances:
- print(f" - {instance.name} ({instance.machine_type})")
- return all_instances
-
-
-# [END compute_instances_list_all]
-
-
-# [START compute_instances_create]
-def create_instance(
- project_id: str,
- zone: str,
- instance_name: str,
- machine_type: str = "n1-standard-1",
- source_image: str = "projects/debian-cloud/global/images/family/debian-10",
- network_name: str = "global/networks/default",
-) -> compute_v1.Instance:
- """
- Send an instance creation request to the Compute Engine API and wait for it to complete.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone you want to use. For example: “us-west3-b”
- instance_name: name of the new virtual machine.
- machine_type: machine type of the VM being created. This value uses the
- following format: "zones/{zone}/machineTypes/{type_name}".
- For example: "zones/europe-west3-c/machineTypes/f1-micro"
- source_image: path to the operating system image to mount on your boot
- disk. This can be one of the public images
- (like "projects/debian-cloud/global/images/family/debian-10")
- or a private image you have access to.
- network_name: name of the network you want the new instance to use.
- For example: "global/networks/default" represents the `default`
- network interface, which is created automatically for each project.
- Returns:
- Instance object.
- """
- instance_client = compute_v1.InstancesClient()
- operation_client = compute_v1.ZoneOperationsClient()
-
- # Describe the size and source image of the boot disk to attach to the instance.
- disk = compute_v1.AttachedDisk()
- initialize_params = compute_v1.AttachedDiskInitializeParams()
- initialize_params.source_image = (
- source_image # "projects/debian-cloud/global/images/family/debian-10"
- )
- initialize_params.disk_size_gb = 10
- disk.initialize_params = initialize_params
- disk.auto_delete = True
- disk.boot = True
- disk.type_ = "PERSISTENT"
-
- # Use the network interface provided in the network_name argument.
- network_interface = compute_v1.NetworkInterface()
- network_interface.name = network_name
-
- # Collect information into the Instance object.
- instance = compute_v1.Instance()
- instance.name = instance_name
- instance.disks = [disk]
- if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
- instance.machine_type = machine_type
- else:
- instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
- instance.network_interfaces = [network_interface]
-
- # Prepare the request to insert an instance.
- request = compute_v1.InsertInstanceRequest()
- request.zone = zone
- request.project = project_id
- request.instance_resource = instance
-
- # Wait for the create operation to complete.
- print(f"Creating the {instance_name} instance in {zone}...")
- operation = instance_client.insert_unary(request=request)
- while operation.status != compute_v1.Operation.Status.DONE:
- operation = operation_client.wait(
- operation=operation.name, zone=zone, project=project_id
- )
- if operation.error:
- print("Error during creation:", operation.error, file=sys.stderr)
- if operation.warnings:
- print("Warning during creation:", operation.warnings, file=sys.stderr)
- print(f"Instance {instance_name} created.")
- return instance
-
-
-# [END compute_instances_create]
-
-
-# [START compute_instances_delete]
-def delete_instance(project_id: str, zone: str, machine_name: str) -> None:
- """
- Send an instance deletion request to the Compute Engine API and wait for it to complete.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone you want to use. For example: “us-west3-b”
- machine_name: name of the machine you want to delete.
- """
- instance_client = compute_v1.InstancesClient()
- operation_client = compute_v1.ZoneOperationsClient()
-
- print(f"Deleting {machine_name} from {zone}...")
- operation = instance_client.delete_unary(
- project=project_id, zone=zone, instance=machine_name
- )
- while operation.status != compute_v1.Operation.Status.DONE:
- operation = operation_client.wait(
- operation=operation.name, zone=zone, project=project_id
- )
- if operation.error:
- print("Error during deletion:", operation.error, file=sys.stderr)
- if operation.warnings:
- print("Warning during deletion:", operation.warnings, file=sys.stderr)
- print(f"Instance {machine_name} deleted.")
- return
-
-
-# [END compute_instances_delete]
-
-
-# [START compute_instances_operation_check]
-def wait_for_operation(
- operation: compute_v1.Operation, project_id: str
-) -> compute_v1.Operation:
- """
- This method waits for an operation to be completed. Calling this function
- will block until the operation is finished.
-
- Args:
- operation: The Operation object representing the operation you want to
- wait on.
- project_id: project ID or project number of the Cloud project you want to use.
-
- Returns:
- Finished Operation object.
- """
- kwargs = {"project": project_id, "operation": operation.name}
- if operation.zone:
- client = compute_v1.ZoneOperationsClient()
- # Operation.zone is a full URL address of a zone, so we need to extract just the name
- kwargs["zone"] = operation.zone.rsplit("/", maxsplit=1)[1]
- elif operation.region:
- client = compute_v1.RegionOperationsClient()
- # Operation.region is a full URL address of a region, so we need to extract just the name
- kwargs["region"] = operation.region.rsplit("/", maxsplit=1)[1]
- else:
- client = compute_v1.GlobalOperationsClient()
- return client.wait(**kwargs)
-
-
-# [END compute_instances_operation_check]
-
-
-def main(project_id: str, zone: str, instance_name: str) -> None:
-
- create_instance(project_id, zone, instance_name)
-
- zone_instances = list_instances(project_id, zone)
- print(f"Instances found in {zone}:", ", ".join(i.name for i in zone_instances))
-
- all_instances = list_all_instances(project_id)
- print(f"Instances found in project {project_id}:")
- for i_zone, instances in all_instances.items():
- print(f"{i_zone}:", ", ".join(i.name for i in instances))
-
- delete_instance(project_id, zone, instance_name)
-
-
-if __name__ == "__main__":
- import uuid
- import google.auth
- import google.auth.exceptions
-
- try:
- default_project_id = google.auth.default()[1]
- except google.auth.exceptions.DefaultCredentialsError:
- print(
- "Please use `gcloud auth application-default login` "
- "or set GOOGLE_APPLICATION_CREDENTIALS to use this script."
- )
- else:
- instance_name = "quickstart-" + uuid.uuid4().hex[:10]
- instance_zone = "europe-central2-b"
- main(default_project_id, instance_zone, instance_name)
diff --git a/samples/snippets/sample_create_vm.py b/samples/snippets/sample_create_vm.py
deleted file mode 100644
index 1ea6ba2d2..000000000
--- a/samples/snippets/sample_create_vm.py
+++ /dev/null
@@ -1,423 +0,0 @@
-# Copyright 2021 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-import re
-import sys
-from typing import List
-
-# [START compute_instances_create_with_subnet]
-# [START compute_instances_create_from_image_plus_snapshot_disk]
-# [START compute_instances_create_from_snapshot]
-# [START compute_instances_create_from_image_plus_empty_disk]
-# [START compute_instances_create_from_custom_image]
-# [START compute_instances_create_from_image]
-from google.cloud import compute_v1
-
-
-# [END compute_instances_create_from_image]
-# [END compute_instances_create_from_custom_image]
-# [END compute_instances_create_from_image_plus_empty_disk]
-# [END compute_instances_create_from_snapshot]
-# [END compute_instances_create_from_image_plus_snapshot_disk]
-# [END compute_instances_create_with_subnet]
-
-
-# [START compute_instances_create_with_subnet]
-# [START compute_instances_create_from_image_plus_snapshot_disk]
-# [START compute_instances_create_from_image_plus_empty_disk]
-# [START compute_instances_create_from_custom_image]
-# [START compute_instances_create_from_image]
-def disk_from_image(
- disk_type: str, disk_size_gb: int, boot: bool, source_image: str
-) -> compute_v1.AttachedDisk:
- """
- Create an AttachedDisk object to be used in VM instance creation. Uses an image as the
- source for the new disk.
-
- Args:
- disk_type: the type of disk you want to create. This value uses the following format:
- "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
- For example: "zones/us-west3-b/diskTypes/pd-ssd"
- disk_size_gb: size of the new disk in gigabytes
- boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
- source_image: source image to use when creating this disk. You must have read access to this disk. This can be one
- of the publicly available images or an image from one of your projects.
- This value uses the following format: "projects/{project_name}/global/images/{image_name}"
-
- Returns:
- AttachedDisk object configured to be created using the specified image.
- """
- boot_disk = compute_v1.AttachedDisk()
- initialize_params = compute_v1.AttachedDiskInitializeParams()
- initialize_params.source_image = source_image
- initialize_params.disk_size_gb = disk_size_gb
- initialize_params.disk_type = disk_type
- boot_disk.initialize_params = initialize_params
- # Remember to set auto_delete to True if you want the disk to be deleted when you delete
- # your VM instance.
- boot_disk.auto_delete = True
- boot_disk.boot = boot
- return boot_disk
-
-
-# [END compute_instances_create_from_image]
-# [END compute_instances_create_from_custom_image]
-# [END compute_instances_create_from_image_plus_empty_disk]
-# [END compute_instances_create_from_image_plus_snapshot_disk]
-# [END compute_instances_create_with_subnet]
-
-
-# [START compute_instances_create_from_image_plus_empty_disk]
-def empty_disk(disk_type: str, disk_size_gb: int) -> compute_v1.AttachedDisk():
- """
- Create an AttachedDisk object to be used in VM instance creation. The created disk contains
- no data and requires formatting before it can be used.
-
- Args:
- disk_type: the type of disk you want to create. This value uses the following format:
- "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
- For example: "zones/us-west3-b/diskTypes/pd-ssd"
- disk_size_gb: size of the new disk in gigabytes
-
- Returns:
- AttachedDisk object configured to be created as an empty disk.
- """
- disk = compute_v1.AttachedDisk()
- initialize_params = compute_v1.AttachedDiskInitializeParams()
- initialize_params.disk_type = disk_type
- initialize_params.disk_size_gb = disk_size_gb
- disk.initialize_params = initialize_params
- # Remember to set auto_delete to True if you want the disk to be deleted when you delete
- # your VM instance.
- disk.auto_delete = True
- disk.boot = False
- return disk
-
-
-# [END compute_instances_create_from_image_plus_empty_disk]
-
-
-# [START compute_instances_create_from_image_plus_snapshot_disk]
-# [START compute_instances_create_from_snapshot]
-def disk_from_snapshot(
- disk_type: str, disk_size_gb: int, boot: bool, disk_snapshot: str
-) -> compute_v1.AttachedDisk():
- """
- Create an AttachedDisk object to be used in VM instance creation. Uses a disk snapshot as the
- source for the new disk.
-
- Args:
- disk_type: the type of disk you want to create. This value uses the following format:
- "zones/{zone}/diskTypes/(pd-standard|pd-ssd|pd-balanced|pd-extreme)".
- For example: "zones/us-west3-b/diskTypes/pd-ssd"
- disk_size_gb: size of the new disk in gigabytes
- boot: boolean flag indicating whether this disk should be used as a boot disk of an instance
- disk_snapshot: disk snapshot to use when creating this disk. You must have read access to this disk.
- This value uses the following format: "projects/{project_name}/global/snapshots/{snapshot_name}"
-
- Returns:
- AttachedDisk object configured to be created using the specified snapshot.
- """
- disk = compute_v1.AttachedDisk()
- initialize_params = compute_v1.AttachedDiskInitializeParams()
- initialize_params.source_snapshot = disk_snapshot
- initialize_params.disk_type = disk_type
- initialize_params.disk_size_gb = disk_size_gb
- disk.initialize_params = initialize_params
- # Remember to set auto_delete to True if you want the disk to be deleted when you delete
- # your VM instance.
- disk.auto_delete = True
- disk.boot = boot
- return disk
-
-
-# [END compute_instances_create_from_snapshot]
-# [END compute_instances_create_from_image_plus_snapshot_disk]
-
-
-# [START compute_instances_create_with_subnet]
-# [START compute_instances_create_from_image_plus_snapshot_disk]
-# [START compute_instances_create_from_snapshot]
-# [START compute_instances_create_from_image_plus_empty_disk]
-# [START compute_instances_create_from_custom_image]
-# [START compute_instances_create_from_image]
-def create_with_disks(
- project_id: str,
- zone: str,
- instance_name: str,
- disks: List[compute_v1.AttachedDisk],
- machine_type: str = "n1-standard-1",
- network_link: str = "global/networks/default",
- subnetwork_link: str = None,
-) -> compute_v1.Instance:
- """
- Send an instance creation request to the Compute Engine API and wait for it to complete.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone to create the instance in. For example: "us-west3-b"
- instance_name: name of the new virtual machine (VM) instance.
- machine_type: machine type of the VM being created. This value uses the
- following format: "zones/{zone}/machineTypes/{type_name}".
- For example: "zones/europe-west3-c/machineTypes/f1-micro"
- disks: a list of compute_v1.AttachedDisk objects describing the disks
- you want to attach to your new instance.
- network_link: name of the network you want the new instance to use.
- For example: "global/networks/default" represents the network
- named "default", which is created automatically for each project.
- subnetwork_link: name of the subnetwork you want the new instance to use.
- This value uses the following format:
- "regions/{region}/subnetworks/{subnetwork_name}"
- Returns:
- Instance object.
- """
- instance_client = compute_v1.InstancesClient()
- operation_client = compute_v1.ZoneOperationsClient()
-
- # Use the network interface provided in the network_link argument.
- network_interface = compute_v1.NetworkInterface()
- network_interface.name = network_link
- if subnetwork_link:
- network_interface.subnetwork = subnetwork_link
-
- # Collect information into the Instance object.
- instance = compute_v1.Instance()
- instance.name = instance_name
- instance.disks = disks
- if re.match(r"^zones/[a-z\d\-]+/machineTypes/[a-z\d\-]+$", machine_type):
- instance.machine_type = machine_type
- else:
- instance.machine_type = f"zones/{zone}/machineTypes/{machine_type}"
- instance.network_interfaces = [network_interface]
-
- # Shielded Instance settings
- # Values presented here are the defaults.
- # instance.shielded_instance_config = compute_v1.ShieldedInstanceConfig()
- # instance.shielded_instance_config.enable_secure_boot = False
- # instance.shielded_instance_config.enable_vtpm = True
- # instance.shielded_instance_config.enable_integrity_monitoring = True
-
- # Prepare the request to insert an instance.
- request = compute_v1.InsertInstanceRequest()
- request.zone = zone
- request.project = project_id
- request.instance_resource = instance
-
- # Wait for the create operation to complete.
- print(f"Creating the {instance_name} instance in {zone}...")
-
- operation = instance_client.insert_unary(request=request)
- while operation.status != compute_v1.Operation.Status.DONE:
- operation = operation_client.wait(
- operation=operation.name, zone=zone, project=project_id
- )
- if operation.error:
- print("Error during creation:", operation.error, file=sys.stderr)
- if operation.warnings:
- print("Warning during creation:", operation.warnings, file=sys.stderr)
- print(f"Instance {instance_name} created.")
- return instance
-
-
-# [END compute_instances_create_from_image]
-# [END compute_instances_create_from_custom_image]
-# [END compute_instances_create_from_image_plus_empty_disk]
-# [END compute_instances_create_from_snapshot]
-# [END compute_instances_create_from_image_plus_snapshot_disk]
-# [END compute_instances_create_with_subnet]
-
-
-# [START compute_instances_create_from_image]
-def create_from_public_image(project_id: str, zone: str, instance_name: str):
- """
- Create a new VM instance with Debian 10 operating system.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone to create the instance in. For example: "us-west3-b"
- instance_name: name of the new virtual machine (VM) instance.
-
- Returns:
- Instance object.
- """
- image_client = compute_v1.ImagesClient()
- # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
- newest_debian = image_client.get_from_family(
- project="debian-cloud", family="debian-10"
- )
- disk_type = f"zones/{zone}/diskTypes/pd-standard"
- disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
- instance = create_with_disks(project_id, zone, instance_name, disks)
- return instance
-
-
-# [END compute_instances_create_from_image]
-
-
-# [START compute_instances_create_from_custom_image]
-def create_from_custom_image(
- project_id: str, zone: str, instance_name: str, custom_image_link: str
-):
- """
- Create a new VM instance with custom image used as its boot disk.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone to create the instance in. For example: "us-west3-b"
- instance_name: name of the new virtual machine (VM) instance.
- custom_image_link: link to the custom image you want to use in the form of:
- "projects/{project_name}/global/images/{image_name}"
-
- Returns:
- Instance object.
- """
- disk_type = f"zones/{zone}/diskTypes/pd-standard"
- disks = [disk_from_image(disk_type, 10, True, custom_image_link)]
- instance = create_with_disks(project_id, zone, instance_name, disks)
- return instance
-
-
-# [END compute_instances_create_from_custom_image]
-
-
-# [START compute_instances_create_from_image_plus_empty_disk]
-def create_with_additional_disk(project_id: str, zone: str, instance_name: str):
- """
- Create a new VM instance with Debian 10 operating system and a 11 GB additional
- empty disk.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone to create the instance in. For example: "us-west3-b"
- instance_name: name of the new virtual machine (VM) instance.
-
- Returns:
- Instance object.
- """
- image_client = compute_v1.ImagesClient()
- # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
- newest_debian = image_client.get_from_family(
- project="debian-cloud", family="debian-10"
- )
- disk_type = f"zones/{zone}/diskTypes/pd-standard"
- disks = [
- disk_from_image(disk_type, 10, True, newest_debian.self_link),
- empty_disk(disk_type, 11),
- ]
- instance = create_with_disks(project_id, zone, instance_name, disks)
- return instance
-
-
-# [END compute_instances_create_from_image_plus_empty_disk]
-
-
-# [START compute_instances_create_from_snapshot]
-def create_from_snapshot(
- project_id: str, zone: str, instance_name: str, snapshot_link: str
-):
- """
- Create a new VM instance with boot disk created from a snapshot.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone to create the instance in. For example: "us-west3-b"
- instance_name: name of the new virtual machine (VM) instance.
- snapshot_link: link to the snapshot you want to use as the source of your
- boot disk in the form of: "projects/{project_name}/global/snapshots/{snapshot_name}"
-
- Returns:
- Instance object.
- """
- disk_type = f"zones/{zone}/diskTypes/pd-standard"
- disks = [disk_from_snapshot(disk_type, 11, True, snapshot_link)]
- instance = create_with_disks(project_id, zone, instance_name, disks)
- return instance
-
-
-# [END compute_instances_create_from_snapshot]
-
-
-# [START compute_instances_create_from_image_plus_snapshot_disk]
-def create_with_snapshotted_data_disk(
- project_id: str, zone: str, instance_name: str, snapshot_link: str
-):
- """
- Create a new VM instance with Debian 10 operating system and data disk created from snapshot.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone to create the instance in. For example: "us-west3-b"
- instance_name: name of the new virtual machine (VM) instance.
- snapshot_link: link to the snapshot you want to use as the source of your
- data disk in the form of: "projects/{project_name}/global/snapshots/{snapshot_name}"
-
- Returns:
- Instance object.
- """
- image_client = compute_v1.ImagesClient()
- # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
- newest_debian = image_client.get_from_family(
- project="debian-cloud", family="debian-10"
- )
- disk_type = f"zones/{zone}/diskTypes/pd-standard"
- disks = [
- disk_from_image(disk_type, 10, True, newest_debian.self_link),
- disk_from_snapshot(disk_type, 11, False, snapshot_link),
- ]
- instance = create_with_disks(project_id, zone, instance_name, disks)
- return instance
-
-
-# [END compute_instances_create_from_image_plus_snapshot_disk]
-
-
-# [START compute_instances_create_with_subnet]
-def create_with_subnet(
- project_id: str, zone: str, instance_name: str, network_link: str, subnet_link: str
-):
- """
- Create a new VM instance with Debian 10 operating system in specified network and subnetwork.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone to create the instance in. For example: "us-west3-b"
- instance_name: name of the new virtual machine (VM) instance.
- network_link: name of the network you want the new instance to use.
- For example: "global/networks/default" represents the network
- named "default", which is created automatically for each project.
- subnetwork_link: name of the subnetwork you want the new instance to use.
- This value uses the following format:
- "regions/{region}/subnetworks/{subnetwork_name}"
-
- Returns:
- Instance object.
- """
- image_client = compute_v1.ImagesClient()
- # List of public operating system (OS) images: https://cloud.google.com/compute/docs/images/os-details
- newest_debian = image_client.get_from_family(
- project="debian-cloud", family="debian-10"
- )
- disk_type = f"zones/{zone}/diskTypes/pd-standard"
- disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
- instance = create_with_disks(
- project_id,
- zone,
- instance_name,
- disks,
- network_link=network_link,
- subnetwork_link=subnet_link,
- )
- return instance
-
-
-# [END compute_instances_create_with_subnet]
diff --git a/samples/snippets/sample_custom_hostname.py b/samples/snippets/sample_custom_hostname.py
deleted file mode 100644
index 8d732f594..000000000
--- a/samples/snippets/sample_custom_hostname.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# Copyright 2022 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# [START compute_instances_create_custom_hostname]
-import sys
-
-
-# [START compute_instances_get_hostname]
-from google.cloud import compute_v1
-
-# [END compute_instances_get_hostname]
-# [END compute_instances_create_custom_hostname]
-
-
-# [START compute_instances_create_custom_hostname]
-def create_instance(
- project_id: str, zone: str, instance_name: str, hostname: str,
-) -> compute_v1.Instance:
- """
- Send an instance creation request to the Compute Engine API and wait for it to complete.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone you want to use. For example: “us-west3-b”
- instance_name: name of the new virtual machine.
- hostname: Custom hostname of the new VM instance.
- Custom hostnames must conform to RFC 1035 requirements for valid hostnames.
-
- Returns:
- Instance object.
- """
- instance_client = compute_v1.InstancesClient()
- operation_client = compute_v1.ZoneOperationsClient()
-
- # Describe the size and source image of the boot disk to attach to the instance.
- disk = compute_v1.AttachedDisk()
- initialize_params = compute_v1.AttachedDiskInitializeParams()
- initialize_params.source_image = (
- "projects/debian-cloud/global/images/family/debian-10"
- )
- initialize_params.disk_size_gb = 10
- disk.initialize_params = initialize_params
- disk.auto_delete = True
- disk.boot = True
- disk.type_ = "PERSISTENT"
-
- # Use the default VPC network.
- network_interface = compute_v1.NetworkInterface()
- network_interface.name = "default"
-
- # Collect information into the Instance object.
- instance = compute_v1.Instance()
- instance.name = instance_name
- instance.disks = [disk]
- instance.machine_type = f"zones/{zone}/machineTypes/e2-small"
- instance.network_interfaces = [network_interface]
-
- # Custom hostnames are not resolved by the automatically created records
- # provided by Compute Engine internal DNS.
- # You must manually configure the DNS record for your custom hostname.
- instance.hostname = hostname
-
- # Prepare the request to insert an instance.
- request = compute_v1.InsertInstanceRequest()
- request.zone = zone
- request.project = project_id
- request.instance_resource = instance
-
- # Wait for the create operation to complete.
- print(f"Creating the {instance_name} instance in {zone}...")
- operation = instance_client.insert_unary(request=request)
- while operation.status != compute_v1.Operation.Status.DONE:
- operation = operation_client.wait(
- operation=operation.name, zone=zone, project=project_id
- )
- if operation.error:
- print("Error during creation:", operation.error, file=sys.stderr)
- if operation.warnings:
- print("Warning during creation:", operation.warnings, file=sys.stderr)
- print(f"Instance {instance_name} created.")
- return instance
-
-
-# [END compute_instances_create_custom_hostname]
-
-
-# [START compute_instances_get_hostname]
-def get_instance_hostname(project_id: str, zone: str, instance_name: str) -> str:
- """
- Get the hostname set for given instance.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone you want to use. For example: “us-west3-b”
- instance_name: name of the virtual machine you want to check.
-
- Returns:
- The hostname of given instance.
- """
- instance_client = compute_v1.InstancesClient()
- instance = instance_client.get(
- project=project_id, zone=zone, instance=instance_name
- )
- return instance.hostname
-
-
-# [END compute_instances_get_hostname]
diff --git a/samples/snippets/sample_delete_protection.py b/samples/snippets/sample_delete_protection.py
deleted file mode 100644
index 1894d3903..000000000
--- a/samples/snippets/sample_delete_protection.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# Copyright 2022 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# [START compute_delete_protection_create]
-import sys
-
-# [END compute_delete_protection_create]
-
-# [START compute_delete_protection_get]
-# [START compute_delete_protection_set]
-# [START compute_delete_protection_create]
-from google.cloud import compute_v1
-
-# [END compute_delete_protection_create]
-# [END compute_delete_protection_set]
-# [END compute_delete_protection_get]
-
-
-# [START compute_delete_protection_create]
-def create_instance(
- project_id: str, zone: str, instance_name: str, delete_protection: bool,
-) -> compute_v1.Instance:
- """
- Send an instance creation request to the Compute Engine API and wait for it to complete.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone you want to use. For example: “us-west3-b”
- instance_name: name of the new virtual machine.
- delete_protection: boolean value indicating if the new virtual machine should be
- protected against deletion or not.
- Returns:
- Instance object.
- """
- instance_client = compute_v1.InstancesClient()
- operation_client = compute_v1.ZoneOperationsClient()
-
- # Describe the size and source image of the boot disk to attach to the instance.
- disk = compute_v1.AttachedDisk()
- initialize_params = compute_v1.AttachedDiskInitializeParams()
- initialize_params.source_image = (
- "projects/debian-cloud/global/images/family/debian-10"
- )
- initialize_params.disk_size_gb = 10
- disk.initialize_params = initialize_params
- disk.auto_delete = True
- disk.boot = True
- disk.type_ = "PERSISTENT"
-
- # Use the default VPC network.
- network_interface = compute_v1.NetworkInterface()
- network_interface.name = "default"
-
- # Collect information into the Instance object.
- instance = compute_v1.Instance()
- instance.name = instance_name
- instance.disks = [disk]
- instance.machine_type = f"zones/{zone}/machineTypes/e2-small"
- instance.network_interfaces = [network_interface]
-
- # Set the delete protection bit
- instance.deletion_protection = delete_protection
-
- # Prepare the request to insert an instance.
- request = compute_v1.InsertInstanceRequest()
- request.zone = zone
- request.project = project_id
- request.instance_resource = instance
-
- # Wait for the create operation to complete.
- print(f"Creating the {instance_name} instance in {zone}...")
- operation = instance_client.insert_unary(request=request)
- while operation.status != compute_v1.Operation.Status.DONE:
- operation = operation_client.wait(
- operation=operation.name, zone=zone, project=project_id
- )
- if operation.error:
- print("Error during creation:", operation.error, file=sys.stderr)
- if operation.warnings:
- print("Warning during creation:", operation.warnings, file=sys.stderr)
- print(f"Instance {instance_name} created.")
- return instance
-
-
-# [END compute_delete_protection_create]
-
-
-# [START compute_delete_protection_set]
-def set_delete_protection(
- project_id: str, zone: str, instance_name: str, delete_protection: bool
-):
- """
- Updates the delete protection setting of given instance.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone you want to use. For example: “us-west3-b”
- instance_name: name of the virtual machine to update.
- delete_protection: boolean value indicating if the virtual machine should be
- protected against deletion or not.
- """
- instance_client = compute_v1.InstancesClient()
- operation_client = compute_v1.ZoneOperationsClient()
-
- request = compute_v1.SetDeletionProtectionInstanceRequest()
- request.project = project_id
- request.zone = zone
- request.resource = instance_name
- request.deletion_protection = delete_protection
-
- operation = instance_client.set_deletion_protection_unary(request)
- operation_client.wait(project=project_id, zone=zone, operation=operation.name)
-
-
-# [END compute_delete_protection_set]
-
-
-# [START compute_delete_protection_get]
-def get_delete_protection(project_id: str, zone: str, instance_name: str) -> bool:
- """
- Returns the state of delete protection flag of given instance.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone you want to use. For example: “us-west3-b”
- instance_name: name of the virtual machine to check.
- Returns:
- The state of the delete protection setting.
- """
- instance_client = compute_v1.InstancesClient()
- instance = instance_client.get(
- project=project_id, zone=zone, instance=instance_name
- )
- return instance.deletion_protection
-
-
-# [END compute_delete_protection_get]
diff --git a/samples/snippets/sample_preemptible.py b/samples/snippets/sample_preemptible.py
deleted file mode 100644
index 3e1b2fc97..000000000
--- a/samples/snippets/sample_preemptible.py
+++ /dev/null
@@ -1,193 +0,0 @@
-# Copyright 2022 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# [START compute_preemptible_history]
-import datetime
-
-# [END compute_preemptible_history]
-# [START compute_preemptible_create]
-import sys
-
-# [END compute_preemptible_create]
-
-# [START compute_preemptible_history]
-from typing import List, Tuple
-
-# [END compute_preemptible_history]
-
-# [START compute_preemptible_create]
-# [START compute_preemptible_check]
-# [START compute_preemptible_history]
-from google.cloud import compute_v1
-
-# [END compute_preemptible_history]
-# [END compute_preemptible_check]
-# [END compute_preemptible_create]
-
-# [START compute_preemptible_history]
-from google.cloud.compute_v1.services.zone_operations import pagers
-
-# [END compute_preemptible_history]
-
-
-# [START compute_preemptible_create]
-def create_preemptible_instance(
- project_id: str, zone: str, instance_name: str,
-) -> compute_v1.Instance:
- """
- Send an instance creation request to the Compute Engine API and wait for it to complete.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone you want to use. For example: "us-west3-b"
- instance_name: name of the new virtual machine.
- Returns:
- Instance object.
- """
- instance_client = compute_v1.InstancesClient()
- operation_client = compute_v1.ZoneOperationsClient()
-
- # Describe the size and source image of the boot disk to attach to the instance.
- disk = compute_v1.AttachedDisk()
- initialize_params = compute_v1.AttachedDiskInitializeParams()
- initialize_params.source_image = (
- "projects/debian-cloud/global/images/family/debian-10"
- )
- initialize_params.disk_size_gb = 10
- disk.initialize_params = initialize_params
- disk.auto_delete = True
- disk.boot = True
- disk.type_ = "PERSISTENT"
-
- # Use the default VPC network.
- network_interface = compute_v1.NetworkInterface()
- network_interface.name = "default"
-
- # Collect information into the Instance object.
- instance = compute_v1.Instance()
- instance.name = instance_name
- instance.disks = [disk]
- instance.machine_type = f"zones/{zone}/machineTypes/e2-small"
- instance.network_interfaces = [network_interface]
-
- # Set the preemptible setting
- instance.scheduling = compute_v1.Scheduling()
- instance.scheduling.preemptible = True
-
- # Prepare the request to insert an instance.
- request = compute_v1.InsertInstanceRequest()
- request.zone = zone
- request.project = project_id
- request.instance_resource = instance
-
- # Wait for the create operation to complete.
- print(f"Creating the {instance_name} instance in {zone}...")
- operation = instance_client.insert_unary(request=request)
- while operation.status != compute_v1.Operation.Status.DONE:
- operation = operation_client.wait(
- operation=operation.name, zone=zone, project=project_id
- )
- if operation.error:
- print("Error during creation:", operation.error, file=sys.stderr)
- if operation.warnings:
- print("Warning during creation:", operation.warnings, file=sys.stderr)
- print(f"Instance {instance_name} created.")
- return instance_client.get(project=project_id, zone=zone, instance=instance_name)
-
-
-# [END compute_preemptible_create]
-
-
-# [START compute_preemptible_check]
-def is_preemptible(project_id: str, zone: str, instance_name: str) -> bool:
- """
- Check if a given instance is preemptible or not.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone you want to use. For example: "us-west3-b"
- instance_name: name of the virtual machine to check.
- Returns:
- The preemptible status of the instance.
- """
- instance_client = compute_v1.InstancesClient()
- instance = instance_client.get(
- project=project_id, zone=zone, instance=instance_name
- )
- return instance.scheduling.preemptible
-
-
-# [END compute_preemptible_check]
-
-
-# [START compute_preemptible_history]
-def list_zone_operations(
- project_id: str, zone: str, filter: str = ""
-) -> pagers.ListPager:
- """
- List all recent operations the happened in given zone in a project. Optionally filter those
- operations by providing a filter. More about using the filter can be found here:
- https://cloud.google.com/compute/docs/reference/rest/v1/zoneOperations/list
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone you want to use. For example: "us-west3-b"
- instance_name: name of the virtual machine to look for.
- Returns:
- List of preemption operations in given zone.
- """
- operation_client = compute_v1.ZoneOperationsClient()
- request = compute_v1.ListZoneOperationsRequest()
- request.project = project_id
- request.zone = zone
- request.filter = filter
-
- return operation_client.list(request)
-
-
-def preemption_history(
- project_id: str, zone: str, instance_name: str = None
-) -> List[Tuple[str, datetime.datetime]]:
- """
- Get a list of preemption operations from given zone in a project. Optionally limit
- the results to instance name.
-
- Args:
- project_id: project ID or project number of the Cloud project you want to use.
- zone: name of the zone you want to use. For example: "us-west3-b"
- instance_name: name of the virtual machine to look for.
- Returns:
- List of preemption operations in given zone.
- """
- if instance_name:
- filter = (
- f'operationType="compute.instances.preempted" '
- f"AND targetLink:instances/{instance_name}"
- )
- else:
- filter = 'operationType="compute.instances.preempted"'
-
- history = []
-
- for operation in list_zone_operations(project_id, zone, filter):
- this_instance_name = operation.target_link.rsplit("/", maxsplit=1)[1]
- if instance_name and this_instance_name == instance_name:
- # The filter used is not 100% accurate, it's `contains` not `equals`
- # So we need to check the name to make sure it's the one we want.
- moment = datetime.datetime.fromisoformat(operation.insert_time)
- history.append((instance_name, moment))
-
- return history
-
-
-# [END compute_preemptible_history]
diff --git a/samples/snippets/sample_start_stop.py b/samples/snippets/sample_start_stop.py
deleted file mode 100644
index 36fe54b99..000000000
--- a/samples/snippets/sample_start_stop.py
+++ /dev/null
@@ -1,152 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright 2021 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-A sample script showing how to start and stop Google Compute Engine instances.
-"""
-
-# [START compute_start_instance]
-# [START compute_start_enc_instance]
-# [START compute_stop_instance]
-# [START compute_reset_instance]
-from google.cloud import compute_v1
-
-# [END compute_reset_instance]
-# [END compute_stop_instance]
-# [END compute_start_enc_instance]
-# [END compute_start_instance]
-
-
-# [START compute_start_instance]
-def start_instance(project_id: str, zone: str, instance_name: str):
- """
- Starts a stopped Google Compute Engine instance (with unencrypted disks).
-
- Args:
- project_id: project ID or project number of the Cloud project your instance belongs to.
- zone: name of the zone your instance belongs to.
- instance_name: name of the instance you want to start.
- """
- instance_client = compute_v1.InstancesClient()
- op_client = compute_v1.ZoneOperationsClient()
-
- op = instance_client.start_unary(
- project=project_id, zone=zone, instance=instance_name
- )
-
- while op.status != compute_v1.Operation.Status.DONE:
- op = op_client.wait(operation=op.name, zone=zone, project=project_id)
- return
-
-
-# [END compute_start_instance]
-
-
-# [START compute_start_enc_instance]
-def start_instance_with_encryption_key(
- project_id: str, zone: str, instance_name: str, key: bytes
-):
- """
- Starts a stopped Google Compute Engine instance (with encrypted disks).
-
- Args:
- project_id: project ID or project number of the Cloud project your instance belongs to.
- zone: name of the zone your instance belongs to.
- instance_name: name of the instance your want to start.
- key: bytes object representing a raw base64 encoded key to your machines boot disk.
- For more information about disk encryption see:
- https://cloud.google.com/compute/docs/disks/customer-supplied-encryption#specifications
- """
- instance_client = compute_v1.InstancesClient()
- op_client = compute_v1.ZoneOperationsClient()
-
- instance_data = instance_client.get(
- project=project_id, zone=zone, instance=instance_name
- )
-
- # Prepare the information about disk encryption
- disk_data = compute_v1.CustomerEncryptionKeyProtectedDisk()
- disk_data.source = instance_data.disks[0].source
- disk_data.disk_encryption_key = compute_v1.CustomerEncryptionKey()
- # Use raw_key to send over the key to unlock the disk
- # To use a key stored in KMS, you need to provide `kms_key_name` and `kms_key_service_account`
- disk_data.disk_encryption_key.raw_key = key
- enc_data = compute_v1.InstancesStartWithEncryptionKeyRequest()
- enc_data.disks = [disk_data]
-
- op = instance_client.start_with_encryption_key_unary(
- project=project_id,
- zone=zone,
- instance=instance_name,
- instances_start_with_encryption_key_request_resource=enc_data,
- )
-
- while op.status != compute_v1.Operation.Status.DONE:
- op = op_client.wait(operation=op.name, zone=zone, project=project_id)
- return
-
-
-# [END compute_start_enc_instance]
-
-
-# [START compute_stop_instance]
-def stop_instance(project_id: str, zone: str, instance_name: str):
- """
- Stops a running Google Compute Engine instance.
-
- Args:
- project_id: project ID or project number of the Cloud project your instance belongs to.
- zone: name of the zone your instance belongs to.
- instance_name: name of the instance your want to stop.
- """
- instance_client = compute_v1.InstancesClient()
- op_client = compute_v1.ZoneOperationsClient()
-
- op = instance_client.stop_unary(
- project=project_id, zone=zone, instance=instance_name
- )
-
- while op.status != compute_v1.Operation.Status.DONE:
- op = op_client.wait(operation=op.name, zone=zone, project=project_id)
- return
-
-
-# [END compute_stop_instance]
-
-
-# [START compute_reset_instance]
-def reset_instance(project_id: str, zone: str, instance_name: str):
- """
- Resets a running Google Compute Engine instance (with unencrypted disks).
-
- Args:
- project_id: project ID or project number of the Cloud project your instance belongs to.
- zone: name of the zone your instance belongs to.
- instance_name: name of the instance your want to reset.
- """
- instance_client = compute_v1.InstancesClient()
- op_client = compute_v1.ZoneOperationsClient()
-
- op = instance_client.reset_unary(
- project=project_id, zone=zone, instance=instance_name
- )
-
- while op.status != compute_v1.Operation.Status.DONE:
- op = op_client.wait(operation=op.name, zone=zone, project=project_id)
- return
-
-
-# [END compute_reset_instance]
diff --git a/samples/snippets/sample_templates.py b/samples/snippets/sample_templates.py
deleted file mode 100644
index ddea06377..000000000
--- a/samples/snippets/sample_templates.py
+++ /dev/null
@@ -1,251 +0,0 @@
-# Copyright 2021 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# [START compute_template_list ]
-from typing import Iterable
-
-# [END compute_template_list ]
-
-# [START compute_template_create ]
-# [START compute_template_list ]
-# [START compute_template_get ]
-# [START compute_template_create_from_instance ]
-# [START compute_template_create_with_subnet ]
-# [START compute_template_delete ]
-from google.cloud import compute_v1
-
-# [END compute_template_delete ]
-# [END compute_template_create_with_subnet ]
-# [END compute_template_create_from_instance ]
-# [END compute_template_get ]
-# [END compute_template_list ]
-# [END compute_template_create ]
-
-
-# [START compute_template_get ]
-def get_instance_template(
- project_id: str, template_name: str
-) -> compute_v1.InstanceTemplate:
- """
- Retrieve an instance template, which you can use to create virtual machine
- (VM) instances and managed instance groups (MIGs).
-
- Args:
- project_id: project ID or project number of the Cloud project you use.
- template_name: name of the template to retrieve.
-
- Returns:
- InstanceTemplate object that represents the retrieved template.
- """
- template_client = compute_v1.InstanceTemplatesClient()
- return template_client.get(project=project_id, instance_template=template_name)
-
-
-# [END compute_template_get ]
-
-
-# [START compute_template_list ]
-def list_instance_templates(project_id: str) -> Iterable[compute_v1.InstanceTemplate]:
- """
- Get a list of InstanceTemplate objects available in a project.
-
- Args:
- project_id: project ID or project number of the Cloud project you use.
-
- Returns:
- Iterable list of InstanceTemplate objects.
- """
- template_client = compute_v1.InstanceTemplatesClient()
- return template_client.list(project=project_id)
-
-
-# [END compute_template_list ]
-
-
-# [START compute_template_create ]
-def create_template(project_id: str, template_name: str) -> compute_v1.InstanceTemplate:
- """
- Create a new instance template with the provided name and a specific
- instance configuration.
-
- Args:
- project_id: project ID or project number of the Cloud project you use.
- template_name: name of the new template to create.
-
- Returns:
- InstanceTemplate object that represents the new instance template.
- """
- # The template describes the size and source image of the boot disk
- # to attach to the instance.
- disk = compute_v1.AttachedDisk()
- initialize_params = compute_v1.AttachedDiskInitializeParams()
- initialize_params.source_image = (
- "projects/debian-cloud/global/images/family/debian-11"
- )
- initialize_params.disk_size_gb = 250
- disk.initialize_params = initialize_params
- disk.auto_delete = True
- disk.boot = True
-
- # The template connects the instance to the `default` network,
- # without specifying a subnetwork.
- network_interface = compute_v1.NetworkInterface()
- network_interface.name = "global/networks/default"
-
- # The template lets the instance use an external IP address.
- access_config = compute_v1.AccessConfig()
- access_config.name = "External NAT"
- access_config.type_ = "ONE_TO_ONE_NAT"
- access_config.network_tier = "PREMIUM"
- network_interface.access_configs = [access_config]
-
- template = compute_v1.InstanceTemplate()
- template.name = template_name
- template.properties.disks = [disk]
- template.properties.machine_type = "e2-standard-4"
- template.properties.network_interfaces = [network_interface]
-
- template_client = compute_v1.InstanceTemplatesClient()
- operation_client = compute_v1.GlobalOperationsClient()
- op = template_client.insert_unary(
- project=project_id, instance_template_resource=template
- )
- operation_client.wait(project=project_id, operation=op.name)
-
- return template_client.get(project=project_id, instance_template=template_name)
-
-
-# [END compute_template_create ]
-
-
-# [START compute_template_create_from_instance ]
-def create_template_from_instance(
- project_id: str, instance: str, template_name: str
-) -> compute_v1.InstanceTemplate:
- """
- Create a new instance template based on an existing instance.
- This new template specifies a different boot disk.
-
- Args:
- project_id: project ID or project number of the Cloud project you use.
- instance: the instance to base the new template on. This value uses
- the following format: "projects/{project}/zones/{zone}/instances/{instance_name}"
- template_name: name of the new template to create.
-
- Returns:
- InstanceTemplate object that represents the new instance template.
- """
- disk = compute_v1.DiskInstantiationConfig()
- # Device name must match the name of a disk attached to the instance you are
- # basing your template on.
- disk.device_name = "disk-1"
- # Replace the original boot disk image used in your instance with a Rocky Linux image.
- disk.instantiate_from = "CUSTOM_IMAGE"
- disk.custom_image = "projects/rocky-linux-cloud/global/images/family/rocky-linux-8"
- # Override the auto_delete setting.
- disk.auto_delete = True
-
- template = compute_v1.InstanceTemplate()
- template.name = template_name
- template.source_instance = instance
- template.source_instance_params = compute_v1.SourceInstanceParams()
- template.source_instance_params.disk_configs = [disk]
-
- template_client = compute_v1.InstanceTemplatesClient()
- operation_client = compute_v1.GlobalOperationsClient()
- op = template_client.insert_unary(
- project=project_id, instance_template_resource=template
- )
- operation_client.wait(project=project_id, operation=op.name)
-
- return template_client.get(project=project_id, instance_template=template_name)
-
-
-# [END compute_template_create_from_instance ]
-
-
-# [START compute_template_create_with_subnet ]
-def create_template_with_subnet(
- project_id: str, network: str, subnetwork: str, template_name: str
-) -> compute_v1.InstanceTemplate:
- """
- Create an instance template that uses a provided subnet.
-
- Args:
- project_id: project ID or project number of the Cloud project you use.
- network: the network to be used in the new template. This value uses
- the following format: "projects/{project}/global/networks/{network}"
- subnetwork: the subnetwork to be used in the new template. This value
- uses the following format: "projects/{project}/regions/{region}/subnetworks/{subnetwork}"
- template_name: name of the new template to create.
-
- Returns:
- InstanceTemplate object that represents the new instance template.
- """
- # The template describes the size and source image of the book disk to
- # attach to the instance.
- disk = compute_v1.AttachedDisk()
- initialize_params = compute_v1.AttachedDiskInitializeParams()
- initialize_params.source_image = (
- "projects/debian-cloud/global/images/family/debian-11"
- )
- initialize_params.disk_size_gb = 250
- disk.initialize_params = initialize_params
- disk.auto_delete = True
- disk.boot = True
-
- template = compute_v1.InstanceTemplate()
- template.name = template_name
- template.properties = compute_v1.InstanceProperties()
- template.properties.disks = [disk]
- template.properties.machine_type = "e2-standard-4"
-
- # The template connects the instance to the specified network and subnetwork.
- network_interface = compute_v1.NetworkInterface()
- network_interface.network = network
- network_interface.subnetwork = subnetwork
- template.properties.network_interfaces = [network_interface]
-
- template_client = compute_v1.InstanceTemplatesClient()
- operation_client = compute_v1.GlobalOperationsClient()
- op = template_client.insert_unary(
- project=project_id, instance_template_resource=template
- )
- operation_client.wait(project=project_id, operation=op.name)
-
- return template_client.get(project=project_id, instance_template=template_name)
-
-
-# [END compute_template_create_with_subnet ]
-
-
-# [START compute_template_delete ]
-def delete_instance_template(project_id: str, template_name: str):
- """
- Delete an instance template.
-
- Args:
- project_id: project ID or project number of the Cloud project you use.
- template_name: name of the template to delete.
- """
- template_client = compute_v1.InstanceTemplatesClient()
- operation_client = compute_v1.GlobalOperationsClient()
- op = template_client.delete_unary(
- project=project_id, instance_template=template_name
- )
- operation_client.wait(project=project_id, operation=op.name)
- return
-
-
-# [END compute_template_delete ]
diff --git a/samples/snippets/test_quickstart.py b/samples/snippets/test_quickstart.py
deleted file mode 100644
index 705707656..000000000
--- a/samples/snippets/test_quickstart.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2021 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import re
-import typing
-import uuid
-
-import google.auth
-
-from quickstart import main
-
-PROJECT = google.auth.default()[1]
-INSTANCE_NAME = "i" + uuid.uuid4().hex[:10]
-INSTANCE_ZONE = "europe-central2-b"
-
-
-def test_main(capsys: typing.Any) -> None:
- main(PROJECT, INSTANCE_ZONE, INSTANCE_NAME)
-
- out, _ = capsys.readouterr()
-
- assert f"Instance {INSTANCE_NAME} created." in out
- assert re.search(f"Instances found in {INSTANCE_ZONE}:.+{INSTANCE_NAME}", out)
- assert re.search(f"zones/{INSTANCE_ZONE}:.+{INSTANCE_NAME}", out)
- assert f"Instance {INSTANCE_NAME} deleted." in out
diff --git a/samples/snippets/tests/__init__.py b/samples/snippets/tests/__init__.py
new file mode 100644
index 000000000..4bbe0ffdb
--- /dev/null
+++ b/samples/snippets/tests/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/samples/snippets/test_sample_custom_hostname.py b/samples/snippets/tests/test_custom_hostnames.py
similarity index 77%
rename from samples/snippets/test_sample_custom_hostname.py
rename to samples/snippets/tests/test_custom_hostnames.py
index 80666c459..b8583db39 100644
--- a/samples/snippets/test_sample_custom_hostname.py
+++ b/samples/snippets/tests/test_custom_hostnames.py
@@ -17,9 +17,9 @@
import google.auth
import pytest
-from quickstart import delete_instance
-from sample_custom_hostname import create_instance
-from sample_custom_hostname import get_instance_hostname
+from ..instances.custom_hostname.create import create_instance_custom_hostname
+from ..instances.custom_hostname.get import get_hostname
+from ..instances.delete import delete_instance
PROJECT = google.auth.default()[1]
INSTANCE_ZONE = "europe-north1-c"
@@ -39,13 +39,13 @@ def random_hostname():
yield "instance.{}.hostname".format(random.randint(0, 2 ** 10))
-def test_delete_protection(autodelete_instance_name, random_hostname):
- instance = create_instance(
+def test_custom_hostname(autodelete_instance_name, random_hostname):
+ instance = create_instance_custom_hostname(
PROJECT, INSTANCE_ZONE, autodelete_instance_name, random_hostname
)
assert instance.name == autodelete_instance_name
assert instance.hostname == random_hostname
assert (
- get_instance_hostname(PROJECT, INSTANCE_ZONE, autodelete_instance_name)
+ get_hostname(PROJECT, INSTANCE_ZONE, autodelete_instance_name)
== random_hostname
)
diff --git a/samples/snippets/test_sample_delete_protection.py b/samples/snippets/tests/test_delete_protection.py
similarity index 80%
rename from samples/snippets/test_sample_delete_protection.py
rename to samples/snippets/tests/test_delete_protection.py
index ee57a3e22..643c9294d 100644
--- a/samples/snippets/test_sample_delete_protection.py
+++ b/samples/snippets/tests/test_delete_protection.py
@@ -16,10 +16,10 @@
import google.auth
import pytest
-from quickstart import delete_instance
-from sample_delete_protection import create_instance
-from sample_delete_protection import get_delete_protection
-from sample_delete_protection import set_delete_protection
+from ..instances.delete import delete_instance
+from ..instances.delete_protection.create import create_protected_instance
+from ..instances.delete_protection.get import get_delete_protection
+from ..instances.delete_protection.set import set_delete_protection
PROJECT = google.auth.default()[1]
INSTANCE_ZONE = "europe-central2-a"
@@ -38,7 +38,9 @@ def autodelete_instance_name():
def test_delete_protection(autodelete_instance_name):
- instance = create_instance(PROJECT, INSTANCE_ZONE, autodelete_instance_name, True)
+ instance = create_protected_instance(
+ PROJECT, INSTANCE_ZONE, autodelete_instance_name
+ )
assert instance.name == autodelete_instance_name
assert (
diff --git a/samples/snippets/test_sample_preemptible.py b/samples/snippets/tests/test_preemptible.py
similarity index 85%
rename from samples/snippets/test_sample_preemptible.py
rename to samples/snippets/tests/test_preemptible.py
index 047a721e3..06c509279 100644
--- a/samples/snippets/test_sample_preemptible.py
+++ b/samples/snippets/tests/test_preemptible.py
@@ -16,10 +16,10 @@
import google.auth
import pytest
-from quickstart import delete_instance
-from sample_preemptible import create_preemptible_instance
-from sample_preemptible import is_preemptible
-from sample_preemptible import list_zone_operations
+from ..instances.delete import delete_instance
+from ..instances.preemptible.create_preemptible import create_preemptible_instance
+from ..instances.preemptible.is_preemptible import is_preemptible
+from ..instances.preemptible.preemption_history import list_zone_operations
PROJECT = google.auth.default()[1]
INSTANCE_ZONE = "europe-central2-c"
diff --git a/samples/snippets/test_sample_create_vm.py b/samples/snippets/tests/test_sample_create_vm.py
similarity index 72%
rename from samples/snippets/test_sample_create_vm.py
rename to samples/snippets/tests/test_sample_create_vm.py
index 3e3189d90..b08617f6e 100644
--- a/samples/snippets/test_sample_create_vm.py
+++ b/samples/snippets/tests/test_sample_create_vm.py
@@ -1,32 +1,38 @@
-# Copyright 2021 Google LLC
+# Copyright 2022 Google LLC
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
import uuid
import google.auth
from google.cloud import compute_v1
import pytest
-from quickstart import delete_instance, wait_for_operation
-
-from sample_create_vm import (
+from ..instances.create_start_instance.create_from_custom_image import (
create_from_custom_image,
+)
+from ..instances.create_start_instance.create_from_public_image import (
create_from_public_image,
- create_from_snapshot,
+)
+from ..instances.create_start_instance.create_from_snapshot import create_from_snapshot
+from ..instances.create_start_instance.create_with_additional_disk import (
create_with_additional_disk,
+)
+from ..instances.create_start_instance.create_with_snapshotted_data_disk import (
create_with_snapshotted_data_disk,
- create_with_subnet,
)
+from ..instances.create_with_subnet import create_with_subnet
+from ..instances.delete import delete_instance
+from ..operations.operation_check import wait_for_operation
PROJECT = google.auth.default()[1]
REGION = "us-central1"
@@ -39,8 +45,8 @@ def get_active_debian():
return image_client.get_from_family(project="debian-cloud", family="debian-11")
-@pytest.fixture(scope="class")
-def src_disk(request):
+@pytest.fixture()
+def src_disk():
disk_client = compute_v1.DisksClient()
disk = compute_v1.Disk()
@@ -53,7 +59,6 @@ def src_disk(request):
wait_for_operation(op, PROJECT)
try:
disk = disk_client.get(project=PROJECT, zone=INSTANCE_ZONE, disk=disk.name)
- request.cls.disk = disk
yield disk
finally:
op = disk_client.delete_unary(
@@ -62,8 +67,8 @@ def src_disk(request):
wait_for_operation(op, PROJECT)
-@pytest.fixture(scope="class")
-def snapshot(request, src_disk):
+@pytest.fixture()
+def snapshot(src_disk):
snapshot_client = compute_v1.SnapshotsClient()
snapshot = compute_v1.Snapshot()
snapshot.name = "test-snap-" + uuid.uuid4().hex[:10]
@@ -76,10 +81,9 @@ def snapshot(request, src_disk):
)
wait_for_operation(op, PROJECT)
try:
- request.cls.snapshot = snapshot_client.get(
+ snapshot = snapshot_client.get(
project=PROJECT, snapshot=snapshot.name
)
- snapshot = request.cls.snapshot
yield snapshot
finally:
@@ -87,8 +91,8 @@ def snapshot(request, src_disk):
wait_for_operation(op, PROJECT)
-@pytest.fixture(scope="class")
-def image(request, src_disk):
+@pytest.fixture()
+def image(src_disk):
image_client = compute_v1.ImagesClient()
image = compute_v1.Image()
image.source_disk = src_disk.self_link
@@ -98,45 +102,47 @@ def image(request, src_disk):
wait_for_operation(op, PROJECT)
try:
image = image_client.get(project=PROJECT, image=image.name)
- request.cls.image = image
yield image
finally:
op = image_client.delete_unary(project=PROJECT, image=image.name)
wait_for_operation(op, PROJECT)
-@pytest.mark.usefixtures("image", "snapshot")
class TestCreation:
- def test_create_from_custom_image(self):
+ def test_create_from_custom_image(self, image):
instance_name = "i" + uuid.uuid4().hex[:10]
instance = create_from_custom_image(
- PROJECT, INSTANCE_ZONE, instance_name, self.image.self_link
+ PROJECT, INSTANCE_ZONE, instance_name, image.self_link
)
try:
assert (
- instance.disks[0].initialize_params.source_image == self.image.self_link
+ instance.disks[0].initialize_params.source_image == image.self_link
)
finally:
delete_instance(PROJECT, INSTANCE_ZONE, instance_name)
def test_create_from_public_image(self):
instance_name = "i" + uuid.uuid4().hex[:10]
- instance = create_from_public_image(PROJECT, INSTANCE_ZONE, instance_name,)
+ instance = create_from_public_image(
+ PROJECT,
+ INSTANCE_ZONE,
+ instance_name,
+ )
try:
assert "debian-cloud" in instance.disks[0].initialize_params.source_image
assert "debian-10" in instance.disks[0].initialize_params.source_image
finally:
delete_instance(PROJECT, INSTANCE_ZONE, instance_name)
- def test_create_from_snapshot(self):
+ def test_create_from_snapshot(self, snapshot):
instance_name = "i" + uuid.uuid4().hex[:10]
instance = create_from_snapshot(
- PROJECT, INSTANCE_ZONE, instance_name, self.snapshot.self_link
+ PROJECT, INSTANCE_ZONE, instance_name, snapshot.self_link
)
try:
assert (
instance.disks[0].initialize_params.source_snapshot
- == self.snapshot.self_link
+ == snapshot.self_link
)
finally:
delete_instance(PROJECT, INSTANCE_ZONE, instance_name)
@@ -155,10 +161,10 @@ def test_create_with_additional_disk(self):
finally:
delete_instance(PROJECT, INSTANCE_ZONE, instance_name)
- def test_create_with_snapshotted_data_disk(self):
+ def test_create_with_snapshotted_data_disk(self, snapshot):
instance_name = "i" + uuid.uuid4().hex[:10]
instance = create_with_snapshotted_data_disk(
- PROJECT, INSTANCE_ZONE, instance_name, self.snapshot.self_link
+ PROJECT, INSTANCE_ZONE, instance_name, snapshot.self_link
)
try:
assert any(
diff --git a/samples/snippets/test_sample_custom_types.py b/samples/snippets/tests/test_sample_custom_types.py
similarity index 84%
rename from samples/snippets/test_sample_custom_types.py
rename to samples/snippets/tests/test_sample_custom_types.py
index 812b04b50..4b7c8108c 100644
--- a/samples/snippets/test_sample_custom_types.py
+++ b/samples/snippets/tests/test_sample_custom_types.py
@@ -16,13 +16,18 @@
import google.auth
import pytest
-from quickstart import create_instance, delete_instance
-from sample_custom_types import (
- add_extended_memory_to_instance,
- create_custom_instance,
+from ..images.get import get_image_from_family
+from ..instances.create import create_instance
+from ..instances.create_start_instance.create_from_public_image import disk_from_image
+from ..instances.custom_machine_types.create_shared_with_helper import (
create_custom_shared_core_instance,
- CustomMachineType,
)
+from ..instances.custom_machine_types.create_with_helper import create_custom_instance
+from ..instances.custom_machine_types.helper_class import CustomMachineType
+from ..instances.custom_machine_types.update_memory import (
+ add_extended_memory_to_instance,
+)
+from ..instances.delete import delete_instance
PROJECT = google.auth.default()[1]
REGION = "us-central1"
@@ -39,14 +44,22 @@ def auto_delete_instance_name():
@pytest.fixture
def instance():
instance_name = "test-instance-" + uuid.uuid4().hex[:10]
+
+ newest_debian = get_image_from_family(project="debian-cloud", family="debian-10")
+ disk_type = f"zones/{INSTANCE_ZONE}/diskTypes/pd-standard"
+ disks = [disk_from_image(disk_type, 10, True, newest_debian.self_link)]
+
instance = create_instance(
- PROJECT, INSTANCE_ZONE, instance_name, "n2-custom-8-10240"
+ PROJECT, INSTANCE_ZONE, instance_name, disks, "n2-custom-8-10240"
)
yield instance
delete_instance(PROJECT, INSTANCE_ZONE, instance_name)
def test_custom_instance_creation(auto_delete_instance_name):
+ # Need to import CustomMachineType from this module, or the assertion will fail
+ from ..instances.custom_machine_types.create_with_helper import CustomMachineType
+
instance = create_custom_instance(
PROJECT,
INSTANCE_ZONE,
@@ -63,6 +76,11 @@ def test_custom_instance_creation(auto_delete_instance_name):
def test_custom_shared_instance_creation(auto_delete_instance_name):
+ # Need to import CustomMachineType from this module, or the assertion will fail
+ from ..instances.custom_machine_types.create_shared_with_helper import (
+ CustomMachineType,
+ )
+
instance = create_custom_shared_core_instance(
PROJECT,
INSTANCE_ZONE,
diff --git a/samples/snippets/test_sample_default_values.py b/samples/snippets/tests/test_sample_default_values.py
similarity index 93%
rename from samples/snippets/test_sample_default_values.py
rename to samples/snippets/tests/test_sample_default_values.py
index 23182e077..f609b3dd5 100644
--- a/samples/snippets/test_sample_default_values.py
+++ b/samples/snippets/tests/test_sample_default_values.py
@@ -20,11 +20,9 @@
import google.cloud.storage as storage
import pytest
-from sample_default_values import (
- disable_usage_export,
- get_usage_export_bucket,
- set_usage_export_bucket,
-)
+from ..usage_report.usage_reports import disable_usage_export
+from ..usage_report.usage_reports import get_usage_export_bucket
+from ..usage_report.usage_reports import set_usage_export_bucket
PROJECT = google.auth.default()[1]
BUCKET_NAME = "test" + uuid.uuid4().hex[:10]
diff --git a/samples/snippets/test_sample_firewall.py b/samples/snippets/tests/test_sample_firewall.py
similarity index 94%
rename from samples/snippets/test_sample_firewall.py
rename to samples/snippets/tests/test_sample_firewall.py
index 517174395..86f978675 100644
--- a/samples/snippets/test_sample_firewall.py
+++ b/samples/snippets/tests/test_sample_firewall.py
@@ -19,13 +19,10 @@
from google.cloud import compute_v1
import pytest
-
-from sample_firewall import (
- create_firewall_rule,
- delete_firewall_rule,
- get_firewall_rule,
- patch_firewall_priority,
-)
+from ..firewall.create import create_firewall_rule
+from ..firewall.delete import delete_firewall_rule
+from ..firewall.main import get_firewall_rule
+from ..firewall.patch import patch_firewall_priority
PROJECT = google.auth.default()[1]
diff --git a/samples/snippets/test_sample_images.py b/samples/snippets/tests/test_sample_images.py
similarity index 93%
rename from samples/snippets/test_sample_images.py
rename to samples/snippets/tests/test_sample_images.py
index 23346c1f8..18852ac09 100644
--- a/samples/snippets/test_sample_images.py
+++ b/samples/snippets/tests/test_sample_images.py
@@ -12,7 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from sample_images import get_image, list_images
+from ..images.get import get_image
+from ..images.list import list_images
def test_list_images():
diff --git a/samples/snippets/test_sample_instance_from_template.py b/samples/snippets/tests/test_sample_instance_from_template.py
similarity index 94%
rename from samples/snippets/test_sample_instance_from_template.py
rename to samples/snippets/tests/test_sample_instance_from_template.py
index c6a2f0f62..e32208258 100644
--- a/samples/snippets/test_sample_instance_from_template.py
+++ b/samples/snippets/tests/test_sample_instance_from_template.py
@@ -17,13 +17,14 @@
from google.cloud import compute_v1
import pytest
-from quickstart import delete_instance
-from sample_instance_from_template import (
+from ..instances.delete import delete_instance
+from ..instances.from_instance_template.create_from_template import (
create_instance_from_template,
+)
+from ..instances.from_instance_template.create_from_template_with_overrides import (
create_instance_from_template_with_overrides,
)
-
PROJECT = google.auth.default()[1]
INSTANCE_ZONE = "europe-north1-c"
diff --git a/samples/snippets/test_sample_pagination.py b/samples/snippets/tests/test_sample_pagination.py
similarity index 66%
rename from samples/snippets/test_sample_pagination.py
rename to samples/snippets/tests/test_sample_pagination.py
index 77672ba50..41e06703d 100644
--- a/samples/snippets/test_sample_pagination.py
+++ b/samples/snippets/tests/test_sample_pagination.py
@@ -11,20 +11,17 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-import typing
-
-from sample_pagination import print_images_list, print_images_list_by_page
+from ..images.pagination import print_images_list
+from ..images.pagination import print_images_list_by_page
PROJECT = "windows-sql-cloud"
-def test_pagination(capsys: typing.Any) -> None:
- print_images_list(PROJECT)
- out, _ = capsys.readouterr()
+def test_pagination() -> None:
+ out = print_images_list(PROJECT)
assert len(out.splitlines()) > 2
-def test_pagination_page(capsys: typing.Any) -> None:
- print_images_list_by_page(PROJECT, 2)
- out, _ = capsys.readouterr()
+def test_pagination_page() -> None:
+ out = print_images_list_by_page(PROJECT, 2)
assert "Page 2" in out
diff --git a/samples/snippets/test_sample_start_stop.py b/samples/snippets/tests/test_sample_start_stop.py
similarity index 97%
rename from samples/snippets/test_sample_start_stop.py
rename to samples/snippets/tests/test_sample_start_stop.py
index bcf249f22..737400f8a 100644
--- a/samples/snippets/test_sample_start_stop.py
+++ b/samples/snippets/tests/test_sample_start_stop.py
@@ -19,14 +19,11 @@
import google.auth
from google.cloud import compute_v1
-
import pytest
-from sample_start_stop import (
- start_instance,
- start_instance_with_encryption_key,
- stop_instance,
-)
+from ..instances.start import start_instance
+from ..instances.start_encrypted import start_instance_with_encryption_key
+from ..instances.stop import stop_instance
PROJECT = google.auth.default()[1]
diff --git a/samples/snippets/test_sample_templates.py b/samples/snippets/tests/test_sample_templates.py
similarity index 88%
rename from samples/snippets/test_sample_templates.py
rename to samples/snippets/tests/test_sample_templates.py
index 2c60aaafb..624a6f017 100644
--- a/samples/snippets/test_sample_templates.py
+++ b/samples/snippets/tests/test_sample_templates.py
@@ -17,17 +17,16 @@
import google.auth
import pytest
-from sample_templates import (
- create_template,
- create_template_from_instance,
- create_template_with_subnet,
- delete_instance_template,
- list_instance_templates,
-)
-
# Turning off F401 check because flake8 doesn't recognize using
# PyTest fixture as parameter as usage.
-from test_sample_start_stop import compute_instance # noqa: F401
+from .test_sample_start_stop import compute_instance # noqa: F401
+
+from ..instance_templates.create import create_template
+from ..instance_templates.create_from_instance import \
+ create_template_from_instance
+from ..instance_templates.create_with_subnet import create_template_with_subnet
+from ..instance_templates.delete import delete_instance_template
+from ..instance_templates.list import list_instance_templates
PROJECT = google.auth.default()[1]
diff --git a/samples/snippets/usage_report/__init__.py b/samples/snippets/usage_report/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/samples/snippets/sample_default_values.py b/samples/snippets/usage_report/usage_reports.py
similarity index 81%
rename from samples/snippets/sample_default_values.py
rename to samples/snippets/usage_report/usage_reports.py
index 351487952..54af6034b 100644
--- a/samples/snippets/sample_default_values.py
+++ b/samples/snippets/usage_report/usage_reports.py
@@ -1,28 +1,34 @@
-#!/usr/bin/env python
-
-# Copyright 2021 Google LLC
+# Copyright 2022 Google LLC
#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# flake8: noqa
"""
A sample script showing how to handle default values when communicating
with the Compute Engine API.
"""
+
+# This file is automatically generated. Please do not modify it directly.
+# Find the relevant recipe file in the samples/recipes or samples/ingredients
+# directory and apply your changes there.
+
+
# [START compute_instances_verify_default_value]
# [START compute_usage_report_set]
# [START compute_usage_report_get]
# [START compute_usage_report_disable]
from google.cloud import compute_v1
+
# [END compute_usage_report_disable]
# [END compute_usage_report_get]
# [END compute_usage_report_set]
@@ -44,9 +50,9 @@ def set_usage_export_bucket(
report_name_prefix: Prefix of the usage report name which defaults to an empty string
to showcase default values behaviour.
"""
- usage_export_location = compute_v1.UsageExportLocation(
- bucket_name=bucket_name, report_name_prefix=report_name_prefix
- )
+ usage_export_location = compute_v1.UsageExportLocation()
+ usage_export_location.bucket_name = bucket_name
+ usage_export_location.report_name_prefix = report_name_prefix
if not report_name_prefix:
# Sending an empty value for report_name_prefix results in the
@@ -70,7 +76,6 @@ def set_usage_export_bucket(
# [END compute_usage_report_set]
-
# [START compute_usage_report_get]
def get_usage_export_bucket(project_id: str) -> compute_v1.UsageExportLocation:
"""
diff --git a/samples/test_sgs.py b/samples/test_sgs.py
index f1c1d71ae..dcc030a17 100644
--- a/samples/test_sgs.py
+++ b/samples/test_sgs.py
@@ -16,7 +16,7 @@
from pathlib import Path
import tempfile
-import sgs
+from . import sgs
FIXTURE_INGREDIENTS = Path("sgs_test_fixtures/ingredients")
FIXTURE_RECIPES = Path("sgs_test_fixtures/recipes")
@@ -26,7 +26,7 @@
def test_sgs_generate():
with tempfile.TemporaryDirectory() as tmp_dir:
args = Namespace(output_dir=tmp_dir)
- sgs.generate(args, FIXTURE_INGREDIENTS, FIXTURE_RECIPES)
+ sgs.generate(args, FIXTURE_INGREDIENTS.absolute(), FIXTURE_RECIPES.absolute())
for test_file in map(Path, glob.glob(f"{tmp_dir}/**")):
match_file = FIXTURE_OUTPUT / test_file.relative_to(tmp_dir)
assert test_file.read_bytes() == match_file.read_bytes()