Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
8569948
Initial work on giving host access to test containers
jhughesoti Jul 22, 2024
1282b4c
Change external ip resolving method to use docker0
jhughesoti Jul 22, 2024
0b7c110
Resolve device interface for test containers
jhughesoti Jul 22, 2024
7f8e00d
Add gRPC methods to control the interface state
jhughesoti Jul 22, 2024
0de0a09
Merge branch 'dev' into feature/dhcp_disconnect
jhughesoti Jul 22, 2024
78ebae8
Fix host network module option
jhughesoti Jul 22, 2024
fddb530
Misc cleanup
jhughesoti Jul 23, 2024
fba0629
Move ip resolving method to IPControl class
jhughesoti Jul 23, 2024
fb11958
pylint fixes
jhughesoti Jul 23, 2024
dc06038
Merge branch 'dev' into feature/dhcp_disconnect
jboddey Jul 25, 2024
9f98cea
refactor func to handle case when network interface not exists
hitnik Jul 2, 2024
c5e6e30
set test result "Error"
hitnik Jul 12, 2024
b55b9a5
check device connected
hitnik Jul 12, 2024
d5517fc
thread for monitoring device connection
hitnik Jul 12, 2024
a209e10
Minor changes
jboddey Jul 21, 2024
b1f0227
check the device connection only before each test
hitnik Jul 25, 2024
b683f86
send testrun status using mqtt
hitnik Jul 29, 2024
3a2837d
remove duplicatied line
hitnik Jul 29, 2024
fbfb765
refactor setting remaining tests to error
hitnik Jul 29, 2024
3fd17d5
Pylint fixes
jhughesoti Jul 29, 2024
b949db7
pylint
hitnik Jul 30, 2024
3f8e4af
Merge branch 'dev' into feature/device_connected
jboddey Jul 31, 2024
5be54da
Merge branch 'dev' into feature/device_connected
jboddey Aug 2, 2024
9053f60
Use mqtt service instead of calling GET /status every 5 seconds. (#644)
sofyakurilova Aug 4, 2024
d9d0bb7
merge dev
jhughesoti Aug 5, 2024
00a4d44
Allow ICMP response to DHCP messages in DHCP snooping test (#608)
jboddey Aug 6, 2024
d7c1e8b
The risk profile saved with old format is shown improperly while loa…
sofyakurilova Aug 7, 2024
9b06a7e
GAR : The alt text for the expired risk profile should be communicate…
sofyakurilova Aug 7, 2024
6a7349e
Merge branch 'dev' into feature/device_connected
hitnik Aug 8, 2024
c435c09
Update wording of tls cipher results (#671)
jhughesoti Aug 12, 2024
c38a561
Show error message if provided; show default message if no (#680)
sofyakurilova Aug 13, 2024
dedcc5d
Test install on supported operating systems (#675)
jboddey Aug 13, 2024
8117bc8
Merge branch 'dev' into feature/dhcp_disconnect
jboddey Aug 14, 2024
05c96dd
Merge branch 'release/v1.4.1' into feature/dhcp_disconnect
jboddey Aug 14, 2024
e315a99
Do not give Non-Compliant if error given
jboddey Aug 14, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,30 @@ jobs:
name: testrun_package
path: testrun*.deb

install_package:
install_package_20:
permissions: {}
needs: create_package
name: Install
name: Install on Ubuntu 20.04
runs-on: ubuntu-20.04
timeout-minutes: 15
steps:
- name: Checkout source
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Download package
uses: actions/download-artifact@v4
with:
name: testrun_package
- name: Install dependencies
shell: bash {0}
run: sudo cmd/prepare
- name: Install package
shell: bash {0}
run: sudo apt install ./testrun*.deb

install_package_22:
permissions: {}
needs: create_package
name: Install on Ubuntu 22.04
runs-on: ubuntu-22.04
timeout-minutes: 15
steps:
Expand All @@ -49,3 +69,23 @@ jobs:
- name: Install package
shell: bash {0}
run: sudo apt install ./testrun*.deb

install_package_24:
permissions: {}
needs: create_package
name: Install on Ubuntu 24.04
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Checkout source
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Download package
uses: actions/download-artifact@v4
with:
name: testrun_package
- name: Install dependencies
shell: bash {0}
run: sudo cmd/prepare
- name: Install package
shell: bash {0}
run: sudo apt install ./testrun*.deb
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ build/

# Ignore generated files from unit tests
testing/unit_test/temp/
testing/unit/conn/output/
testing/unit/dns/output/
testing/unit/nmap/output/
testing/unit/ntp/output/
Expand Down
1 change: 1 addition & 0 deletions framework/python/src/common/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class MQTT:
def __init__(self) -> None:
self._host = WEBSOCKETS_HOST
self._client = mqtt_client.Client(mqtt_client.CallbackAPIVersion.VERSION2)
LOGGER.setLevel(logger.logging.INFO)
self._client.enable_logger(LOGGER)

def _connect(self):
Expand Down
43 changes: 42 additions & 1 deletion framework/python/src/common/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
import pytz
import json
import os
from common import util, logger
from fastapi.encoders import jsonable_encoder
from common import util, logger, mqtt
from common.risk_profile import RiskProfile
from net_orc.ip_control import IPControl

Expand All @@ -37,13 +38,42 @@
MAX_DEVICE_REPORTS_KEY = 'max_device_reports'
CERTS_PATH = 'local/root_certs'
CONFIG_FILE_PATH = 'local/system.json'
STATUS_TOPIC = 'status'

PROFILE_FORMAT_PATH = 'resources/risk_assessment.json'
PROFILES_DIR = 'local/risk_profiles'

LOGGER = logger.get_logger('session')


def session_tracker(method):
"""Session changes tracker."""
def wrapper(self, *args, **kwargs):

result = method(self, *args, **kwargs)

if self.get_status() != 'Idle':
self.get_mqtt_client().send_message(
STATUS_TOPIC,
jsonable_encoder(self.to_json())
)

return result
return wrapper

def apply_session_tracker(cls):
"""Applies tracker decorator to class methods"""
for attr in dir(cls):
if (callable(getattr(cls, attr))
and not attr.startswith('_')
and not attr.startswith('get')
and not attr == 'to_json'
):
setattr(cls, attr, session_tracker(getattr(cls, attr)))
return cls


@apply_session_tracker
class TestrunSession():
"""Represents the current session of Test Run."""

Expand Down Expand Up @@ -109,6 +139,9 @@ def __init__(self, root_dir):
self._timezone = tz[0]
LOGGER.debug(f'System timezone is {self._timezone}')

# MQTT client
self._mqtt_client = mqtt.MQTT()

def start(self):
self.reset()
self._status = 'Waiting for Device'
Expand Down Expand Up @@ -333,6 +366,11 @@ def add_test_result(self, result):
if not updated:
self._results.append(result)

def set_test_result_error(self, result):
"""Set test result error"""
result.result = 'Error'
self._results.append(result)

def add_module_report(self, module_report):
self._module_reports.append(module_report)

Expand Down Expand Up @@ -731,5 +769,8 @@ def detect_network_adapters_change(self) -> dict:
self._ifaces = ifaces_new
return adapters

def get_mqtt_client(self):
return self._mqtt_client

def get_ifaces(self):
return self._ifaces
1 change: 1 addition & 0 deletions framework/python/src/common/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

from common import logger

# Check adapters period seconds
# Check adapters period seconds
CHECK_NETWORK_ADAPTERS_PERIOD = 5
INTERNET_CONNECTION_TOPIC = 'events/internet'
Expand Down
14 changes: 10 additions & 4 deletions framework/python/src/net_orc/ip_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from common import logger
from common import util
import re
import socket

LOGGER = logger.get_logger('ip_ctrl')

Expand Down Expand Up @@ -45,10 +46,7 @@ def add_namespace(self, namespace):

def check_interface_status(self, interface_name):
output = util.run_command(cmd=f'ip link show {interface_name}', output=True)
if 'state DOWN ' in output[0]:
return False
else:
return True
return 'state UP ' in output[0]

def delete_link(self, interface_name):
"""Delete an ip link"""
Expand Down Expand Up @@ -99,6 +97,14 @@ def get_iface_port_stats(self, iface):
else:
return None

def get_ip_address(self, iface):
addrs = psutil.net_if_addrs()
if iface in addrs:
for addr in addrs[iface]:
if addr.family == socket.AF_INET:
return addr.address
return None

def get_namespaces(self):
result = util.run_command('ip netns list')
# Strip ID's from the namespace results
Expand Down
54 changes: 33 additions & 21 deletions framework/python/src/net_orc/network_orchestrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ def start_network(self):
# Get network ready (via Network orchestrator)
LOGGER.debug('Network is ready')

def get_ip_address(self, iface):
return self._ip_ctrl.get_ip_address(iface)

def get_listener(self):
return self._listener

Expand Down Expand Up @@ -494,14 +497,15 @@ def _load_network_module(self, module_dir):
# Load network service networking configuration
if net_module.enable_container:

net_module.net_config.enable_wan = net_module_json['config']['network'][
'enable_wan']
net_module.net_config.ip_index = net_module_json['config']['network'][
'ip_index']

net_module.net_config.host = False if not 'host' in net_module_json[
'config']['network'] else net_module_json['config']['network']['host']

if not net_module.net_config.host:
net_module.net_config.enable_wan = net_module_json['config']['network'][
'enable_wan']
net_module.net_config.ip_index = net_module_json['config']['network'][
'ip_index']

net_module.net_config.ipv4_address = self.network_config.ipv4_network[
net_module.net_config.ip_index]
net_module.net_config.ipv4_network = self.network_config.ipv4_network
Expand Down Expand Up @@ -538,26 +542,29 @@ def _get_network_module(self, name):
def _start_network_service(self, net_module):

LOGGER.debug('Starting network service ' + net_module.display_name)
network = 'host' if net_module.net_config.host else PRIVATE_DOCKER_NET
network = 'host' if net_module.net_config.host else 'bridge'
LOGGER.debug(f"""Network: {network}, image name: {net_module.image_name},
container name: {net_module.container_name}""")

try:
client = docker.from_env()
net_module.container = client.containers.run(
net_module.image_name,
auto_remove=True,
cap_add=['NET_ADMIN'],
name=net_module.container_name,
hostname=net_module.container_name,
network_mode='none',
privileged=True,
detach=True,
mounts=net_module.mounts,
environment={
'TZ': self.get_session().get_timezone(),
'HOST_USER': util.get_host_user()
})
net_module.image_name,
auto_remove=True,
cap_add=['NET_ADMIN'],
name=net_module.container_name,
hostname=net_module.container_name,
# Undetermined version of docker seems to have broken
# DNS configuration (/etc/resolv.conf) Re-add when/if
# this network is utilized and DNS issue is resolved
network=network,
privileged=True,
detach=True,
mounts=net_module.mounts,
environment={
'TZ': self.get_session().get_timezone(),
'HOST_USER': util.get_host_user()
})
except docker.errors.ContainerError as error:
LOGGER.error('Container run error')
LOGGER.error(error)
Expand Down Expand Up @@ -793,9 +800,15 @@ def network_adapters_checker(self, mqtt_client: mqtt.MQTT, topic: str):
adapters = self._session.detect_network_adapters_change()
if adapters:
mqtt_client.send_message(topic, adapters)
except Exception:
except Exception: # pylint: disable=W0718
LOGGER.error(traceback.format_exc())

def is_device_connected(self):
"""Check if device connected"""
return self._ip_ctrl.check_interface_status(
self._session.get_device_interface()
)

def internet_conn_checker(self, mqtt_client: mqtt.MQTT, topic: str):
"""Checks internet connection and sends a status to frontend"""

Expand Down Expand Up @@ -825,7 +838,6 @@ def internet_conn_checker(self, mqtt_client: mqtt.MQTT, topic: str):
# Broadcast via MQTT client
mqtt_client.send_message(topic, message)


class NetworkModule:
"""Define all the properties of a Network Module"""

Expand Down
Loading