Skip to content

Commit

Permalink
Replaces user input from IP address to more convenient interface name (
Browse files Browse the repository at this point in the history
  • Loading branch information
gruyaume authored Mar 21, 2023
1 parent 83eb914 commit 02c163d
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 13 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ If you wish to change the default configuration, create a YAML configuration fil
```yaml
---
srs-enb-ue:
bind-address: <Local IP address to bind for GTP and S1AP connection.>
bind-interface: <Local interface to bind for GTP and S1AP connection.>
enb-name: <eNodeB name.>
enb-mcc: <EnodeB Mobile Country Code (MCC).>
enb-mnc: <EnodeB Mobile Network Code (MNC).>
Expand Down
5 changes: 2 additions & 3 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
# See LICENSE file for licensing details.

options:
bind-address:
bind-interface:
type: string
description: |
Local IP address to bind for GTP and S1AP connection.
default: ""
Local interface to bind for GTP and S1AP connection.
enb-name:
type: string
description: |
Expand Down
10 changes: 5 additions & 5 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,11 +238,11 @@ def _mme_address(self) -> Optional[str]:
@property
def _bind_address(self) -> Optional[str]:
"""Returns bind address."""
return (
bind_address
if (bind_address := self.model.config.get("bind-address"))
else ip_from_default_iface()
)
bind_interface = self.model.config.get("bind-interface")
if not bind_interface:
return ip_from_default_iface()
else:
return get_iface_ip_address(iface=bind_interface)


if __name__ == "__main__":
Expand Down
4 changes: 2 additions & 2 deletions src/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ def ip_from_default_iface() -> Optional[str]:
"""Returns the default interface's IP address."""
default_gateway = netifaces.gateways()["default"]
if netifaces.AF_INET in default_gateway:
_, iface = netifaces.gateways()["default"][netifaces.AF_INET]
_, iface = default_gateway[netifaces.AF_INET]
default_interface = netifaces.ifaddresses(iface)
if netifaces.AF_INET in default_interface:
return netifaces.ifaddresses(iface)[netifaces.AF_INET][0].get("addr")
return default_interface[netifaces.AF_INET][0].get("addr")
return None


Expand Down
22 changes: 21 additions & 1 deletion tests/unit/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,27 @@ def test_given_lte_core_relation_when_mme_address_is_available_then_srsenb_servi
description="SRS eNodeB Emulator Service",
)

@patch("linux_service.Service.restart", new=Mock)
@patch("linux_service.Service.enable", new=Mock)
@patch("linux_service.Service.create")
@patch("charm.get_iface_ip_address")
def test_given_user_specified_bind_interface_when_lte_core_available_then_interface_is_used(
self, patch_get_iface_ip_address, patch_service_create
):
self.harness.update_config(key_values={"bind-interface": "eth1"})
eth_1_ip_address = "5.6.7.8"
patch_get_iface_ip_address.return_value = eth_1_ip_address

self.harness.set_leader(True)

self.create_lte_core_relation()

patch_service_create.assert_called_with(
command=f"/snap/bin/srsran.srsenb --enb.mme_addr=1.2.3.4 --enb.gtp_bind_addr={eth_1_ip_address} --enb.s1c_bind_addr={eth_1_ip_address} --enb.name=dummyENB01 --enb.mcc=001 --enb.mnc=01 --enb_files.rr_config=/snap/srsran/current/config/rr.conf --enb_files.sib_config=/snap/srsran/current/config/sib.conf /snap/srsran/current/config/enb.conf --rf.device_name=zmq --rf.device_args=fail_on_disconnect=true,tx_port=tcp://*:2000,rx_port=tcp://localhost:2001,id=enb,base_srate=23.04e6", # noqa: E501
user="root",
description="SRS eNodeB Emulator Service",
)

@patch("charm.ip_from_default_iface", new=Mock)
@patch("linux_service.Service.restart")
@patch("linux_service.Service.enable", new=Mock)
Expand Down Expand Up @@ -158,7 +179,6 @@ def test_given_any_config_and_started_is_false_when_on_config_changed_then_srsen
patch_service_restart.assert_not_called()

@patch("charm.ip_from_default_iface", new=Mock)
@patch("charm.get_iface_ip_address", new=Mock)
@patch("linux_service.Service.restart", new=Mock)
@patch("linux_service.Service.enable", new=Mock)
@patch("linux_service.Service.create")
Expand Down
62 changes: 61 additions & 1 deletion tests/unit/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import unittest
from unittest.mock import patch

from utils import shell
import netifaces # type: ignore[import]

from utils import get_iface_ip_address, ip_from_default_iface, shell


class TestUtils(unittest.TestCase):
Expand All @@ -15,3 +17,61 @@ def test_given_command_when_shell_then_subprocess_run(self, patch_run):
shell(command=command)

patch_run.assert_called_with(command, shell=True, stdout=-1, encoding="utf-8")

@patch("netifaces.ifaddresses")
@patch("netifaces.gateways")
def test_given_default_interface_has_ip_when_ip_from_default_iface_then_ip_is_returned(
self, patch_gateways, patch_addresses
):
default_gateway = "192.168.2.1"
ip_address = "192.168.2.122"
interface_name = "eth0"
patch_gateways.return_value = {
"default": {netifaces.AF_INET: (default_gateway, interface_name)}
}
patch_addresses.return_value = {netifaces.AF_INET: [{"addr": ip_address}]}

assert ip_from_default_iface() == ip_address

@patch("netifaces.ifaddresses")
@patch("netifaces.gateways")
def test_given_no_default_gateway_ip_when_ip_from_default_iface_then_none_is_returned( # noqa: E501
self, patch_gateways, patch_addresses
):
patch_gateways.return_value = {"default": {}}
patch_addresses.return_value = {}

assert not ip_from_default_iface()

@patch("netifaces.ifaddresses")
@patch("netifaces.gateways")
def test_given_default_interface_does_not_have_an_ip_when_ip_from_default_iface_then_none_is_returned( # noqa: E501
self, patch_gateways, patch_addresses
):
default_gateway = "192.168.2.1"
interface_name = "eth0"
patch_gateways.return_value = {
"default": {netifaces.AF_INET: (default_gateway, interface_name)}
}
patch_addresses.return_value = {}

assert not ip_from_default_iface()

@patch("netifaces.ifaddresses")
def test_given_interface_has_ip_address_when_get_iface_ip_address_then_ip_is_returned(
self, patch_addresses
):
interface = "eth0"
ip_address = "1.2.3.4"
patch_addresses.return_value = {netifaces.AF_INET: [{"addr": ip_address}]}

assert get_iface_ip_address(interface) == ip_address

@patch("netifaces.ifaddresses")
def test_given_interface_does_not_exist_when_get_iface_ip_address_then_none_is_returned(
self, patch_addresses
):
interface = "eth0"
patch_addresses.side_effect = ValueError()

assert not get_iface_ip_address(interface)

0 comments on commit 02c163d

Please sign in to comment.