Skip to content

Commit

Permalink
feat(oracle): Add vcn_name as a configuration option through the toml…
Browse files Browse the repository at this point in the history
… file

When there are multiple virtual cloud networks (VCNs) available on an Oracle compartment,
pycloudlib will use the newest VCN available, which might not be desired. Currently, the
VCN selection functionality is present within the cloud class level, however it cannot be
set through the config file. This patch modifies the `pycloudlib/oci/cloud.py` file to
retrieve the `vcn_name` key from config and use it to force a VCN to use. A commented entry
is also included in the `pycloudlib.toml.template` for reference.
  • Loading branch information
Bryzizzle committed Dec 12, 2024
1 parent 72ebfce commit cf53c36
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 29 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1!10.6.1
1!10.6.2
1 change: 1 addition & 0 deletions pycloudlib.toml.template
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ availability_domain = "" # Likely in ~/.oci/oci_cli_rc
compartment_id = "" # Likely in ~/.oci/oci_cli_rc
# region = "us-phoenix-1" # will use region from oci config file if not specified
# profile = "DEFAULT" # will use default profile from oci config file if not specified
# vcn_name = "" # Exact name of the VCN to use. If not provided, the newest VCN in the given compartment will be used.
# public_key_path = "~/.ssh/id_rsa.pub"
# private_key_path = "" # Defaults to 'public_key_path' without the '.pub'
# key_name = "" # Defaults to your username if not set
Expand Down
4 changes: 2 additions & 2 deletions pycloudlib/oci/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def __init__(
tag,
timestamp_suffix,
config_file,
required_values=[availability_domain, compartment_id],
required_values=[availability_domain, compartment_id, vcn_name],
)

self.availability_domain = availability_domain or self.config["availability_domain"]
Expand Down Expand Up @@ -114,7 +114,7 @@ def __init__(
self.oci_config["region"] = region or self.config.get("region") or self.oci_config["region"]
self.region = self.oci_config["region"]

self.vcn_name = vcn_name
self.vcn_name = vcn_name or self.config.get("vcn_name")
self.fault_domain = fault_domain
self._log.debug("Logging into OCI")
self.compute_client = oci.core.ComputeClient(self.oci_config) # noqa: E501
Expand Down
95 changes: 69 additions & 26 deletions tests/unit_tests/oci/test_cloud.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Tests for pycloudlib's OCI Cloud class."""

from textwrap import dedent
from typing import List
from unittest import mock

Expand All @@ -15,25 +16,15 @@
from pycloudlib.oci.cloud import OCI
from pycloudlib.oci.instance import OciInstance


@pytest.fixture
def oci_cloud(tmp_path):
"""
Fixture for OCI Cloud class.
This fixture mocks the oci.config.validate_config function to not raise an error. It also
mocks the oci.core.ComputeClient and oci.core.VirtualNetworkClient classes to return mock
instances of the clients.
"""
def oci_mock():
oci_config = {
"user": "ocid1.user.oc1..example",
"fingerprint": "mock-fingerprint",
"key_file": "/path/to/key",
"tenancy": "ocid1.tenancy.oc1..example",
"region": "us-phoenix-1",
}
pycloudlib_config = tmp_path / "pyproject.toml"
pycloudlib_config.write_text("[oci]\n")

with mock.patch(
"pycloudlib.oci.cloud.oci.config.validate_config",
Expand All @@ -49,24 +40,40 @@ def oci_cloud(tmp_path):
mock_compute_client_class.return_value = mock_compute_client
mock_network_client_class.return_value = mock_network_client

# Create instance
oci_cloud = OCI(
"test-instance",
timestamp_suffix=True,
config_file=pycloudlib_config,
availability_domain="PHX-AD-1",
compartment_id="test-compartment-id",
region="us-phoenix-1",
config_dict=oci_config,
)
yield mock_compute_client, mock_network_client, oci_config

@pytest.fixture
def oci_cloud(oci_mock, tmp_path):
"""
Fixture for OCI Cloud class.
This fixture mocks the oci.config.validate_config function to not raise an error. It also
mocks the oci.core.ComputeClient and oci.core.VirtualNetworkClient classes to return mock
instances of the clients.
"""
pycloudlib_config = tmp_path / "pyproject.toml"
pycloudlib_config.write_text("[oci]\n")

mock_compute_client, mock_network_client, oci_config = oci_mock

# Create instance
oci_cloud = OCI(
"test-instance",
timestamp_suffix=True,
config_file=pycloudlib_config,
availability_domain="PHX-AD-1",
compartment_id="test-compartment-id",
region="us-phoenix-1",
config_dict=oci_config,
)

oci_cloud._log = mock.MagicMock()
oci_cloud._log = mock.MagicMock()

# Assign the mocked clients to the instance
oci_cloud.compute_client = mock_compute_client
oci_cloud.network_client = mock_network_client
# Assign the mocked clients to the instance
oci_cloud.compute_client = mock_compute_client
oci_cloud.network_client = mock_network_client

yield oci_cloud
yield oci_cloud


OCI_PYCLOUDLIB_CONFIG = """\
Expand Down Expand Up @@ -99,6 +106,42 @@ def test_init_invalid_config(self, tmp_path):
config_dict={"invalid": "config"},
)

@pytest.mark.parametrize(
["vcn_name"],
[
pytest.param(
"test-vcn",
id="VCN entry provided",
),
pytest.param(
None,
id="No VCN entry provided",
),
],
)
def test_config_toml(self, tmp_path, vcn_name):
config_toml = dedent("""\
[oci]
availability_domain = "PYCL-AD-1"
compartment_id = "pycloudlib-compartment-id"
region = "pycl-pheonix-1"
""")

if vcn_name:
config_toml += 'vcn_name = "test-vcn"\n'

pycloudlib_config = tmp_path / "pyproject.toml"
pycloudlib_config.write_text(config_toml)

test_inst = OCI(
tag="test-instance",
config_file=pycloudlib_config,
)

assert test_inst.availability_domain == "PYCL-AD-1"
assert test_inst.compartment_id == "pycloudlib-compartment-id"
assert test_inst.region == "pycl-pheonix-1"
assert test_inst.vcn_name == vcn_name

@pytest.mark.mock_ssh_keys
class TestOciImages:
Expand Down

0 comments on commit cf53c36

Please sign in to comment.