From a63cd4666991ab1bcfb6415296dbbc7186e56a76 Mon Sep 17 00:00:00 2001 From: Shivaschandra KL Date: Thu, 22 Jan 2026 07:10:36 -0500 Subject: [PATCH] feat(mtda-cli): find all mtda agents in give ip pattern This commit is just proposal to start discussions on having a api to search all agents and their status, which would potentially help in automation labs with multiple setups to get the status of agent and use it to deploy. For now i have used the storage_status if the idea seems valid and fit ,would like work and add required apis in main to make this feature more dependable. Signed-off-by: Shivaschandra KL --- mtda-cli | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/mtda-cli b/mtda-cli index f2f73812..5bd5b668 100755 --- a/mtda-cli +++ b/mtda-cli @@ -13,11 +13,16 @@ # System imports import os import requests +import re import time import sys import socket from argparse import ArgumentParser, RawTextHelpFormatter - +# Pyro +try: + from Pyro5.compatibility import Pyro4 +except ImportError: + import Pyro4 # Local imports from mtda.main import MultiTenantDeviceAccess from mtda.client import Client @@ -32,6 +37,30 @@ def human_readable_bytes(size): else: return f"{size / 1024 / 1024 / 1024:.2f} GiB" +def find_devices_in_pattern(ip_pattern): + """ + Generates all IP addresses for a given pattern of the first three octets, + assuming the last octet iterates from 0 to 255. + """ + if not re.fullmatch(r'(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.\*', ip_pattern): + print("Error: Invalid pattern for the first three octets. Please use the format X.X.X (e.g., 134.86.254).") + return [] + octets_prefix = ip_pattern.split('.')[:3] + for i, octet_str in enumerate(octets_prefix): + try: + val = int(octet_str) + if not (0 <= val <= 255): + print(f"Error: Invalid octet value '{octet_str}' in position {i+1}. Octets must be between 0 and 255.") + return [] + except ValueError: + print(f"Error: Invalid octet value '{octet_str}' in position {i+1}. Octets must be numbers.") + return [] + found_ips = [] + base_ip = ".".join(octets_prefix) + for last_octet in range(256): + full_ip = f"{base_ip}.{last_octet}" + found_ips.append(full_ip) + return found_ips class AppOutput(ScreenOutput): def __init__(self, app): @@ -349,6 +378,21 @@ class Application: result = self.client().monitor_wait(args.wait_string, args.timeout) return 0 if result is True else 1 + def search_cmd(self, args): + ip_pattern_from_args = args.ip_range + print(f"The IP pattern provided is: {ip_pattern_from_args}") + os.system("ulimit -n 4096") + patterns_to_try = find_devices_in_pattern(ip_pattern_from_args) + for ip in patterns_to_try: + try: + local_client = Client(host=ip) + _, writing, written = local_client.storage_status() + local_client._impl._pyroRelease() + print(f"Found MTDA Device at IP : {ip}") + except Pyro4.errors.CommunicationError as e: + continue + return 0 + def setenv_cmd(self, args=None): self.agent.env_set(args.name, args.value) return 0 @@ -746,6 +790,22 @@ class Application: help="buttons" ) + # subcommand: search + cmd = self.search_cmd + p = subparsers.add_parser( + "search", + help="This utility helps you find devices within a specified IP pattern.\n" + "Please enter an IP pattern using numbers (0-255) and '*' as a wildcard.\n" + "Example: 192.168.1.*" + ) + p.add_argument( + "ip_range", + metavar="ip_range", + type=str, + help="The IP pattern to search for (e.g., 134.86.254.*). " + ) + p.set_defaults(func=cmd) + # subcommand: monitor cmd = self.monitor_cmd p = subparsers.add_parser(