Skip to content

Commit

Permalink
feat(apply): add support for multiple interfaces in get_intf_ip filter
Browse files Browse the repository at this point in the history
The `get_intf_ip` filter now supports a comma-separated list of network
interfaces. It returns the first IP address found among the specified
interfaces.

Additionally, the filter is optimized to cache results, preventing repeated
network calls and ensuring better performance when used multiple times in a
workflow.
  • Loading branch information
ankitrgadiya committed Dec 26, 2024
1 parent afc25e2 commit bc29232
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 17 deletions.
36 changes: 23 additions & 13 deletions riocli/apply/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
Filters to use in the manifests.
"""

from functools import lru_cache
import os
from typing import Dict, List

from riocli.config import new_client
from riocli.device.util import find_device_guid
Expand All @@ -42,17 +44,35 @@ def get_interface_ip(device_name: str, interface: str) -> str:
Usage:
"ip" : {{ device_name | get_intf_ip(interface='intf-name') }}
"ip" : {{ device_name | get_intf_ip(interface='intf1,intf2') }}
Args:
device_name: The name of the device.
interface: The name of the interface.
interface: The comma-separated list of the interfaces.
Returns:
The IP address of the interface
The IP address of the first interface from the list that is available.
Raises:
Exception: If the interface is not available on the device.
"""

splits = interface.split(",")

ip_interfaces = get_device_ip_interfaces(device_name)

for split in splits:
ip_interface = ip_interfaces.get(split, None)
if ip_interface is not None:
if len(ip_interface) == 0 or len(ip_interface[0]) == 0:
continue

return ip_interface[0]

raise Exception(f'interface "{interface}" not found on device "{device_name}"')

@lru_cache
def get_device_ip_interfaces(device_name: str) -> Dict[str, List[str]]:
client = new_client(with_project=True)
device_id = find_device_guid(client, device_name)

Expand All @@ -64,14 +84,4 @@ def get_interface_ip(device_name: str, interface: str) -> str:

device.refresh()

for name in device.ip_interfaces:
if name == interface:
return device.ip_interfaces[name][0]

raise Exception(f'interface "{interface}" not found on device "{device_name}"')


FILTERS = {
"getenv": getenv,
"get_intf_ip": get_interface_ip,
}
return device.ip_interfaces
7 changes: 6 additions & 1 deletion riocli/apply/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from ansible.plugins.filter.mathstuff import FilterModule as MathFilterModule
from ansible.plugins.filter.encryption import FilterModule as EncryptionFilterModule

from riocli.apply.filters import FILTERS
from riocli.apply.filters import get_interface_ip, getenv
from riocli.constants import Colors
from riocli.deployment.model import Deployment
from riocli.device.model import Device
Expand Down Expand Up @@ -56,6 +56,11 @@
"usergroup": UserGroup,
}

FILTERS = {
"getenv": getenv,
"get_intf_ip": get_interface_ip,
}


def get_model(data: dict) -> Model:
"""Get the model class based on the kind"""
Expand Down
7 changes: 4 additions & 3 deletions riocli/device/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# 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 functools
from functools import wraps, lru_cache
import json
import re
import time
Expand All @@ -37,7 +37,7 @@


def name_to_guid(f: typing.Callable) -> typing.Callable:
@functools.wraps(f)
@wraps(f)
def decorated(**kwargs: typing.Any):
try:
client = new_client()
Expand Down Expand Up @@ -118,6 +118,7 @@ def get_device_name(client: Client, guid: str) -> str:
return device.name


@lru_cache
def find_device_guid(client: Client, name: str) -> str:
devices = client.get_all_devices(device_name=name)
for device in devices:
Expand All @@ -136,7 +137,7 @@ def find_device_by_name(client: Client, name: str) -> Device:


def name_to_request_id(f: typing.Callable) -> typing.Callable:
@functools.wraps(f)
@wraps(f)
def decorated(**kwargs):
try:
client = new_client()
Expand Down

0 comments on commit bc29232

Please sign in to comment.