Skip to content

Commit

Permalink
Merge pull request #238 from NebraLtd/shawaj/onboarding
Browse files Browse the repository at this point in the history
feat: add parsing for onboarding key
  • Loading branch information
shawaj authored Apr 8, 2023
2 parents 8d93145 + b6d6d2c commit 00b1272
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 4 deletions.
25 changes: 25 additions & 0 deletions hm_pyhelper/hardware_definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberrypi3-64'],
'SPIBUS': 'spidev1.2',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 38,
'MAC': 'eth0',
'STATUS': 25,
Expand All @@ -48,6 +49,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberrypi3-64'],
'SPIBUS': 'spidev1.2',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 38,
'MAC': 'eth0',
'STATUS': 25,
Expand All @@ -71,6 +73,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['rockpi-4b-rk3399'],
'SPIBUS': 'spidev32766.0',
'SWARM_KEY_URI': ['ecc://i2c-7:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-7:96?slot=0'],
'RESET': 149,
'MAC': 'eth0',
'STATUS': 156,
Expand All @@ -96,6 +99,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberry-pi'],
'SPIBUS': 'spidev1.2',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 22,
'MAC': 'wlan0',
'STATUS': 24,
Expand All @@ -117,6 +121,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberry-pi'],
'SPIBUS': 'spidev1.2',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 22,
'MAC': 'wlan0',
'STATUS': 24,
Expand All @@ -138,6 +143,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['radxa-zero'],
'SPIBUS': 'spidev0.0',
'SWARM_KEY_URI': ['ecc://i2c-3:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-3:96?slot=0'],
'RESET': 415,
'MAC': 'wlan0',
'STATUS': 421,
Expand All @@ -159,6 +165,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberry-pi'],
'SPIBUS': 'spidev1.2',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 4,
'MAC': 'wlan0',
'STATUS': 26,
Expand All @@ -180,6 +187,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['beaglebone-black'],
'SPIBUS': 'spidev1.0',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 60,
'MAC': 'eth0',
'STATUS': 31,
Expand All @@ -201,6 +209,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['beaglebone-pocket'],
'SPIBUS': 'spidev1.2',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 60,
'MAC': 'wlan0',
'STATUS': 31,
Expand All @@ -222,6 +231,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['rockpi-4b-rk3399'],
'SPIBUS': 'spidev32766.0',
'SWARM_KEY_URI': ['ecc://i2c-7:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-7:96?slot=0'],
'RESET': 149,
'MAC': 'eth0',
'STATUS': 156,
Expand All @@ -245,6 +255,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['asus-tinker-board'],
'SPIBUS': 'spidev2.0',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 167,
'MAC': 'eth0',
'STATUS': 163,
Expand All @@ -266,6 +277,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberrypi4-64'],
'SPIBUS': 'spidev0.0',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 25,
'MAC': 'wlan0',
'STATUS': 20,
Expand Down Expand Up @@ -309,6 +321,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberrypi4-64'],
'SPIBUS': 'spidev0.0',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 17,
'MAC': 'wlan0',
'STATUS': 22,
Expand All @@ -330,6 +343,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberrypi4-64'],
'SPIBUS': 'spidev0.0',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 23,
'MAC': 'wlan0',
'STATUS': 22,
Expand All @@ -351,6 +365,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberrypi4-64'],
'SPIBUS': 'spidev0.0',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 17,
'MAC': 'wlan0',
'STATUS_LED': {
Expand All @@ -377,6 +392,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberrypi4-64'],
'SPIBUS': 'spidev0.0',
'SWARM_KEY_URI': ['ecc://i2c-0:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-0:96?slot=0'],
'RESET': 23,
'MAC': 'eth0',
'STATUS': 17,
Expand All @@ -398,6 +414,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberrypi4-64'],
'SPIBUS': 'spidev0.0',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 4,
'MAC': 'wlan0',
'STATUS_LED': {
Expand Down Expand Up @@ -426,6 +443,7 @@ def is_raspberry_pi() -> bool:
'raspberrypi4-64'],
'SPIBUS': 'spidev0.0',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 22,
'MAC': 'eth0',
'STATUS': 20,
Expand All @@ -449,6 +467,7 @@ def is_raspberry_pi() -> bool:
'raspberrypi4-64'],
'SPIBUS': 'spidev0.0',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 17,
'MAC': 'eth0',
'STATUS': 20,
Expand All @@ -470,6 +489,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberrypicm4-ioboard'],
'SPIBUS': 'spidev0.0',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 17,
'MAC': 'wlan0',
'STATUS': 22,
Expand All @@ -491,6 +511,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['radxa-cm3-rpicm4-ioboard'],
'SPIBUS': 'spidev0.0',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 17,
'MAC': 'wlan0',
'STATUS': 22,
Expand All @@ -512,6 +533,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberrypicm4-ioboard'],
'SPIBUS': 'spidev0.0',
'SWARM_KEY_URI': ['ecc://i2c-10:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-10:96?slot=0'],
'RESET': 23,
'MAC': 'wlan0',
'STATUS': 22,
Expand Down Expand Up @@ -577,6 +599,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberrypi4-64'],
'SPIBUS': 'spidev0.0', # There is a CSN1 pin which is connected to GPIO6 (HAT Pin 31)
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 22,
'MAC': 'eth0',
'STATUS': 21, # Stub. There is no status LED on X3. I2C-3 is used for display
Expand All @@ -599,6 +622,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberrypi3-64'],
'SPIBUS': 'spidev1.0',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 38,
'MAC': 'eth0',
'STATUS': 25,
Expand All @@ -620,6 +644,7 @@ def is_raspberry_pi() -> bool:
'BALENA_DEVICE_TYPE': ['raspberrypicm4-ioboard'],
'SPIBUS': 'spidev0.0',
'SWARM_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-1:96?slot=0'],
'RESET': 17,
'MAC': 'wlan0',
'STATUS': 22,
Expand Down
44 changes: 44 additions & 0 deletions hm_pyhelper/miner_param.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,50 @@ def get_ecc_location() -> str:
return ecc_location


