зеркало из https://github.com/Azure/iotedgedev.git
Collect IoT Hub hostname hash and suffix when deploying (#328)
* Collect IoT Hub hostname hash and suffix when deploying * Handle empty hostname * Move hash connection method to connection string class * Calculate hostname hash when init connection string * Refactor ConnectionString class
This commit is contained in:
Родитель
ce79408f68
Коммит
f71356fb34
|
@ -3,16 +3,14 @@ import os
|
|||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
try:
|
||||
from queue import Queue, Empty
|
||||
except ImportError:
|
||||
from Queue import Queue, Empty # python 2.x
|
||||
|
||||
from io import StringIO
|
||||
from threading import Timer, Thread
|
||||
from threading import Thread, Timer
|
||||
|
||||
from azure.cli.core import get_default_cli
|
||||
from fstrings import f
|
||||
from six.moves.queue import Empty, Queue
|
||||
|
||||
from . import telemetry
|
||||
|
||||
output_io_cls = StringIO
|
||||
|
||||
|
@ -357,11 +355,14 @@ class AzureCli:
|
|||
|
||||
return result
|
||||
|
||||
def set_modules(self, device_id, connection_string, hub_name, config):
|
||||
def set_modules(self, device_id, connection_string, config):
|
||||
self.output.status(f("Deploying '{config}' to '{device_id}'..."))
|
||||
|
||||
telemetry.add_extra_props({'iothubhostname': connection_string.iothub_host.name_hash, 'iothubhostnamesuffix': connection_string.iothub_host.name_suffix})
|
||||
|
||||
config = os.path.join(os.getcwd(), config)
|
||||
|
||||
return self.invoke_az_cli_outproc(["iot", "edge", "set-modules", "-d", device_id, "-n", hub_name, "-k", config, "-l", connection_string],
|
||||
return self.invoke_az_cli_outproc(["iot", "edge", "set-modules", "-d", device_id, "-n", connection_string.iothub_host.hub_name, "-k", config, "-l", connection_string.connection_string],
|
||||
error_message=f("Failed to deploy '{config}' to '{device_id}'..."), suppress_output=True)
|
||||
|
||||
def monitor_events(self, device_id, connection_string, hub_name, timeout=300):
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
from .utility import Utility
|
||||
|
||||
|
||||
class ConnectionString:
|
||||
def __init__(self, value):
|
||||
self.ConnectionString = value
|
||||
self.connection_string = value
|
||||
self.data = dict()
|
||||
|
||||
if self.ConnectionString:
|
||||
parts = self.ConnectionString.split(';')
|
||||
if self.connection_string:
|
||||
parts = self.connection_string.split(';')
|
||||
if len(parts) > 0:
|
||||
for part in parts:
|
||||
subpart = part.split('=', 1)
|
||||
|
@ -12,10 +15,8 @@ class ConnectionString:
|
|||
self.data[subpart[0].lower()] = subpart[1].strip()
|
||||
|
||||
if self.data:
|
||||
self.HostName = self["hostname"]
|
||||
if self.HostName:
|
||||
self.HubName = self.HostName.split('.')[0]
|
||||
self.SharedAccessKey = self["sharedaccesskey"]
|
||||
self.iothub_host = IoTHubHost(self["hostname"])
|
||||
self.shared_access_key = self["sharedaccesskey"]
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.data[key]
|
||||
|
@ -25,13 +26,28 @@ class IoTHubConnectionString(ConnectionString):
|
|||
def __init__(self, value):
|
||||
ConnectionString.__init__(self, value)
|
||||
|
||||
if self.ConnectionString:
|
||||
self.SharedAccessKeyName = self["sharedaccesskeyname"]
|
||||
if self.connection_string:
|
||||
self.shared_access_key_name = self["sharedaccesskeyname"]
|
||||
|
||||
|
||||
class DeviceConnectionString(ConnectionString):
|
||||
def __init__(self, value):
|
||||
ConnectionString.__init__(self, value)
|
||||
|
||||
if self.ConnectionString:
|
||||
self.DeviceId = self["deviceid"]
|
||||
if self.connection_string:
|
||||
self.device_id = self["deviceid"]
|
||||
|
||||
|
||||
class IoTHubHost:
|
||||
def __init__(self, hostname):
|
||||
self.name = hostname
|
||||
if self.name and "." in self.name:
|
||||
self.hub_name = self.name.split('.')[0]
|
||||
# get connection string hostname hash to count distint IoT Hub number
|
||||
self.name_hash = Utility.get_sha256_hash(self.name)
|
||||
# get hostname suffix (e.g., azure-devices.net) to distinguish national clouds
|
||||
self.name_suffix = self.name[self.name.index(".")+1:]
|
||||
else:
|
||||
self.hub_name = ""
|
||||
self.name_hash = ""
|
||||
self.name_suffix = ""
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import hashlib
|
||||
import sys
|
||||
from functools import wraps
|
||||
|
||||
|
@ -73,8 +72,10 @@ def hash256_result(func):
|
|||
raise ValueError('Return value is None')
|
||||
elif not isinstance(val, six.string_types):
|
||||
raise ValueError('Return value is not string')
|
||||
hash_object = hashlib.sha256(val.encode('utf-8'))
|
||||
return str(hash_object.hexdigest())
|
||||
|
||||
from .utility import Utility
|
||||
return Utility.get_sha256_hash(val)
|
||||
|
||||
return _wrapped_func
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,6 @@ class Edge:
|
|||
self.envvars.verify_envvar_has_val("DEVICE_CONNECTION_STRING", self.envvars.DEVICE_CONNECTION_INFO)
|
||||
self.envvars.verify_envvar_has_val("DEPLOYMENT_CONFIG_FILE", self.envvars.DEPLOYMENT_CONFIG_FILE)
|
||||
|
||||
self.azure_cli.set_modules(self.envvars.DEVICE_CONNECTION_INFO.DeviceId, self.envvars.IOTHUB_CONNECTION_INFO.ConnectionString,
|
||||
self.envvars.IOTHUB_CONNECTION_INFO.HubName, self.envvars.DEPLOYMENT_CONFIG_FILE_PATH)
|
||||
self.azure_cli.set_modules(self.envvars.DEVICE_CONNECTION_INFO.device_id, self.envvars.IOTHUB_CONNECTION_INFO, self.envvars.DEPLOYMENT_CONFIG_FILE_PATH)
|
||||
|
||||
self.output.footer("DEPLOYMENT COMPLETE")
|
||||
|
|
|
@ -31,18 +31,18 @@ class IoTHub:
|
|||
|
||||
if timeout == 0:
|
||||
self.utility.call_proc(['iothub-explorer', '--login', self.envvars.IOTHUB_CONNECTION_STRING,
|
||||
'monitor-events', self.envvars.DEVICE_CONNECTION_INFO.DeviceId], shell=not self.envvars.is_posix())
|
||||
'monitor-events', self.envvars.DEVICE_CONNECTION_INFO.device_id], shell=not self.envvars.is_posix())
|
||||
else:
|
||||
monitor_js = os.path.join(os.path.split(__file__)[0], "monitor.js")
|
||||
|
||||
self.utility.call_proc(['node', monitor_js, self.envvars.IOTHUB_CONNECTION_STRING,
|
||||
self.envvars.DEVICE_CONNECTION_INFO.DeviceId, timeout], shell=not self.envvars.is_posix())
|
||||
self.envvars.DEVICE_CONNECTION_INFO.device_id, timeout], shell=not self.envvars.is_posix())
|
||||
except Exception as ex:
|
||||
self.output.error("Problem while trying to call iothub-explorer. Please ensure that you have installed the iothub-explorer npm package with: npm i -g iothub-explorer.")
|
||||
self.output.error(str(ex))
|
||||
|
||||
def monitor_events_cli(self, timeout=0):
|
||||
self.azure_cli.monitor_events(self.envvars.DEVICE_CONNECTION_INFO.DeviceId,
|
||||
self.envvars.IOTHUB_CONNECTION_INFO.ConnectionString,
|
||||
self.envvars.IOTHUB_CONNECTION_INFO.HubName,
|
||||
self.azure_cli.monitor_events(self.envvars.DEVICE_CONNECTION_INFO.device_id,
|
||||
self.envvars.IOTHUB_CONNECTION_INFO.connection_string,
|
||||
self.envvars.IOTHUB_CONNECTION_INFO.iothub_host.hub_name,
|
||||
timeout)
|
||||
|
|
|
@ -51,6 +51,8 @@ class TelemetrySession(object):
|
|||
if self.exception:
|
||||
props['Exception'] = self.exception
|
||||
|
||||
props.update(self.extra_props)
|
||||
|
||||
self.events[_get_AI_key()].append({
|
||||
'name': '{}/command'.format(PRODUCT_NAME),
|
||||
'properties': props
|
||||
|
@ -106,6 +108,12 @@ def fail(exception, summary):
|
|||
_session.result_summary = summary
|
||||
|
||||
|
||||
@suppress_all_exceptions()
|
||||
def add_extra_props(props):
|
||||
if props is not None:
|
||||
_session.extra_props.update(props)
|
||||
|
||||
|
||||
@_user_agrees_to_telemetry
|
||||
@suppress_all_exceptions()
|
||||
def flush():
|
||||
|
|
|
@ -188,3 +188,9 @@ class Utility:
|
|||
current = current.get(key)
|
||||
|
||||
current[keys[-1]] = value
|
||||
|
||||
@staticmethod
|
||||
def get_sha256_hash(val):
|
||||
hash_object = sha256(val.encode('utf-8'))
|
||||
|
||||
return str(hash_object.hexdigest()).lower()
|
||||
|
|
|
@ -8,11 +8,12 @@ pytestmark = pytest.mark.unit
|
|||
|
||||
emptystring = ""
|
||||
valid_connectionstring = "HostName=testhub.azure-devices.net;SharedAccessKey=gibberish"
|
||||
valid_iothub_connectionstring = "HostName=testhub.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=moregibberish"
|
||||
valid_iothub_connectionstring = "HostName=ChaoyiTestIoT.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=moregibberish"
|
||||
valid_device_connectionstring = "HostName=testhub.azure-devices.net;DeviceId=testdevice;SharedAccessKey=othergibberish"
|
||||
invalid_connectionstring = "HostName=azure-devices.net;SharedAccessKey=gibberish"
|
||||
invalid_iothub_connectionstring = "HostName=testhub.azure-devices.net;SharedAccessKey=moregibberish"
|
||||
invalid_device_connectionstring = "HostName=testhub.azure-devices.net;DeviceId=;SharedAccessKey=othergibberish"
|
||||
empty_hostname_iothub_connectionstring = "HostName=;SharedAccessKeyName=iothubowner;SharedAccessKey=moregibberish"
|
||||
|
||||
|
||||
def test_empty_connectionstring():
|
||||
|
@ -20,6 +21,14 @@ def test_empty_connectionstring():
|
|||
assert not connectionstring.data
|
||||
|
||||
|
||||
def test_empty_hostname_iothub_connectionstring():
|
||||
connectionstring = ConnectionString(empty_hostname_iothub_connectionstring)
|
||||
assert connectionstring.iothub_host.name == ""
|
||||
assert connectionstring.iothub_host.hub_name == ""
|
||||
assert connectionstring.shared_access_key == "moregibberish"
|
||||
assert connectionstring.iothub_host.name_hash == ""
|
||||
|
||||
|
||||
def test_empty_iothub_connectionstring():
|
||||
connectionstring = IoTHubConnectionString(emptystring)
|
||||
assert not connectionstring.data
|
||||
|
@ -32,30 +41,31 @@ def test_empty_device_connectionstring():
|
|||
|
||||
def test_valid_connectionstring():
|
||||
connectionstring = ConnectionString(valid_connectionstring)
|
||||
assert connectionstring.HostName == "testhub.azure-devices.net"
|
||||
assert connectionstring.HubName == "testhub"
|
||||
assert connectionstring.SharedAccessKey == "gibberish"
|
||||
assert connectionstring.iothub_host.name == "testhub.azure-devices.net"
|
||||
assert connectionstring.iothub_host.hub_name == "testhub"
|
||||
assert connectionstring.shared_access_key == "gibberish"
|
||||
|
||||
|
||||
def test_valid_iothub_connectionstring():
|
||||
connectionstring = IoTHubConnectionString(valid_iothub_connectionstring)
|
||||
assert connectionstring.HostName == "testhub.azure-devices.net"
|
||||
assert connectionstring.HubName == "testhub"
|
||||
assert connectionstring.SharedAccessKeyName == "iothubowner"
|
||||
assert connectionstring.SharedAccessKey == "moregibberish"
|
||||
assert connectionstring.iothub_host.name == "ChaoyiTestIoT.azure-devices.net"
|
||||
assert connectionstring.iothub_host.hub_name == "ChaoyiTestIoT"
|
||||
assert connectionstring.shared_access_key_name == "iothubowner"
|
||||
assert connectionstring.shared_access_key == "moregibberish"
|
||||
assert connectionstring.iothub_host.name_hash == "6b8fcfea09003d5f104771e83bd9ff54c592ec2277ec1815df91dd64d1633778"
|
||||
|
||||
|
||||
def test_valid_devicehub_connectionstring():
|
||||
connectionstring = DeviceConnectionString(valid_device_connectionstring)
|
||||
assert connectionstring.HostName == "testhub.azure-devices.net"
|
||||
assert connectionstring.HubName == "testhub"
|
||||
assert connectionstring.DeviceId == "testdevice"
|
||||
assert connectionstring.SharedAccessKey == "othergibberish"
|
||||
assert connectionstring.iothub_host.name == "testhub.azure-devices.net"
|
||||
assert connectionstring.iothub_host.hub_name == "testhub"
|
||||
assert connectionstring.device_id == "testdevice"
|
||||
assert connectionstring.shared_access_key == "othergibberish"
|
||||
|
||||
|
||||
def test_invalid_connectionstring():
|
||||
connectionstring = ConnectionString(invalid_connectionstring)
|
||||
assert connectionstring.HubName != "testhub"
|
||||
assert connectionstring.iothub_host.hub_name != "testhub"
|
||||
|
||||
|
||||
def test_invalid_iothub_connectionstring():
|
||||
|
@ -65,7 +75,7 @@ def test_invalid_iothub_connectionstring():
|
|||
|
||||
def test_invalid_devicehub_connectionstring():
|
||||
connectionstring = DeviceConnectionString(invalid_device_connectionstring)
|
||||
assert connectionstring.HostName == "testhub.azure-devices.net"
|
||||
assert connectionstring.HubName == "testhub"
|
||||
assert not connectionstring.DeviceId
|
||||
assert connectionstring.SharedAccessKey == "othergibberish"
|
||||
assert connectionstring.iothub_host.name == "testhub.azure-devices.net"
|
||||
assert connectionstring.iothub_host.hub_name == "testhub"
|
||||
assert not connectionstring.device_id
|
||||
assert connectionstring.shared_access_key == "othergibberish"
|
||||
|
|
|
@ -210,20 +210,20 @@ def test_valid_env_iothub_connectionstring():
|
|||
|
||||
env_iothub_connectionstring = os.getenv("IOTHUB_CONNECTION_STRING")
|
||||
connectionstring = IoTHubConnectionString(env_iothub_connectionstring)
|
||||
assert connectionstring.HostName
|
||||
assert connectionstring.HubName
|
||||
assert connectionstring.SharedAccessKey
|
||||
assert connectionstring.SharedAccessKeyName
|
||||
assert connectionstring.iothub_host.name
|
||||
assert connectionstring.iothub_host.hub_name
|
||||
assert connectionstring.shared_access_key
|
||||
assert connectionstring.shared_access_key_name
|
||||
|
||||
|
||||
def test_valid_env_device_connectionstring():
|
||||
envvars.load_dotenv()
|
||||
env_device_connectionstring = os.getenv("DEVICE_CONNECTION_STRING")
|
||||
connectionstring = DeviceConnectionString(env_device_connectionstring)
|
||||
assert connectionstring.HostName
|
||||
assert connectionstring.HubName
|
||||
assert connectionstring.SharedAccessKey
|
||||
assert connectionstring.DeviceId
|
||||
assert connectionstring.iothub_host.name
|
||||
assert connectionstring.iothub_host.hub_name
|
||||
assert connectionstring.shared_access_key
|
||||
assert connectionstring.device_id
|
||||
|
||||
|
||||
def test_shared_lib():
|
||||
|
|
|
@ -58,7 +58,7 @@ def test_start_single():
|
|||
cli = __import__('iotedgedev.cli', fromlist=['main'])
|
||||
runner = CliRunner()
|
||||
|
||||
result = runner.invoke(cli.main, ['simulator', 'start', '-i', 'setup'])
|
||||
result = runner.invoke(cli.main, ['simulator', 'start', '-i', 'input1'])
|
||||
print(result.output)
|
||||
|
||||
assert 'IoT Edge Simulator has been started in single module mode.' in result.output
|
||||
|
|
|
@ -81,3 +81,7 @@ def test_in_asterisk_list_empty(utility):
|
|||
|
||||
def test_in_asterisk_list_asterisk(utility):
|
||||
assert utility.in_asterisk_list("filtermodule", "*")
|
||||
|
||||
|
||||
def test_get_sha256_hash():
|
||||
assert Utility.get_sha256_hash("foo") == "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"
|
||||
|
|
Загрузка…
Ссылка в новой задаче