From 483c26b79784a3932744b3392574660449b35e53 Mon Sep 17 00:00:00 2001 From: uhryniuk Date: Tue, 25 Feb 2025 12:55:57 -0600 Subject: [PATCH] feat(oracle): specify which subnet an instance must use --- VERSION | 2 +- pycloudlib/oci/cloud.py | 25 ++++++++++++++++++------- tests/unit_tests/oci/test_cloud.py | 10 +++++++++- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/VERSION b/VERSION index 5a192aad..46e08828 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1!10.8.1 +1!10.9.0 diff --git a/pycloudlib/oci/cloud.py b/pycloudlib/oci/cloud.py index 02638fa7..76c1df83 100644 --- a/pycloudlib/oci/cloud.py +++ b/pycloudlib/oci/cloud.py @@ -19,7 +19,12 @@ PycloudlibException, ) from pycloudlib.oci.instance import OciInstance -from pycloudlib.oci.utils import get_subnet_id, parse_oci_config_from_env_vars, wait_till_ready +from pycloudlib.oci.utils import ( + get_subnet_id, + get_subnet_id_by_name, + parse_oci_config_from_env_vars, + wait_till_ready, +) from pycloudlib.util import UBUNTU_RELEASE_VERSION_MAP, subp @@ -257,6 +262,7 @@ def launch( retry_strategy=None, username: Optional[str] = None, cluster_id: Optional[str] = None, + subnet_name: Optional[str] = None, **kwargs, ) -> OciInstance: """Launch an instance. @@ -267,6 +273,7 @@ def launch( https://docs.cloud.oracle.com/en-us/iaas/Content/Compute/References/computeshapes.htm user_data: used by Cloud-Init to run custom scripts or provide custom Cloud-Init configuration + subnet_name: string, name of subnet to use for instance. retry_strategy: a retry strategy from oci.retry module to apply for this operation username: username to use when connecting via SSH @@ -281,12 +288,16 @@ def launch( """ if not image_id: raise ValueError(f"{self._type} launch requires image_id param. Found: {image_id}") - subnet_id = get_subnet_id( - self.network_client, - self.compartment_id, - self.availability_domain, - vcn_name=self.vcn_name, - ) + + if subnet_name: + subnet_id = get_subnet_id_by_name(self.network_client, self.compartment_id, subnet_name) + else: + subnet_id = get_subnet_id( + self.network_client, + self.compartment_id, + self.availability_domain, + vcn_name=self.vcn_name, + ) metadata = { "ssh_authorized_keys": self.key_pair.public_key_content, } diff --git a/tests/unit_tests/oci/test_cloud.py b/tests/unit_tests/oci/test_cloud.py index 46231d34..c26f2855 100644 --- a/tests/unit_tests/oci/test_cloud.py +++ b/tests/unit_tests/oci/test_cloud.py @@ -263,8 +263,10 @@ def test_get_instance_not_found(self, oci_cloud): oci_cloud.get_instance("test-instance-id") @mock.patch("pycloudlib.oci.cloud.wait_till_ready") - def test_launch_instance(self, mock_wait_till_ready, oci_cloud): + def test_launch_instance(self, mock_wait_till_ready, oci_cloud, oci_mock): """Test launch method with valid inputs.""" + _, mock_network_client, _ = oci_mock + # mock the key pair oci_cloud.key_pair = mock.Mock(public_key_config="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC") oci_cloud.compute_client.launch_instance.return_value = mock.Mock( @@ -279,6 +281,12 @@ def test_launch_instance(self, mock_wait_till_ready, oci_cloud): assert instance is not None m_subnet.assert_called_once() oci_cloud.get_instance.assert_called_once() + + # assert that subnet_name is obtained properly + mock_network_client.list_subnets.return_value = mock.Mock(data=[mock.Mock(id="subnet-id")]) + instance = oci_cloud.launch("test-image-id", instance_type="VM.Standard2.1", subnet_name="subnet-name") + mock_network_client.list_subnets.assert_called_once() + assert oci_cloud.get_instance.call_count == 2 def test_launch_instance_invalid_image(self, oci_cloud): """Test launch method raises ValueError when no image_id is provided."""