def get_onboarding_location() -> str:
onboarding_list = get_variant_attribute(os.getenv('VARIANT'), 'ONBOARDING_KEY_URI')
onboarding_location = None

try:
with open("/var/nebra/onboarding_file", 'r') as data:
generated_onboarding_location = str(data.read()).rstrip('\n')

if len(generated_onboarding_location) < 10:
generated_onboarding_location = None
else:
LOGGER.info("Generated onboarding key location file found: "
+ generated_onboarding_location)
except FileNotFoundError:
# No onboarding key location file found, create variable with value None
generated_onboarding_location = None

if os.getenv('ONBOARDING_KEY_URI_OVERRIDE'):
onboarding_location = os.getenv('ONBOARDING_KEY_URI_OVERRIDE')
elif generated_onboarding_location is not None:
onboarding_location = generated_onboarding_location
elif len(onboarding_list) == 1:
onboarding_location = onboarding_list[0]
else:
for location in onboarding_list:
parse_result = urlparse(location)
i2c_bus = parse_i2c_bus(parse_result.hostname)
i2c_address = parse_i2c_address(parse_result.port)
command = f'i2cdetect -y {i2c_bus}'
parameter = f'{i2c_address} --'

if config_search_param(command, parameter):
onboarding_location = location
with open("/var/nebra/onboarding_file", "w") as file:
file.write(onboarding_location)
return onboarding_location

if not onboarding_location:
LOGGER.error("Can't find onboarding key. Ensure ONBOARDING_KEY_URI is "
"correct in hardware definitions.")

return onboarding_location


def get_gateway_mfr_command(sub_command: str, slot: int = False) -> list:
gateway_mfr_path = get_gateway_mfr_path()
command = [gateway_mfr_path]
Expand Down
80 changes: 77 additions & 3 deletions hm_pyhelper/tests/test_miner_param.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
import sys
from unittest.mock import ANY, mock_open, patch, Mock
from packaging.version import Version
from hm_pyhelper.exceptions import ECCMalfunctionException, \
from hm_pyhelper.exceptions import ECCMalfunctionException, UnknownVariantAttributeException, \
MinerFailedToFetchMacAddress, GatewayMFRInvalidVersion, GatewayMFRExecutionException, \
GatewayMFRFileNotFoundException, UnsupportedGatewayMfrVersion
GatewayMFRFileNotFoundException, UnsupportedGatewayMfrVersion, UnknownVariantException
from hm_pyhelper.lock_singleton import ResourceBusyError
from hm_pyhelper.miner_param import retry_get_region, await_spi_available, \
provision_key, run_gateway_mfr, get_gateway_mfr_path, config_search_param, get_ecc_location, \
did_gateway_mfr_test_result_include_miner_key_pass, parse_i2c_address, parse_i2c_bus, \
get_mac_address, get_public_keys_rust, get_gateway_mfr_version, get_gateway_mfr_command
get_mac_address, get_public_keys_rust, get_gateway_mfr_version, get_gateway_mfr_command, \
get_onboarding_location

sys.path.append("..")

