Skip to content

Commit

Permalink
fix: Use service name instead of IP in URL (#133)
Browse files Browse the repository at this point in the history
  • Loading branch information
ghislainbourgeois authored Apr 4, 2024
1 parent a3da117 commit 16b6b23
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 94 deletions.
32 changes: 6 additions & 26 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
"""Charmed operator for the SD-Core NRF service for K8s."""

import logging
from ipaddress import IPv4Address
from subprocess import check_output
from typing import Optional

from charms.data_platform_libs.v0.data_interfaces import DatabaseRequires # type: ignore[import]
from charms.loki_k8s.v1.loki_push_api import LogForwarder
Expand Down Expand Up @@ -48,20 +45,10 @@
LOGGING_RELATION_NAME = "logging"


def _get_pod_ip() -> Optional[str]:
"""Return the pod IP using juju client.
Returns:
str: The pod IP.
"""
ip_address = check_output(["unit-get", "private-address"])
return str(IPv4Address(ip_address.decode().strip())) if ip_address else None


def _render_config(
database_name: str,
database_url: str,
nrf_ip: str,
nrf_host: str,
nrf_sbi_port: int,
scheme: str,
) -> str:
Expand All @@ -70,7 +57,7 @@ def _render_config(
Args:
database_name: Name of the database
database_url: URL of the database
nrf_ip: IP of the NRF service
nrf_host: Hostname or IP of the NRF service
nrf_sbi_port: Port of the NRF service
scheme: SBI interface scheme ("http" or "https")
Expand All @@ -83,7 +70,7 @@ def _render_config(
database_name=database_name,
database_url=database_url,
nrf_sbi_port=nrf_sbi_port,
nrf_ip=nrf_ip,
nrf_ip=nrf_host,
scheme=scheme,
)
return content
Expand Down Expand Up @@ -137,8 +124,6 @@ def ready_to_configure(self) -> bool:
path=CERTS_DIR_PATH
):
return False
if not _get_pod_ip():
return False
return True

def _on_collect_unit_status(self, event: CollectStatusEvent): # noqa C901
Expand Down Expand Up @@ -179,10 +164,6 @@ def _on_collect_unit_status(self, event: CollectStatusEvent): # noqa C901
event.add_status(WaitingStatus("Waiting for storage to be attached"))
logger.info("Waiting for storage to be attached")
return
if not _get_pod_ip():
event.add_status(WaitingStatus("Waiting for pod IP address to be available"))
logger.info("Waiting for pod IP address to be available")
return
if self._csr_is_stored() and not self._get_current_provider_certificate():
event.add_status(WaitingStatus("Waiting for certificates to be stored"))
logger.info("Waiting for certificates to be stored")
Expand Down Expand Up @@ -356,7 +337,7 @@ def _generate_nrf_config_file(self) -> str:
"""
return _render_config(
database_url=self._database_info()["uris"].split(",")[0],
nrf_ip=_get_pod_ip(), # type: ignore[arg-type]
nrf_host=self.model.app.name,
database_name=DATABASE_NAME,
nrf_sbi_port=NRF_SBI_PORT,
scheme="https",
Expand Down Expand Up @@ -529,10 +510,9 @@ def _nrf_service_is_running(self) -> bool:
return False
return service.is_running()

@staticmethod
def _get_nrf_url() -> str:
def _get_nrf_url(self) -> str:
"""Return NRF URL."""
return f"https://nrf:{NRF_SBI_PORT}"
return f"https://{self.model.app.name}:{NRF_SBI_PORT}"


if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/expected_config/config.conf
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ configuration:
sbi:
bindingIPv4: 0.0.0.0
port: 29510
registerIPv4: 1.1.1.1
registerIPv4: sdcore-nrf-k8s
scheme: https
serviceNameList:
- nnrf-nfm
Expand Down
71 changes: 4 additions & 67 deletions tests/unit/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,14 @@ def test_given_certificates_relation_not_created_when_pebble_ready_then_status_i
BlockedStatus(f"Waiting for {TLS_RELATION_NAME} relation to be created"),
)

@patch("charm.check_output")
def test_given_nrf_charm_in_active_state_when_database_relation_breaks_then_status_is_blocked(
self,
patch_check_output,
):
self.harness.add_storage("config", attach=True)
self.harness.add_storage("certs", attach=True)
certificate = "Whatever certificate content"
root = self.harness.get_filesystem_root("nrf")
(root / "support/TLS/nrf.pem").write_text(certificate)
patch_check_output.return_value = b"1.1.1.1"
database_relation_id = self._create_database_relation_and_populate_data()
self.harness.add_relation(relation_name=TLS_RELATION_NAME, remote_app=TLS_APPLICATION_NAME)
self.harness.container_pebble_ready(container_name="nrf")
Expand Down Expand Up @@ -155,18 +152,16 @@ def test_given_storage_not_attached_when_pebble_ready_then_status_is_waiting(
)

@patch("charm.generate_csr")
@patch("charm.check_output")
@patch("charm.generate_private_key")
def test_given_certificates_not_stored_when_pebble_ready_then_status_is_waiting(
self, patch_generate_private_key, patch_check_output, patch_generate_csr
self, patch_generate_private_key, patch_generate_csr
):
self.harness.add_storage("config", attach=True)
self.harness.add_storage("certs", attach=True)
private_key = b"whatever key content"
patch_generate_private_key.return_value = private_key
csr = b"whatever csr content"
patch_generate_csr.return_value = csr
patch_check_output.return_value = b"1.1.1.1"
self.harness.set_can_connect(container="nrf", val=True)
self._create_database_relation_and_populate_data()
self.harness.add_relation(relation_name=TLS_RELATION_NAME, remote_app=TLS_APPLICATION_NAME)
Expand All @@ -181,12 +176,10 @@ def test_given_certificates_not_stored_when_pebble_ready_then_status_is_waiting(
"charms.tls_certificates_interface.v3.tls_certificates.TLSCertificatesRequiresV3.get_assigned_certificates", # noqa: E501
)
@patch("charm.generate_csr")
@patch("charm.check_output")
@patch("charm.generate_private_key")
def test_given_database_info_and_storage_attached_and_certs_stored_when_pebble_ready_then_config_file_is_rendered_and_pushed( # noqa: E501
self,
patch_generate_private_key,
patch_check_output,
patch_generate_csr,
patch_get_assigned_certificates,
):
Expand All @@ -195,7 +188,6 @@ def test_given_database_info_and_storage_attached_and_certs_stored_when_pebble_r
root = self.harness.get_filesystem_root("nrf")
private_key = b"whatever key content"
patch_generate_private_key.return_value = private_key
patch_check_output.return_value = b"1.1.1.1"
certificate = "Whatever certificate content"
csr = b"whatever csr content"
patch_generate_csr.return_value = csr
Expand All @@ -219,10 +211,8 @@ def test_given_database_info_and_storage_attached_and_certs_stored_when_pebble_r
(root / f"etc/nrf/{CONFIG_FILE_NAME}").read_text(), expected_content.strip()
)

@patch("charm.check_output")
def test_given_content_of_config_file_not_changed_when_pebble_ready_then_config_file_is_not_pushed( # noqa: E501
self,
patch_check_output,
):
self.harness.add_storage("config", attach=True)
self.harness.add_storage("certs", attach=True)
Expand All @@ -233,7 +223,6 @@ def test_given_content_of_config_file_not_changed_when_pebble_ready_then_config_
self._read_file("tests/unit/expected_config/config.conf").strip()
)
config_modification_time = (root / f"etc/nrf/{CONFIG_FILE_NAME}").stat().st_mtime
patch_check_output.return_value = b"1.1.1.1"
self.harness.set_can_connect(container="nrf", val=True)
self._create_database_relation_and_populate_data()
self.harness.container_pebble_ready(container_name="nrf")
Expand All @@ -245,12 +234,10 @@ def test_given_content_of_config_file_not_changed_when_pebble_ready_then_config_
"charms.tls_certificates_interface.v3.tls_certificates.TLSCertificatesRequiresV3.get_assigned_certificates", # noqa: E501
)
@patch("charm.generate_csr")
@patch("charm.check_output")
@patch("charm.generate_private_key")
def test_given_config_pushed_when_pebble_ready_then_pebble_plan_is_applied(
self,
patch_generate_private_key,
patch_check_output,
patch_generate_csr,
patch_get_assigned_certificates,
):
Expand All @@ -259,7 +246,6 @@ def test_given_config_pushed_when_pebble_ready_then_pebble_plan_is_applied(
root = self.harness.get_filesystem_root("nrf")
private_key = b"whatever key content"
patch_generate_private_key.return_value = private_key
patch_check_output.return_value = b"1.1.1.1"
certificate = "Whatever certificate content"
csr = b"whatever csr content"
patch_generate_csr.return_value = csr
Expand Down Expand Up @@ -305,12 +291,10 @@ def test_given_config_pushed_when_pebble_ready_then_pebble_plan_is_applied(
"charms.tls_certificates_interface.v3.tls_certificates.TLSCertificatesRequiresV3.get_assigned_certificates", # noqa: E501
)
@patch("charm.generate_csr")
@patch("charm.check_output")
@patch("charm.generate_private_key")
def test_given_database_relation_is_created_and_config_file_is_written_when_pebble_ready_then_status_is_active( # noqa: E501
self,
patch_generate_private_key,
patch_check_output,
patch_generate_csr,
patch_get_assigned_certificates,
):
Expand All @@ -319,7 +303,6 @@ def test_given_database_relation_is_created_and_config_file_is_written_when_pebb
root = self.harness.get_filesystem_root("nrf")
private_key = b"whatever key content"
patch_generate_private_key.return_value = private_key
patch_check_output.return_value = b"1.1.1.1"
certificate = "Whatever certificate content"
csr = b"whatever csr content"
patch_generate_csr.return_value = csr
Expand All @@ -344,43 +327,13 @@ def test_given_database_relation_is_created_and_config_file_is_written_when_pebb

self.assertEqual(self.harness.model.unit.status, ActiveStatus())

@patch("charm.check_output")
def test_given_ip_not_available_when_pebble_ready_then_status_is_waiting(
self,
patch_check_output,
):
patch_check_output.return_value = b""
self.harness.add_storage("config", attach=True)
self.harness.add_storage("certs", attach=True)
certificate = "Whatever certificate content"
root = self.harness.get_filesystem_root("nrf")
(root / "support/TLS/nrf.pem").write_text(certificate)
(root / f"etc/nrf/{CONFIG_FILE_NAME}").write_text(
self._read_file("tests/unit/expected_config/config.conf").strip()
)

self.harness.set_can_connect(container="nrf", val=True)

self._create_database_relation_and_populate_data()
self.harness.add_relation(relation_name=TLS_RELATION_NAME, remote_app=TLS_APPLICATION_NAME)

self.harness.container_pebble_ready("nrf")
self.harness.evaluate_status()

self.assertEqual(
self.harness.model.unit.status,
WaitingStatus("Waiting for pod IP address to be available"),
)

@patch(
"charms.tls_certificates_interface.v3.tls_certificates.TLSCertificatesRequiresV3.get_assigned_certificates", # noqa: E501
)
@patch("charm.generate_csr")
@patch("charm.generate_private_key")
@patch("charm.check_output")
def test_given_https_nrf_url_and_service_is_running_when_fiveg_nrf_relation_joined_then_nrf_url_is_in_relation_databag( # noqa: E501
self,
patch_check_output,
patch_generate_private_key,
patch_generate_csr,
patch_get_assigned_certificates,
Expand All @@ -390,7 +343,6 @@ def test_given_https_nrf_url_and_service_is_running_when_fiveg_nrf_relation_join
root = self.harness.get_filesystem_root("nrf")
private_key = b"whatever key content"
patch_generate_private_key.return_value = private_key
patch_check_output.return_value = b"1.1.1.1"
certificate = "Whatever certificate content"
csr = b"whatever csr content"
patch_generate_csr.return_value = csr
Expand All @@ -416,18 +368,16 @@ def test_given_https_nrf_url_and_service_is_running_when_fiveg_nrf_relation_join
relation_data = self.harness.get_relation_data(
relation_id=relation_id, app_or_unit=self.harness.charm.app.name
)
self.assertEqual(relation_data["url"], "https://nrf:29510")
self.assertEqual(relation_data["url"], "https://sdcore-nrf-k8s:29510")

@patch(
"charms.tls_certificates_interface.v3.tls_certificates.TLSCertificatesRequiresV3.get_assigned_certificates", # noqa: E501
)
@patch("charm.generate_csr")
@patch("charm.check_output")
@patch("charm.generate_private_key")
def test_service_starts_running_after_nrf_relation_joined_when_fiveg_pebble_ready_then_nrf_url_is_in_relation_databag( # noqa: E501
self,
patch_generate_private_key,
patch_check_output,
patch_generate_csr,
patch_get_assigned_certificates,
):
Expand All @@ -436,7 +386,6 @@ def test_service_starts_running_after_nrf_relation_joined_when_fiveg_pebble_read
root = self.harness.get_filesystem_root("nrf")
private_key = b"whatever key content"
patch_generate_private_key.return_value = private_key
patch_check_output.return_value = b"1.1.1.1"
certificate = "Whatever certificate content"
csr = b"whatever csr content"
patch_generate_csr.return_value = csr
Expand Down Expand Up @@ -480,24 +429,21 @@ def test_service_starts_running_after_nrf_relation_joined_when_fiveg_pebble_read
relation_2_data = self.harness.get_relation_data(
relation_id=relation_2_id, app_or_unit=self.harness.charm.app.name
)
self.assertEqual(relation_1_data["url"], "https://nrf:29510")
self.assertEqual(relation_2_data["url"], "https://nrf:29510")
self.assertEqual(relation_1_data["url"], "https://sdcore-nrf-k8s:29510")
self.assertEqual(relation_2_data["url"], "https://sdcore-nrf-k8s:29510")

@patch("charm.generate_csr")
@patch("charm.check_output")
@patch("charm.generate_private_key")
def test_given_can_connect_when_on_certificates_relation_created_then_private_key_is_generated(
self,
patch_generate_private_key,
patch_check_output,
patch_generate_csr,
):
private_key = b"whatever key content"
self.harness.add_storage("config", attach=True)
self.harness.add_storage("certs", attach=True)
root = self.harness.get_filesystem_root("nrf")
patch_generate_private_key.return_value = private_key
patch_check_output.return_value = b"1.1.1.1"
csr = b"whatever csr content"
patch_generate_csr.return_value = csr
self._create_database_relation_and_populate_data()
Expand Down Expand Up @@ -552,7 +498,6 @@ def test_given_certificates_are_stored_when_on_certificates_relation_broken_then
BlockedStatus(f"Waiting for {TLS_RELATION_NAME} relation to be created"),
)

@patch("charm.check_output")
@patch("charm.generate_private_key")
@patch(
"charms.tls_certificates_interface.v3.tls_certificates.TLSCertificatesRequiresV3.request_certificate_creation", # noqa: E501
Expand All @@ -563,13 +508,11 @@ def test_given_private_key_exists_when_pebble_ready_then_csr_is_generated(
self,
patch_generate_csr,
patch_generate_private_key,
patch_check_output,
):
self.harness.add_storage("config", attach=True)
self.harness.add_storage("certs", attach=True)
private_key = "whatever key content"
patch_generate_private_key.return_value = private_key
patch_check_output.return_value = b"1.1.1.1"
root = self.harness.get_filesystem_root("nrf")
(root / "support/TLS/nrf.key").write_text(private_key)
csr = b"whatever csr content"
Expand All @@ -586,12 +529,10 @@ def test_given_private_key_exists_when_pebble_ready_then_csr_is_generated(
"charms.tls_certificates_interface.v3.tls_certificates.TLSCertificatesRequiresV3.get_assigned_certificates", # noqa: E501
)
@patch("charm.generate_csr")
@patch("charm.check_output")
@patch("charm.generate_private_key")
def test_given_csr_matches_stored_one_when_certificate_available_then_certificate_is_pushed(
self,
patch_generate_private_key,
patch_check_output,
patch_generate_csr,
patch_get_assigned_certificates,
):
Expand All @@ -600,7 +541,6 @@ def test_given_csr_matches_stored_one_when_certificate_available_then_certificat
root = self.harness.get_filesystem_root("nrf")
private_key = b"whatever key content"
patch_generate_private_key.return_value = private_key
patch_check_output.return_value = b"1.1.1.1"
certificate = "Whatever certificate content"
csr = b"whatever csr content"
patch_generate_csr.return_value = csr
Expand All @@ -623,12 +563,10 @@ def test_given_csr_matches_stored_one_when_certificate_available_then_certificat
"charms.tls_certificates_interface.v3.tls_certificates.TLSCertificatesRequiresV3.get_assigned_certificates", # noqa: E501
)
@patch("charm.generate_csr")
@patch("charm.check_output")
@patch("charm.generate_private_key")
def test_given_csr_doesnt_match_stored_one_when_certificate_available_then_certificate_is_not_pushed( # noqa: E501
self,
patch_generate_private_key,
patch_check_output,
patch_generate_csr,
patch_get_assigned_certificates,
):
Expand All @@ -638,7 +576,6 @@ def test_given_csr_doesnt_match_stored_one_when_certificate_available_then_certi
root = self.harness.get_filesystem_root("nrf")
private_key = b"whatever key content"
patch_generate_private_key.return_value = private_key
patch_check_output.return_value = b"1.1.1.1"
certificate = "Whatever certificate content"
csr = b"whatever csr content"
patch_generate_csr.return_value = csr
Expand Down

0 comments on commit 16b6b23

Please sign in to comment.