iotedgedev 3.3.4__zip → 3.3.5__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- s/.git/FETCH_HEAD +2 -1
- s/.git/HEAD +1 -1
- s/.git/hooks/fsmonitor-watchman.sample +3 -2
- s/.git/index +0 -0
- s/.git/logs/HEAD +1 -1
- s/.git/logs/refs/remotes/origin/EO +1 -1
- s/.git/logs/refs/remotes/origin/avagraw/security_fix +1 -1
- s/.git/logs/refs/remotes/origin/cherry-pick-rename +1 -1
- s/.git/logs/refs/remotes/origin/chyuan/fix-validation-not-fail-test +1 -1
- s/.git/logs/refs/remotes/origin/chyuan/update-linux-agent +1 -1
- s/.git/logs/refs/remotes/origin/dependabot/pip/cookiecutter-2.1.1 +1 -0
- s/.git/logs/refs/remotes/origin/dependabot/pip/pyyaml-5.4 +1 -1
- s/.git/logs/refs/remotes/origin/main +1 -1
- s/.git/logs/refs/remotes/origin/ray-deps +1 -1
- s/.git/logs/refs/remotes/origin/ray-dev-setup +1 -1
- s/.git/logs/refs/remotes/origin/ray-tox +1 -1
- s/.git/logs/refs/remotes/origin/release-pipeline-automation +1 -1
- s/.git/logs/refs/remotes/origin/spmcdono/fix-pipeline-test-install +1 -1
- s/.git/logs/refs/remotes/origin/spmcdono/layered-deployments +1 -1
- s/.git/logs/refs/remotes/origin/spmcdono/pypi-package-test-pipeline +1 -1
- s/.git/logs/refs/remotes/origin/spmcdono/remove-py2 +1 -1
- s/.git/logs/refs/remotes/origin/spmcdono/remove-py2-dev +1 -1
- s/.git/logs/refs/remotes/origin/spmcdono/test-native-runtime-install +1 -1
- s/.git/logs/refs/remotes/origin/spmcdono/update-pipeline +1 -1
- s/.git/logs/refs/remotes/origin/user/marine/EliiseS/devcontainer +1 -1
- s/.git/logs/refs/remotes/origin/user/marine/fixsimver +1 -1
- s/.git/logs/refs/remotes/origin/user/marine/layereddeploymentsbuildtest +1 -1
- s/.git/logs/refs/remotes/origin/user/marine/master-to-main +1 -1
- s/.git/logs/refs/remotes/origin/user/marine/pipeline +1 -1
- s/.git/logs/refs/remotes/origin/user/vikas +1 -1
- s/.git/logs/refs/remotes/origin/user/vikas0212/verify-tests +1 -1
- s/.git/logs/refs/remotes/origin/user/vikas2 +1 -1
- s/.git/logs/refs/remotes/origin/user/vikas_pypi +1 -1
- s/.git/logs/refs/remotes/origin/user/vikas_pypi-1 +1 -1
- s/.git/logs/refs/remotes/origin/user/vikas_supplychain-issue1 +1 -0
- s/.git/logs/refs/remotes/origin/user/vikas_testing +1 -1
- s/.git/logs/refs/remotes/origin/user/vikas_trigger +1 -0
- s/.git/logs/refs/remotes/origin/user/vikas_trigger_new +1 -0
- s/.git/logs/refs/remotes/origin/user/xinzed/dps_conn_str +1 -1
- s/.git/logs/refs/remotes/origin/user/xinzed/update-python-docker +1 -1
- s/.git/logs/refs/remotes/origin/vikas/azure +1 -1
- s/.git/logs/refs/remotes/origin/vikas/dependebot +1 -1
- s/.git/logs/refs/remotes/origin/vikas-triggers +1 -0
- s/.git/logs/refs/remotes/origin/xinzed/3_1_0rc1 +1 -1
- s/.git/logs/refs/remotes/origin/xinzed/update-runtime +1 -1
- s/.git/objects/pack/pack-7a60b35c219082b6cfceccd45f3712d11b9c0e3b.idx +0 -0
- s/.git/objects/pack/{pack-a8179feb7da51d11a42c37c5b3c8593cffe17075.pack → pack-7a60b35c219082b6cfceccd45f3712d11b9c0e3b.pack} +0 -0
- s/.git/refs/remotes/origin/dependabot/pip/cookiecutter-2.1.1 +1 -0
- s/.git/refs/remotes/origin/main +1 -1
- s/.git/refs/remotes/origin/user/vikas_supplychain-issue1 +1 -0
- s/.git/refs/remotes/origin/user/vikas_trigger +1 -0
- s/.git/refs/remotes/origin/user/vikas_trigger_new +1 -0
- s/.git/refs/remotes/origin/vikas-triggers +1 -0
- s/.git/refs/tags/v3.3.5 +1 -0
- s/.github/ISSUE_TEMPLATE/01_bug_report.yml +55 -0
- s/.github/ISSUE_TEMPLATE/02_feature_request.yml +14 -0
- s/.github/pull_request_template.md +35 -0
- s/.github/workflows/wiki.yml +1 -1
- s/.vscode/launch.json +2 -2
- s/.vscode/settings.json +2 -1
- s/CHANGELOG.md +63 -4
- s/CONTRIBUTING.md +30 -97
- s/Makefile +1 -2
- s/README.md +16 -169
- s/SECURITY.md +41 -0
- s/build/lib/iotedgedev/__init__.py +1 -1
- s/build/lib/iotedgedev/azurecli.py +14 -4
- s/build/lib/iotedgedev/cli.py +36 -25
- s/build/lib/iotedgedev/connectionstring.py +10 -8
- s/build/lib/iotedgedev/edge.py +1 -1
- s/dist/{iotedgedev-3.3.4-py3-none-any.whl → iotedgedev-3.3.5-py3-none-any.whl} +0 -0
- s/docker/tool/build-docker.sh +3 -3
- s/docker/tool/deps.txt +1 -1
- s/docker/tool/linux/Dockerfile.base +7 -4
- s/docker/tool/windows/Dockerfile.base +1 -1
- s/docs/_Sidebar.md +5 -4
- s/docs/{Azure-Setup.md → azure-setup.md} +19 -18
- s/docs/{Edge-Device-Setup.md → edge-device-setup.md} +5 -4
- s/docs/environment-setup/install-docker.md +9 -0
- s/docs/environment-setup/manual-dev-machine-setup.md +79 -0
- s/docs/{Python-Virtual-Environment-Setup.md → environment-setup/python-virtual-environment-setup.md} +7 -8
- s/docs/environment-setup/run-devcontainer-docker.md +24 -0
- s/docs/home.md +10 -0
- s/docs/{Migration-Guides.md → migration-guides.md} +26 -26
- s/docs/quickstart.md +152 -0
- s/docs/run-modules-on-simulator.md +18 -0
- s/docs/run-modules-on-vm.md +54 -0
- s/docs/{Troubleshooting.md → troubleshooting.md} +5 -4
- s/docs/{Usage.md → usage.md} +19 -20
- s/iotedgedev/__init__.py +1 -1
- s/iotedgedev/azurecli.py +14 -4
- s/iotedgedev/cli.py +36 -25
- s/iotedgedev/connectionstring.py +10 -8
- s/iotedgedev/edge.py +1 -1
- s/iotedgedev.egg-info/PKG-INFO +1 -1
- s/iotedgedev.egg-info/SOURCES.txt +2 -1
- s/iotedgedev.egg-info/requires.txt +1 -1
- s/requirements.txt +2 -2
- s/setup.cfg +1 -1
- s/setup.py +4 -2
- s/tests/__init__.py +1 -1
- s/tests/assets/test_solution_shared_lib/deployment.template.json +1 -1
- s/tests/assets/test_solution_shared_lib/layered_deployment.flattened_props.template.json +43 -9
- s/tests/test_iotedgedev_iothub_deploy.py +0 -1
- s/tests/test_iotedgedev_solution.py +3 -4
- s/tests/test_iotedgedev_solution_build.py +0 -19
- s/tests/test_iotedgedev_solution_deploy.py +197 -0
- s/tests/test_iotedgedev_solution_init.py +34 -0
- s/.git/logs/refs/remotes/origin/eliises/add-device-tagging-docs +0 -1
- s/.git/objects/pack/pack-a8179feb7da51d11a42c37c5b3c8593cffe17075.idx +0 -0
- s/.git/refs/remotes/origin/eliises/add-device-tagging-docs +0 -1
- s/.github/ISSUE_TEMPLATE/bug_report.md +0 -16
- s/.github/ISSUE_TEMPLATE/feature_request.md +0 -7
- s/docs/Home.md +0 -10
- s/docs/Manual-Dev-Machine-Setup.md +0 -77
- s/docs/Quickstart-with-IoT-Edge-Dev-Container.md +0 -145
- s/pull_request_template.md +0 -9
- s/tests/assets/test_solution_shared_lib/layered_deployment.no_modules.template.json +0 -12
- /s/docs/{Command-List.md → command-list.md} +0 -0
- /s/docs/{Command-Tips.md → command-tips.md} +0 -0
- /s/docs/{Overview.md → overview.md} +0 -0
- /s/docs/{Test-Coverage.md → test-coverage.md} +0 -0
s/iotedgedev/cli.py
CHANGED
|
@@ -3,6 +3,11 @@ import socket
|
|
|
3
3
|
import sys
|
|
4
4
|
|
|
5
5
|
import click
|
|
6
|
+
import copy
|
|
7
|
+
import typing as t
|
|
8
|
+
|
|
9
|
+
from click import Command
|
|
10
|
+
from click import Group
|
|
6
11
|
from fstrings import f
|
|
7
12
|
|
|
8
13
|
from .azurecli import AzureCli
|
|
@@ -19,6 +24,16 @@ from .simulator import Simulator
|
|
|
19
24
|
from .solution import Solution
|
|
20
25
|
from .utility import Utility
|
|
21
26
|
|
|
27
|
+
# Extend click.Group#add_command(cmd, name) to take deprecated=bool flag by monkey patching.
|
|
28
|
+
def add_command_with_deprecation(self, cmd: Command, name: t.Optional[str] = None, deprecated = False):
|
|
29
|
+
# Directly changing the deprecated flag of the cmd has side-effects on the reference source.
|
|
30
|
+
# To avoid this, copy the cmd object with deepcopy.
|
|
31
|
+
copied_command = copy.deepcopy(cmd)
|
|
32
|
+
copied_command.deprecated = deprecated
|
|
33
|
+
self.add_command(copied_command, name)
|
|
34
|
+
|
|
35
|
+
Group.add_command_with_deprecation = add_command_with_deprecation
|
|
36
|
+
|
|
22
37
|
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'], max_content_width=120)
|
|
23
38
|
|
|
24
39
|
output = Output()
|
|
@@ -84,14 +99,16 @@ def new(name, module, template, edge_runtime_version, group_id):
|
|
|
84
99
|
sol = Solution(output, utility)
|
|
85
100
|
sol.create(name, module, template, edge_runtime_version, group_id)
|
|
86
101
|
|
|
87
|
-
|
|
88
|
-
main.add_command(new)
|
|
102
|
+
main.add_command_with_deprecation(new, deprecated=True)
|
|
89
103
|
|
|
90
104
|
|
|
91
105
|
@solution.command(context_settings=CONTEXT_SETTINGS,
|
|
92
106
|
help="Create a new IoT Edge solution and provision Azure resources",
|
|
93
107
|
# hack to prevent Click truncating help messages
|
|
94
108
|
short_help="Create a new IoT Edge solution and provision Azure resources")
|
|
109
|
+
@click.argument("name",
|
|
110
|
+
required=False,
|
|
111
|
+
default=".")
|
|
95
112
|
@click.option("--edge-runtime-version",
|
|
96
113
|
"-er",
|
|
97
114
|
default="1.2",
|
|
@@ -100,28 +117,22 @@ main.add_command(new)
|
|
|
100
117
|
help="Specify the IoT Edge Runtime Version. Currently available 1.0, 1.1, 1.2")
|
|
101
118
|
@add_module_options(envvars, init=True)
|
|
102
119
|
@with_telemetry
|
|
103
|
-
def init(module, template, group_id, edge_runtime_version):
|
|
120
|
+
def init(name, module, template, group_id, edge_runtime_version):
|
|
104
121
|
if edge_runtime_version is not None:
|
|
105
122
|
if (str(edge_runtime_version) != "1.0" and str(edge_runtime_version) != "1.1" and str(edge_runtime_version) != "1.2"):
|
|
106
123
|
output.info('-edge-runtime-version `{0}` is not valid. Currently supported versions are 1.0, 1.1, 1.2'.format(edge_runtime_version))
|
|
107
124
|
sys.exit()
|
|
108
125
|
utility = Utility(envvars, output)
|
|
109
126
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
else:
|
|
113
|
-
solcmd = "iotedgedev new . --module {0} --template {1} --edge-runtime-version {2}".format(module, template, edge_runtime_version)
|
|
114
|
-
output.header(solcmd)
|
|
115
|
-
ret = utility.call_proc(solcmd.split())
|
|
127
|
+
sol = Solution(output, utility)
|
|
128
|
+
sol.create(name, module, template, edge_runtime_version, group_id)
|
|
116
129
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
# Had to use call_proc, because @click.invoke doesn't honor prompts
|
|
121
|
-
utility.call_proc(azsetupcmd.split())
|
|
130
|
+
azsetupcmd = "iotedgedev iothub setup --update-dotenv"
|
|
131
|
+
output.header(azsetupcmd)
|
|
132
|
+
utility.call_proc(azsetupcmd.split())
|
|
122
133
|
|
|
123
134
|
|
|
124
|
-
main.
|
|
135
|
+
main.add_command_with_deprecation(init, deprecated=True)
|
|
125
136
|
|
|
126
137
|
|
|
127
138
|
@solution.command(context_settings=CONTEXT_SETTINGS, help="Push, deploy, start, monitor")
|
|
@@ -144,7 +155,7 @@ def add(name, template, group_id):
|
|
|
144
155
|
mod.add(name, template, group_id)
|
|
145
156
|
|
|
146
157
|
|
|
147
|
-
main.
|
|
158
|
+
main.add_command_with_deprecation(add, deprecated=True)
|
|
148
159
|
|
|
149
160
|
|
|
150
161
|
@solution.command(context_settings=CONTEXT_SETTINGS, help="Build the solution")
|
|
@@ -186,7 +197,7 @@ def build(ctx, push, do_deploy, template_file, platform):
|
|
|
186
197
|
ctx.invoke(deploy)
|
|
187
198
|
|
|
188
199
|
|
|
189
|
-
main.
|
|
200
|
+
main.add_command_with_deprecation(build, deprecated=True)
|
|
190
201
|
|
|
191
202
|
|
|
192
203
|
@solution.command(context_settings=CONTEXT_SETTINGS, help="Push module images to container registry")
|
|
@@ -227,7 +238,7 @@ def push(ctx, do_deploy, no_build, template_file, platform):
|
|
|
227
238
|
ctx.invoke(deploy)
|
|
228
239
|
|
|
229
240
|
|
|
230
|
-
main.
|
|
241
|
+
main.add_command_with_deprecation(push, deprecated=True)
|
|
231
242
|
|
|
232
243
|
|
|
233
244
|
@solution.command(context_settings=CONTEXT_SETTINGS, help="Deploy solution to IoT Edge device")
|
|
@@ -245,7 +256,7 @@ def deploy(manifest_file):
|
|
|
245
256
|
edge.deploy(manifest_file)
|
|
246
257
|
|
|
247
258
|
|
|
248
|
-
main.
|
|
259
|
+
main.add_command_with_deprecation(deploy, deprecated=True)
|
|
249
260
|
|
|
250
261
|
|
|
251
262
|
@iothub.command(
|
|
@@ -340,7 +351,7 @@ def genconfig(template_file, platform, fail_on_validation_error):
|
|
|
340
351
|
mod.build_push(template_file, platform, no_build=True, no_push=True, fail_on_validation_error=fail_on_validation_error)
|
|
341
352
|
|
|
342
353
|
|
|
343
|
-
main.
|
|
354
|
+
main.add_command_with_deprecation(genconfig, deprecated=True)
|
|
344
355
|
|
|
345
356
|
|
|
346
357
|
@simulator.command(context_settings=CONTEXT_SETTINGS,
|
|
@@ -363,7 +374,7 @@ def setup_simulator(gateway_host, iothub_connection_string):
|
|
|
363
374
|
sim.setup(gateway_host, iothub_connection_string)
|
|
364
375
|
|
|
365
376
|
|
|
366
|
-
main.
|
|
377
|
+
main.add_command_with_deprecation(setup_simulator, deprecated=True)
|
|
367
378
|
|
|
368
379
|
|
|
369
380
|
@simulator.command(context_settings=CONTEXT_SETTINGS,
|
|
@@ -438,7 +449,7 @@ def start_simulator(setup, solution, build, manifest_file, platform, verbose, in
|
|
|
438
449
|
sim.start_single(inputs, port)
|
|
439
450
|
|
|
440
451
|
|
|
441
|
-
main.
|
|
452
|
+
main.add_command_with_deprecation(start_simulator, deprecated=True)
|
|
442
453
|
|
|
443
454
|
|
|
444
455
|
@simulator.command(context_settings=CONTEXT_SETTINGS,
|
|
@@ -450,7 +461,7 @@ def stop_simulator():
|
|
|
450
461
|
sim.stop()
|
|
451
462
|
|
|
452
463
|
|
|
453
|
-
main.
|
|
464
|
+
main.add_command_with_deprecation(stop_simulator, deprecated=True)
|
|
454
465
|
|
|
455
466
|
|
|
456
467
|
@simulator.command(context_settings=CONTEXT_SETTINGS,
|
|
@@ -490,7 +501,7 @@ def monitor(timeout):
|
|
|
490
501
|
ih.monitor_events(timeout)
|
|
491
502
|
|
|
492
503
|
|
|
493
|
-
main.
|
|
504
|
+
main.add_command_with_deprecation(monitor, deprecated=True)
|
|
494
505
|
|
|
495
506
|
|
|
496
507
|
def ensure_azure_cli_iot_ext():
|
|
@@ -824,7 +835,7 @@ def log(show, save):
|
|
|
824
835
|
dock.handle_logs_cmd(show, save)
|
|
825
836
|
|
|
826
837
|
|
|
827
|
-
main.
|
|
838
|
+
main.add_command_with_deprecation(log, deprecated=True)
|
|
828
839
|
|
|
829
840
|
if __name__ == "__main__":
|
|
830
841
|
main()
|
s/iotedgedev/connectionstring.py
CHANGED
|
@@ -2,8 +2,8 @@ from .utility import Utility
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class ConnectionString:
|
|
5
|
-
def __init__(self,
|
|
6
|
-
self.connection_string =
|
|
5
|
+
def __init__(self, connection_string: str):
|
|
6
|
+
self.connection_string = connection_string
|
|
7
7
|
self.data = dict()
|
|
8
8
|
|
|
9
9
|
if self.connection_string:
|
|
@@ -22,25 +22,27 @@ class ConnectionString:
|
|
|
22
22
|
else:
|
|
23
23
|
# unexpected input of connection. Set to None and throw error
|
|
24
24
|
self.connection_string = None
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
def __getitem__(self, key):
|
|
27
27
|
return self.data[key]
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
class IoTHubConnectionString(ConnectionString):
|
|
31
|
-
def __init__(self,
|
|
32
|
-
|
|
31
|
+
def __init__(self, connection_string: str):
|
|
32
|
+
super().__init__(connection_string)
|
|
33
33
|
|
|
34
34
|
if self.connection_string:
|
|
35
35
|
self.shared_access_key_name = self["sharedaccesskeyname"]
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
class DeviceConnectionString(ConnectionString):
|
|
39
|
-
def __init__(self,
|
|
40
|
-
|
|
39
|
+
def __init__(self, connection_string: str):
|
|
40
|
+
super().__init__(connection_string)
|
|
41
41
|
|
|
42
|
-
if self.
|
|
42
|
+
if("deviceid" in self.data):
|
|
43
43
|
self.device_id = self["deviceid"]
|
|
44
|
+
else:
|
|
45
|
+
self.device_id = None
|
|
44
46
|
|
|
45
47
|
|
|
46
48
|
class IoTHubHost:
|
s/iotedgedev/edge.py
CHANGED
|
@@ -14,7 +14,7 @@ class Edge:
|
|
|
14
14
|
self.output.header("DEPLOYING CONFIGURATION")
|
|
15
15
|
|
|
16
16
|
self.envvars.verify_envvar_has_val("IOTHUB_CONNECTION_STRING", self.envvars.IOTHUB_CONNECTION_INFO)
|
|
17
|
-
self.envvars.verify_envvar_has_val("
|
|
17
|
+
self.envvars.verify_envvar_has_val("EDGE_DEVICE_ID", self.envvars.DEVICE_CONNECTION_INFO.device_id)
|
|
18
18
|
self.envvars.verify_envvar_has_val("DEPLOYMENT_CONFIG_FILE", self.envvars.DEPLOYMENT_CONFIG_FILE)
|
|
19
19
|
|
|
20
20
|
if self.azure_cli.set_modules(config=manifest_file,
|
s/iotedgedev.egg-info/PKG-INFO
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 1.2
|
|
2
2
|
Name: iotedgedev
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.5
|
|
4
4
|
Summary: The Azure IoT Edge Dev Tool greatly simplifies the IoT Edge development process by automating many routine manual tasks, such as building, deploying, pushing modules and configuring the IoT Edge Runtime.
|
|
5
5
|
Home-page: https://github.com/azure/iotedgedev
|
|
6
6
|
Author: Microsoft Corporation
|
|
@@ -59,6 +59,8 @@ tests/test_iotedgedev_iothub_deploy.py
|
|
|
59
59
|
tests/test_iotedgedev_simulator.py
|
|
60
60
|
tests/test_iotedgedev_solution.py
|
|
61
61
|
tests/test_iotedgedev_solution_build.py
|
|
62
|
+
tests/test_iotedgedev_solution_deploy.py
|
|
63
|
+
tests/test_iotedgedev_solution_init.py
|
|
62
64
|
tests/test_iotedgedev_solution_tag.py
|
|
63
65
|
tests/test_utility.py
|
|
64
66
|
tests/utility.py
|
|
@@ -79,7 +81,6 @@ tests/assets/test_solution_shared_lib/deployment.debug.template.json
|
|
|
79
81
|
tests/assets/test_solution_shared_lib/deployment.escapedpath.template.json
|
|
80
82
|
tests/assets/test_solution_shared_lib/deployment.template.json
|
|
81
83
|
tests/assets/test_solution_shared_lib/layered_deployment.flattened_props.template.json
|
|
82
|
-
tests/assets/test_solution_shared_lib/layered_deployment.no_modules.template.json
|
|
83
84
|
tests/assets/test_solution_shared_lib/.vscode/launch.json
|
|
84
85
|
tests/assets/test_solution_shared_lib/libs/sharedlib/Class1.cs
|
|
85
86
|
tests/assets/test_solution_shared_lib/libs/sharedlib/sharedlib.csproj
|
s/requirements.txt
CHANGED
|
@@ -3,10 +3,10 @@ docker==5.0.3
|
|
|
3
3
|
python-dotenv==0.19.0
|
|
4
4
|
requests==2.25.1
|
|
5
5
|
fstrings==0.1.0
|
|
6
|
-
msrestazure==0.4
|
|
6
|
+
msrestazure==0.6.4
|
|
7
7
|
iotedgehubdev==0.14.14
|
|
8
8
|
applicationinsights==0.11.9
|
|
9
9
|
commentjson==0.9.0
|
|
10
|
-
azure-cli-core==2.
|
|
10
|
+
azure-cli-core==2.34.1
|
|
11
11
|
pypiwin32==219; sys_platform == 'win32' and python_version < '3.6'
|
|
12
12
|
pypiwin32==223; sys_platform == 'win32' and python_version >= '3.6'
|
s/setup.cfg
CHANGED
s/setup.py
CHANGED
|
@@ -12,7 +12,9 @@ requirements = [
|
|
|
12
12
|
'python-dotenv',
|
|
13
13
|
'requests >= 2.20.0, <= 2.25.1',
|
|
14
14
|
'fstrings',
|
|
15
|
-
|
|
15
|
+
# Note >=2.35.0 cannot be used as is not compatible with the docker dependency;
|
|
16
|
+
# docker requires websocket-client==0.56.0 and azure-cli-core>=2.35.0 requires websocket-client==1.31.1.
|
|
17
|
+
'azure-cli-core >= 2.34.1, < 2.35.0',
|
|
16
18
|
'iotedgehubdev == 0.14.14',
|
|
17
19
|
'applicationinsights == 0.11.9',
|
|
18
20
|
'commentjson == 0.9.0',
|
|
@@ -31,7 +33,7 @@ test_requirements = [
|
|
|
31
33
|
|
|
32
34
|
setup(
|
|
33
35
|
name='iotedgedev',
|
|
34
|
-
version='3.3.
|
|
36
|
+
version='3.3.5',
|
|
35
37
|
description='The Azure IoT Edge Dev Tool greatly simplifies the IoT Edge development process by automating many routine manual tasks, such as building, deploying, pushing modules and configuring the IoT Edge Runtime.',
|
|
36
38
|
long_description='See https://github.com/azure/iotedgedev for usage instructions.',
|
|
37
39
|
author='Microsoft Corporation',
|
s/tests/__init__.py
CHANGED
|
@@ -2,19 +2,53 @@
|
|
|
2
2
|
"content": {
|
|
3
3
|
"modulesContent": {
|
|
4
4
|
"$edgeAgent": {
|
|
5
|
-
"properties.desired
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
"
|
|
5
|
+
"properties.desired": {
|
|
6
|
+
"schemaVersion": "${EDGEAGENT_SCHEMA_VERSION}",
|
|
7
|
+
"runtime": {
|
|
8
|
+
"type": "docker",
|
|
9
|
+
"settings": {
|
|
10
|
+
"minDockerVersion": "v1.25",
|
|
11
|
+
"loggingOptions": "",
|
|
12
|
+
"registryCredentials": {}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"modules": {
|
|
16
|
+
"sample_module": {
|
|
17
|
+
"version": "1.0",
|
|
18
|
+
"type": "docker",
|
|
19
|
+
"status": "running",
|
|
20
|
+
"restartPolicy": "always",
|
|
21
|
+
"settings": {
|
|
22
|
+
"image": "${MODULES.sample_module}",
|
|
23
|
+
"createOptions": {}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"systemModules": {
|
|
28
|
+
"edgeAgent": {
|
|
29
|
+
"type": "docker",
|
|
30
|
+
"settings": {
|
|
31
|
+
"image": "mcr.microsoft.com/azureiotedge-agent:${EDGE_RUNTIME_VERSION}"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"edgeHub": {
|
|
35
|
+
"type": "docker",
|
|
36
|
+
"status": "running",
|
|
37
|
+
"settings": {
|
|
38
|
+
"image": "mcr.microsoft.com/azureiotedge-hub:${EDGE_RUNTIME_VERSION}"
|
|
39
|
+
},
|
|
40
|
+
"restartPolicy": "always"
|
|
41
|
+
}
|
|
13
42
|
}
|
|
14
43
|
}
|
|
15
44
|
},
|
|
16
45
|
"$edgeHub": {
|
|
17
|
-
"properties.desired
|
|
46
|
+
"properties.desired": {
|
|
47
|
+
"schemaVersion": "${EDGEHUB_SCHEMA_VERSION}",
|
|
48
|
+
"routes": {
|
|
49
|
+
"route": "FROM /messages/* INTO $upstream"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
18
52
|
}
|
|
19
53
|
}
|
|
20
54
|
}
|
|
@@ -21,7 +21,6 @@ test_solution_shared_lib_dir = os.path.join(os.getcwd(), "tests", "assets", "tes
|
|
|
21
21
|
"config, manifest",
|
|
22
22
|
[
|
|
23
23
|
("layered_deployment.flattened_props.template.json", "layered_deployment.flattened_props.json"),
|
|
24
|
-
("layered_deployment.no_modules.template.json", "layered_deployment.no_modules.json"),
|
|
25
24
|
("deployment.template.json", f"deployment.{get_platform_type()}.json")
|
|
26
25
|
]
|
|
27
26
|
)
|
|
@@ -201,7 +201,7 @@ def test_module_add_invalid_name(prepare_solution_with_env):
|
|
|
201
201
|
assert "already exists under" in result.output
|
|
202
202
|
|
|
203
203
|
|
|
204
|
-
@pytest.fixture
|
|
204
|
+
@ pytest.fixture
|
|
205
205
|
def test_push_modules():
|
|
206
206
|
result = runner_invoke(['push', '-P', get_platform_type()])
|
|
207
207
|
|
|
@@ -210,7 +210,7 @@ def test_push_modules():
|
|
|
210
210
|
assert 'ERROR' not in result.output
|
|
211
211
|
|
|
212
212
|
|
|
213
|
-
@pytest.fixture
|
|
213
|
+
@ pytest.fixture
|
|
214
214
|
def test_deploy_modules():
|
|
215
215
|
if get_docker_os_type() == "windows":
|
|
216
216
|
result = runner_invoke(['deploy', '-f', os.path.join('config', 'deployment.' + get_platform_type() + '.json')])
|
|
@@ -221,7 +221,7 @@ def test_deploy_modules():
|
|
|
221
221
|
assert 'ERROR' not in result.output.replace('ERROR: Error while checking for extension', '')
|
|
222
222
|
|
|
223
223
|
|
|
224
|
-
@pytest.fixture
|
|
224
|
+
@ pytest.fixture
|
|
225
225
|
def test_monitor(capfd):
|
|
226
226
|
runner_invoke(['monitor', '--timeout', '5'])
|
|
227
227
|
|
|
@@ -371,7 +371,6 @@ def test_validate_deployment_template_and_manifest_success():
|
|
|
371
371
|
result = runner_invoke(['genconfig', '-f', deployment_file_name])
|
|
372
372
|
|
|
373
373
|
assert "ERROR" not in result.output
|
|
374
|
-
assert "Deployment manifest schema validation passed" in result.output
|
|
375
374
|
assert "Warning: Deployment manifest schema validation failed" not in result.output
|
|
376
375
|
assert "Validation for all createOptions passed" in result.output
|
|
377
376
|
assert "Warning: Errors found during createOptions validation" not in result.output
|
|
@@ -69,25 +69,6 @@ def test_solution_build_and_push_with_layered_deployment():
|
|
|
69
69
|
assert 'ERROR' not in result.output
|
|
70
70
|
|
|
71
71
|
|
|
72
|
-
def test_solution_build_and_push_with_layered_deployment_no_modules():
|
|
73
|
-
# Arrange
|
|
74
|
-
os.chdir(test_solution_shared_lib_dir)
|
|
75
|
-
new_config_deployment_path = os.path.join(test_solution_shared_lib_dir, 'config', 'layered_deployment.no_modules.json')
|
|
76
|
-
|
|
77
|
-
# Act
|
|
78
|
-
result = runner_invoke(['build', '--push', '-f', "layered_deployment.no_modules.template.json", '-P', get_platform_type()])
|
|
79
|
-
|
|
80
|
-
# Assert
|
|
81
|
-
|
|
82
|
-
with open(new_config_deployment_path, "r") as f:
|
|
83
|
-
content = json.load(f)
|
|
84
|
-
|
|
85
|
-
set_property = content["content"]["modulesContent"]["exampleModule"]["properties.desired"]["foo"]
|
|
86
|
-
|
|
87
|
-
assert 'ERROR' not in result.output
|
|
88
|
-
assert 'bar-1.2' == set_property
|
|
89
|
-
|
|
90
|
-
|
|
91
72
|
def test_solution_build_and_push_with_platform():
|
|
92
73
|
os.chdir(test_solution_shared_lib_dir)
|
|
93
74
|
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import shutil
|
|
4
|
+
import time
|
|
5
|
+
from unittest import mock
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
from iotedgedev.envvars import EnvVars
|
|
9
|
+
from iotedgedev.output import Output
|
|
10
|
+
from iotedgedev.version import PY35
|
|
11
|
+
|
|
12
|
+
from .utility import (get_docker_os_type,
|
|
13
|
+
get_platform_type, runner_invoke)
|
|
14
|
+
|
|
15
|
+
pytestmark = pytest.mark.e2e
|
|
16
|
+
|
|
17
|
+
output = Output()
|
|
18
|
+
envvars = EnvVars(output)
|
|
19
|
+
|
|
20
|
+
root_dir = os.getcwd()
|
|
21
|
+
tests_dir = os.path.join(root_dir, "tests")
|
|
22
|
+
tests_assets_dir = os.path.join(tests_dir, "assets")
|
|
23
|
+
|
|
24
|
+
env_file_name = envvars.get_dotenv_file()
|
|
25
|
+
env_file_path = envvars.get_dotenv_path(env_file_name)
|
|
26
|
+
|
|
27
|
+
launch_json_file = os.path.join(tests_dir, "assets", "launch.json")
|
|
28
|
+
launch_json_file_without_nodejs = os.path.join(tests_dir, "assets", "launch_without_nodejs.json")
|
|
29
|
+
|
|
30
|
+
test_solution = "test_solution"
|
|
31
|
+
test_solution_dir = os.path.join(tests_dir, test_solution)
|
|
32
|
+
|
|
33
|
+
test_solution_shared_lib = "test_solution_shared_lib"
|
|
34
|
+
test_solution_shared_lib_dir = os.path.join(tests_dir, "assets", test_solution_shared_lib)
|
|
35
|
+
|
|
36
|
+
templates = ["c", "csharp", "java", "nodejs", "python", "csharpfunction"]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def create_solution(template, custom_module_name=None):
|
|
40
|
+
if custom_module_name is None:
|
|
41
|
+
module_name = template + "module"
|
|
42
|
+
else:
|
|
43
|
+
module_name = custom_module_name
|
|
44
|
+
result = runner_invoke(['new', test_solution, '-m', module_name, '-t', template])
|
|
45
|
+
|
|
46
|
+
return result
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def clean_folder(folder_path):
|
|
50
|
+
os.chdir(tests_dir)
|
|
51
|
+
time.sleep(5)
|
|
52
|
+
shutil.rmtree(folder_path, ignore_errors=True)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@pytest.fixture
|
|
56
|
+
def prepare_solution_with_env():
|
|
57
|
+
os.chdir(tests_dir)
|
|
58
|
+
|
|
59
|
+
template = "csharp"
|
|
60
|
+
module_name = "filtermodule"
|
|
61
|
+
result = create_solution(template, module_name)
|
|
62
|
+
if 'AZURE IOT EDGE SOLUTION CREATED' not in result.output:
|
|
63
|
+
raise Exception(result.stdout)
|
|
64
|
+
|
|
65
|
+
shutil.copyfile(env_file_path, os.path.join(test_solution_dir, env_file_name))
|
|
66
|
+
|
|
67
|
+
os.chdir(test_solution_dir)
|
|
68
|
+
|
|
69
|
+
yield prepare_solution_with_env
|
|
70
|
+
clean_folder(test_solution_dir)
|
|
71
|
+
|
|
72
|
+
return
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def assert_solution_folder_structure(template):
|
|
76
|
+
module_name = template + "module"
|
|
77
|
+
|
|
78
|
+
expected_files = [".env", "deployment.template.json", "deployment.debug.template.json",
|
|
79
|
+
os.path.join(".vscode", "launch.json"),
|
|
80
|
+
os.path.join("modules", module_name, "Dockerfile.amd64"),
|
|
81
|
+
os.path.join("modules", module_name, "Dockerfile.amd64.debug"),
|
|
82
|
+
os.path.join("modules", module_name, "Dockerfile.arm32v7"),
|
|
83
|
+
os.path.join("modules", module_name, "module.json")]
|
|
84
|
+
for expected_file in expected_files:
|
|
85
|
+
assert os.path.exists(os.path.join(test_solution_dir, expected_file))
|
|
86
|
+
|
|
87
|
+
expected_template_files = [os.environ["DEPLOYMENT_CONFIG_TEMPLATE_FILE"], os.environ["DEPLOYMENT_CONFIG_DEBUG_TEMPLATE_FILE"]]
|
|
88
|
+
|
|
89
|
+
for expected_template_file in expected_template_files:
|
|
90
|
+
with open(os.path.join(test_solution_dir, expected_template_file)) as f:
|
|
91
|
+
content = json.load(f)
|
|
92
|
+
|
|
93
|
+
assert module_name in content["modulesContent"]["$edgeAgent"]["properties.desired"]["modules"]
|
|
94
|
+
assert module_name in content["modulesContent"]["$edgeAgent"]["properties.desired"]["modules"][module_name]["settings"]["image"]
|
|
95
|
+
assert module_name in content["modulesContent"]["$edgeHub"]["properties.desired"]["routes"]["sensorTo" + module_name]
|
|
96
|
+
assert module_name in content["modulesContent"]["$edgeHub"]["properties.desired"]["routes"][module_name + "ToIoTHub"]
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def assert_module_folder_structure(template):
|
|
100
|
+
module_name = template + "module"
|
|
101
|
+
expected_template_files = [os.environ["DEPLOYMENT_CONFIG_TEMPLATE_FILE"], os.environ["DEPLOYMENT_CONFIG_DEBUG_TEMPLATE_FILE"]]
|
|
102
|
+
|
|
103
|
+
for expected_template_file in expected_template_files:
|
|
104
|
+
with open(expected_template_file) as f:
|
|
105
|
+
content = json.load(f)
|
|
106
|
+
|
|
107
|
+
assert module_name in content["modulesContent"]["$edgeAgent"]["properties.desired"]["modules"]
|
|
108
|
+
assert module_name in content["modulesContent"]["$edgeAgent"]["properties.desired"]["modules"][module_name]["settings"]["image"]
|
|
109
|
+
assert module_name in content["modulesContent"]["$edgeHub"]["properties.desired"]["routes"][module_name + "ToIoTHub"]
|
|
110
|
+
|
|
111
|
+
if expected_template_file == os.environ["DEPLOYMENT_CONFIG_DEBUG_TEMPLATE_FILE"]:
|
|
112
|
+
if module_name in ["cmodule", "pythonmodule", "nodejsmodule", "javamodule"]:
|
|
113
|
+
assert "HostConfig" in content["modulesContent"]["$edgeAgent"]["properties.desired"]["modules"][module_name]["settings"]["createOptions"]
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@pytest.fixture
|
|
117
|
+
def test_push_modules():
|
|
118
|
+
result = runner_invoke(['push', '-P', get_platform_type()])
|
|
119
|
+
|
|
120
|
+
assert 'BUILD COMPLETE' in result.output
|
|
121
|
+
assert 'PUSH COMPLETE' in result.output
|
|
122
|
+
assert 'ERROR' not in result.output
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
@pytest.fixture
|
|
126
|
+
def test_deploy_modules():
|
|
127
|
+
if get_docker_os_type() == "windows":
|
|
128
|
+
result = runner_invoke(['deploy', '-f', os.path.join('config', 'deployment.' + get_platform_type() + '.json')])
|
|
129
|
+
else:
|
|
130
|
+
result = runner_invoke(['deploy'])
|
|
131
|
+
|
|
132
|
+
assert 'DEPLOYMENT COMPLETE' in result.output
|
|
133
|
+
assert 'ERROR' not in result.output.replace('ERROR: Error while checking for extension', '')
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@pytest.fixture
|
|
137
|
+
def test_monitor(capfd):
|
|
138
|
+
runner_invoke(['monitor', '--timeout', '5'])
|
|
139
|
+
|
|
140
|
+
out, err = capfd.readouterr()
|
|
141
|
+
if not PY35:
|
|
142
|
+
assert 'Monitoring events from device' in out
|
|
143
|
+
else:
|
|
144
|
+
assert not err
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def get_connection_string_value(key: str) -> str:
|
|
148
|
+
|
|
149
|
+
connection_string_values = os.environ["DEVICE_CONNECTION_STRING"].split(';')
|
|
150
|
+
device_id = None
|
|
151
|
+
|
|
152
|
+
for item in connection_string_values:
|
|
153
|
+
if key in item:
|
|
154
|
+
device_id = item.split('=')[1]
|
|
155
|
+
|
|
156
|
+
return device_id
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@ mock.patch.dict(os.environ, {"DEVICE_CONNECTION_STRING": f"HostName={get_connection_string_value('HostName')};DeviceId={get_connection_string_value('DeviceId')};=testaccesskey"})
|
|
160
|
+
def test_solution_deploy_with_sas_connection_string():
|
|
161
|
+
# Arrange
|
|
162
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
163
|
+
|
|
164
|
+
# Act
|
|
165
|
+
result = runner_invoke(['solution', 'deploy'])
|
|
166
|
+
|
|
167
|
+
# Assert
|
|
168
|
+
assert 'DEPLOYMENT COMPLETE' in result.output
|
|
169
|
+
assert 'ERROR' not in result.output
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
@ mock.patch.dict(os.environ, {"DEVICE_CONNECTION_STRING": f"HostName={get_connection_string_value('HostName')};DeviceId={get_connection_string_value('DeviceId')};x509=true;"})
|
|
173
|
+
def test_solution_deploy_with_x509_connection_string():
|
|
174
|
+
# Arrange
|
|
175
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
176
|
+
|
|
177
|
+
# Act
|
|
178
|
+
runner_invoke(['build', '-f', "deployment.template.json", '-P', get_platform_type()])
|
|
179
|
+
result = runner_invoke(['solution', 'deploy'])
|
|
180
|
+
|
|
181
|
+
# Assert
|
|
182
|
+
assert 'DEPLOYMENT COMPLETE' in result.output
|
|
183
|
+
assert 'ERROR' not in result.output
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@ mock.patch.dict(os.environ, {"DEVICE_CONNECTION_STRING": "HostName=test-iothub.azure-devices.net;SharedAccessKey=testaccesskey"})
|
|
187
|
+
def test_connection_string_no_device_id_throws_env_error():
|
|
188
|
+
# Arrange
|
|
189
|
+
os.chdir(test_solution_shared_lib_dir)
|
|
190
|
+
|
|
191
|
+
# Act
|
|
192
|
+
runner_invoke(['build', '-f', "deployment.template.json", '-P', get_platform_type()])
|
|
193
|
+
with pytest.raises(Exception) as context:
|
|
194
|
+
runner_invoke(['solution', 'deploy'])
|
|
195
|
+
|
|
196
|
+
# Assert
|
|
197
|
+
assert "ERROR: Environment Variable EDGE_DEVICE_ID not set." in str(context.value)
|