Expand Down Expand Up @@ -64,10 +65,12 @@
'NEBHNT-WITH-ECC-ADDRESS': {
'KEY_STORAGE_BUS': '/dev/i2c-X',
'SWARM_KEY_URI': ['ecc://i2c-X:96?slot=0'],
'ONBOARDING_KEY_URI': ['ecc://i2c-X:96?slot=0'],
},
'NEBHNT-NO-ECC-ADDRESS': {
'NO_KEY_STORAGE_BUS': '/dev/i2c-X',
'NO_KEY_SWARM_KEY_URI': ['ecc://i2c-X:96?slot=0'],
'NO_ONBOARDING_KEY_URI': ['ecc://i2c-X:96?slot=0'],
},
'NEBHNT-MULTIPLE-ECC-ADDRESS': {
'KEY_STORAGE_BUS': '/dev/i2c-2',
Expand All @@ -78,6 +81,8 @@

ECC_FILE_DATA = 'ecc://i2c-Y:96?slot=1'
ECC_FILE_DATA_BLANK = None
ONBOARDING_FILE_DATA = 'ecc://i2c-Z:96?slot=10'
ONBOARDING_FILE_DATA_BLANK = None


class SubprocessResult(object):
Expand Down Expand Up @@ -278,6 +283,64 @@ def test_get_ecc_location_generated_ecc(self):
expected_result = 'ecc://i2c-Y:96?slot=1'
self.assertEqual(actual_result, expected_result)

@patch("builtins.open", mock_open(read_data=ONBOARDING_FILE_DATA))
def test_get_onboarding_location_generated_ecc(self):
actual_result = get_onboarding_location()
expected_result = 'ecc://i2c-Z:96?slot=10'
self.assertEqual(actual_result, expected_result)

@patch.dict('os.environ', {"ONBOARDING_KEY_URI_OVERRIDE": "override-test"})
def test_get_onboarding_override(self):
actual_result = get_onboarding_location()
expected_result = "override-test"
self.assertEqual(actual_result, expected_result)

@patch("builtins.open", mock_open(read_data=ONBOARDING_FILE_DATA_BLANK))
@patch.dict('os.environ', {"VARIANT": "NEBHNT-MULTIPLE-ECC-ADDRESS"})
@patch('subprocess.Popen')
def test_get_onboarding_key_multi_KEY_URI(self, mock_subproc_popen):
process_mock = Mock()
attrs = {'communicate.return_value': (str.encode("60 --"), 'error')}
process_mock.configure_mock(**attrs)
mock_subproc_popen.return_value = process_mock

actual_result = get_onboarding_location()
expected_result = 'ecc://i2c-3:96?slot=0'
self.assertEqual(actual_result, expected_result)

@patch("builtins.open", mock_open(read_data=ONBOARDING_FILE_DATA_BLANK))
@patch.dict('os.environ', {"VARIANT": "NEBHNT-MULTIPLE-ECC-ADDRESS"})
@patch('subprocess.Popen')
def test_get_onboarding_key_multi_KEY_58(self, mock_subproc_popen):
process_mock = Mock()
attrs = {'communicate.return_value': (str.encode("58 --"), 'error')}
process_mock.configure_mock(**attrs)
mock_subproc_popen.return_value = process_mock

actual_result = get_onboarding_location()
expected_result = 'ecc://i2c-4:88?slot=15'
self.assertEqual(actual_result, expected_result)

@patch.dict('os.environ', {"VARIANT": "NEBHNT-NO-ECC-ADDRESS"})
def test_get_onboarding_key_missing(self):
with self.assertRaises(UnknownVariantAttributeException):
get_onboarding_location()

@patch.dict('os.environ', {"VARIANT": "NEBHNT-NO-ECC-ADDRESS"})
def test_get_ecc_key_missing(self):
with self.assertRaises(UnknownVariantAttributeException):
get_ecc_location()

@patch.dict('os.environ', {"VARIANT": "MISSING"})
def test_get_onboarding_key_missing_variant(self):
with self.assertRaises(UnknownVariantException):
get_onboarding_location()

@patch.dict('os.environ', {"VARIANT": "MISSING"})
def test_get_ecc_key_missing_variant(self):
with self.assertRaises(UnknownVariantException):
get_ecc_location()

@patch('hm_pyhelper.miner_param.get_gateway_mfr_command',
return_value=['gateway_mfr', 'arg1', 'arg2'])
@patch('subprocess.run', side_effect=FileNotFoundError())
Expand Down Expand Up @@ -450,6 +513,17 @@ def test_incorrect_param(self, mock_subproc_popen):
result = config_search_param("somecommand", "60--")
self.assertEqual(result, False)

@patch('subprocess.Popen')
def test_error_command(self, mock_subproc_popen):
process_mock = Mock()
attrs = {'communicate.return_value': (str.encode(''),
"Error: Could not open file `/dev/i2c-1' or `/dev/i2c/1': "
"No such file or directory")}
process_mock.configure_mock(**attrs)
mock_subproc_popen.return_value = process_mock
result = config_search_param("somecommand", "60--")
self.assertEqual(result, False)

def test_types(self):
self.assertRaises(TypeError, config_search_param, 1, 2)
self.assertRaises(TypeError, config_search_param, "123321", 1)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

setup(
name='hm_pyhelper',
version='0.14.1',
version='0.14.2',
author="Nebra Ltd",
author_email="[email protected]",
description="Helium Python Helper",
Expand Down

0 comments on commit 00b1272

Please sign in to comment.