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.
Files changed (122) hide show
  1. s/.git/FETCH_HEAD +2 -1
  2. s/.git/HEAD +1 -1
  3. s/.git/hooks/fsmonitor-watchman.sample +3 -2
  4. s/.git/index +0 -0
  5. s/.git/logs/HEAD +1 -1
  6. s/.git/logs/refs/remotes/origin/EO +1 -1
  7. s/.git/logs/refs/remotes/origin/avagraw/security_fix +1 -1
  8. s/.git/logs/refs/remotes/origin/cherry-pick-rename +1 -1
  9. s/.git/logs/refs/remotes/origin/chyuan/fix-validation-not-fail-test +1 -1
  10. s/.git/logs/refs/remotes/origin/chyuan/update-linux-agent +1 -1
  11. s/.git/logs/refs/remotes/origin/dependabot/pip/cookiecutter-2.1.1 +1 -0
  12. s/.git/logs/refs/remotes/origin/dependabot/pip/pyyaml-5.4 +1 -1
  13. s/.git/logs/refs/remotes/origin/main +1 -1
  14. s/.git/logs/refs/remotes/origin/ray-deps +1 -1
  15. s/.git/logs/refs/remotes/origin/ray-dev-setup +1 -1
  16. s/.git/logs/refs/remotes/origin/ray-tox +1 -1
  17. s/.git/logs/refs/remotes/origin/release-pipeline-automation +1 -1
  18. s/.git/logs/refs/remotes/origin/spmcdono/fix-pipeline-test-install +1 -1
  19. s/.git/logs/refs/remotes/origin/spmcdono/layered-deployments +1 -1
  20. s/.git/logs/refs/remotes/origin/spmcdono/pypi-package-test-pipeline +1 -1
  21. s/.git/logs/refs/remotes/origin/spmcdono/remove-py2 +1 -1
  22. s/.git/logs/refs/remotes/origin/spmcdono/remove-py2-dev +1 -1
  23. s/.git/logs/refs/remotes/origin/spmcdono/test-native-runtime-install +1 -1
  24. s/.git/logs/refs/remotes/origin/spmcdono/update-pipeline +1 -1
  25. s/.git/logs/refs/remotes/origin/user/marine/EliiseS/devcontainer +1 -1
  26. s/.git/logs/refs/remotes/origin/user/marine/fixsimver +1 -1
  27. s/.git/logs/refs/remotes/origin/user/marine/layereddeploymentsbuildtest +1 -1
  28. s/.git/logs/refs/remotes/origin/user/marine/master-to-main +1 -1
  29. s/.git/logs/refs/remotes/origin/user/marine/pipeline +1 -1
  30. s/.git/logs/refs/remotes/origin/user/vikas +1 -1
  31. s/.git/logs/refs/remotes/origin/user/vikas0212/verify-tests +1 -1
  32. s/.git/logs/refs/remotes/origin/user/vikas2 +1 -1
  33. s/.git/logs/refs/remotes/origin/user/vikas_pypi +1 -1
  34. s/.git/logs/refs/remotes/origin/user/vikas_pypi-1 +1 -1
  35. s/.git/logs/refs/remotes/origin/user/vikas_supplychain-issue1 +1 -0
  36. s/.git/logs/refs/remotes/origin/user/vikas_testing +1 -1
  37. s/.git/logs/refs/remotes/origin/user/vikas_trigger +1 -0
  38. s/.git/logs/refs/remotes/origin/user/vikas_trigger_new +1 -0
  39. s/.git/logs/refs/remotes/origin/user/xinzed/dps_conn_str +1 -1
  40. s/.git/logs/refs/remotes/origin/user/xinzed/update-python-docker +1 -1
  41. s/.git/logs/refs/remotes/origin/vikas/azure +1 -1
  42. s/.git/logs/refs/remotes/origin/vikas/dependebot +1 -1
  43. s/.git/logs/refs/remotes/origin/vikas-triggers +1 -0
  44. s/.git/logs/refs/remotes/origin/xinzed/3_1_0rc1 +1 -1
  45. s/.git/logs/refs/remotes/origin/xinzed/update-runtime +1 -1
  46. s/.git/objects/pack/pack-7a60b35c219082b6cfceccd45f3712d11b9c0e3b.idx +0 -0
  47. s/.git/objects/pack/{pack-a8179feb7da51d11a42c37c5b3c8593cffe17075.pack → pack-7a60b35c219082b6cfceccd45f3712d11b9c0e3b.pack} +0 -0
  48. s/.git/refs/remotes/origin/dependabot/pip/cookiecutter-2.1.1 +1 -0
  49. s/.git/refs/remotes/origin/main +1 -1
  50. s/.git/refs/remotes/origin/user/vikas_supplychain-issue1 +1 -0
  51. s/.git/refs/remotes/origin/user/vikas_trigger +1 -0
  52. s/.git/refs/remotes/origin/user/vikas_trigger_new +1 -0
  53. s/.git/refs/remotes/origin/vikas-triggers +1 -0
  54. s/.git/refs/tags/v3.3.5 +1 -0
  55. s/.github/ISSUE_TEMPLATE/01_bug_report.yml +55 -0
  56. s/.github/ISSUE_TEMPLATE/02_feature_request.yml +14 -0
  57. s/.github/pull_request_template.md +35 -0
  58. s/.github/workflows/wiki.yml +1 -1
  59. s/.vscode/launch.json +2 -2
  60. s/.vscode/settings.json +2 -1
  61. s/CHANGELOG.md +63 -4
  62. s/CONTRIBUTING.md +30 -97
  63. s/Makefile +1 -2
  64. s/README.md +16 -169
  65. s/SECURITY.md +41 -0
  66. s/build/lib/iotedgedev/__init__.py +1 -1
  67. s/build/lib/iotedgedev/azurecli.py +14 -4
  68. s/build/lib/iotedgedev/cli.py +36 -25
  69. s/build/lib/iotedgedev/connectionstring.py +10 -8
  70. s/build/lib/iotedgedev/edge.py +1 -1
  71. s/dist/{iotedgedev-3.3.4-py3-none-any.whl → iotedgedev-3.3.5-py3-none-any.whl} +0 -0
  72. s/docker/tool/build-docker.sh +3 -3
  73. s/docker/tool/deps.txt +1 -1
  74. s/docker/tool/linux/Dockerfile.base +7 -4
  75. s/docker/tool/windows/Dockerfile.base +1 -1
  76. s/docs/_Sidebar.md +5 -4
  77. s/docs/{Azure-Setup.md → azure-setup.md} +19 -18
  78. s/docs/{Edge-Device-Setup.md → edge-device-setup.md} +5 -4
  79. s/docs/environment-setup/install-docker.md +9 -0
  80. s/docs/environment-setup/manual-dev-machine-setup.md +79 -0
  81. s/docs/{Python-Virtual-Environment-Setup.md → environment-setup/python-virtual-environment-setup.md} +7 -8
  82. s/docs/environment-setup/run-devcontainer-docker.md +24 -0
  83. s/docs/home.md +10 -0
  84. s/docs/{Migration-Guides.md → migration-guides.md} +26 -26
  85. s/docs/quickstart.md +152 -0
  86. s/docs/run-modules-on-simulator.md +18 -0
  87. s/docs/run-modules-on-vm.md +54 -0
  88. s/docs/{Troubleshooting.md → troubleshooting.md} +5 -4
  89. s/docs/{Usage.md → usage.md} +19 -20
  90. s/iotedgedev/__init__.py +1 -1
  91. s/iotedgedev/azurecli.py +14 -4
  92. s/iotedgedev/cli.py +36 -25
  93. s/iotedgedev/connectionstring.py +10 -8
  94. s/iotedgedev/edge.py +1 -1
  95. s/iotedgedev.egg-info/PKG-INFO +1 -1
  96. s/iotedgedev.egg-info/SOURCES.txt +2 -1
  97. s/iotedgedev.egg-info/requires.txt +1 -1
  98. s/requirements.txt +2 -2
  99. s/setup.cfg +1 -1
  100. s/setup.py +4 -2
  101. s/tests/__init__.py +1 -1
  102. s/tests/assets/test_solution_shared_lib/deployment.template.json +1 -1
  103. s/tests/assets/test_solution_shared_lib/layered_deployment.flattened_props.template.json +43 -9
  104. s/tests/test_iotedgedev_iothub_deploy.py +0 -1
  105. s/tests/test_iotedgedev_solution.py +3 -4
  106. s/tests/test_iotedgedev_solution_build.py +0 -19
  107. s/tests/test_iotedgedev_solution_deploy.py +197 -0
  108. s/tests/test_iotedgedev_solution_init.py +34 -0
  109. s/.git/logs/refs/remotes/origin/eliises/add-device-tagging-docs +0 -1
  110. s/.git/objects/pack/pack-a8179feb7da51d11a42c37c5b3c8593cffe17075.idx +0 -0
  111. s/.git/refs/remotes/origin/eliises/add-device-tagging-docs +0 -1
  112. s/.github/ISSUE_TEMPLATE/bug_report.md +0 -16
  113. s/.github/ISSUE_TEMPLATE/feature_request.md +0 -7
  114. s/docs/Home.md +0 -10
  115. s/docs/Manual-Dev-Machine-Setup.md +0 -77
  116. s/docs/Quickstart-with-IoT-Edge-Dev-Container.md +0 -145
  117. s/pull_request_template.md +0 -9
  118. s/tests/assets/test_solution_shared_lib/layered_deployment.no_modules.template.json +0 -12
  119. /s/docs/{Command-List.md → command-list.md} +0 -0
  120. /s/docs/{Command-Tips.md → command-tips.md} +0 -0
  121. /s/docs/{Overview.md → overview.md} +0 -0
  122. /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
- if template == "java":
111
- solcmd = "iotedgedev new . --module {0} --template {1} --edge-runtime-version {2} --group-id {3}".format(module, template, edge_runtime_version, group_id)
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
- if ret == 0:
118
- azsetupcmd = "iotedgedev iothub setup --update-dotenv"
119
- output.header(azsetupcmd)
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.add_command(init)
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.add_command(add)
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.add_command(build)
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.add_command(push)
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.add_command(deploy)
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.add_command(genconfig)
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.add_command(setup_simulator)
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.add_command(start_simulator)
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.add_command(stop_simulator)
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.add_command(monitor)
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.add_command(log)
838
+ main.add_command_with_deprecation(log, deprecated=True)
828
839
 
829
840
  if __name__ == "__main__":
830
841
  main()
@@ -2,8 +2,8 @@ from .utility import Utility
2
2
 
3
3
 
4
4
  class ConnectionString:
5
- def __init__(self, value):
6
- self.connection_string = value
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, value):
32
- ConnectionString.__init__(self, value)
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, value):
40
- ConnectionString.__init__(self, value)
39
+ def __init__(self, connection_string: str):
40
+ super().__init__(connection_string)
41
41
 
42
- if self.connection_string:
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("DEVICE_CONNECTION_STRING", self.envvars.DEVICE_CONNECTION_INFO)
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,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.2
2
2
  Name: iotedgedev
3
- Version: 3.3.4
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
@@ -4,7 +4,7 @@ docker>=3.7.0
4
4
  python-dotenv
5
5
  requests<=2.25.1,>=2.20.0
6
6
  fstrings
7
- azure-cli-core>=2.25.0
7
+ azure-cli-core<2.35.0,>=2.34.1
8
8
  iotedgehubdev==0.14.14
9
9
  applicationinsights==0.11.9
10
10
  commentjson==0.9.0
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.34
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.25.0
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
@@ -1,5 +1,5 @@
1
1
  [bumpversion]
2
- current_version = 3.3.4
2
+ current_version = 3.3.5
3
3
  commit = True
4
4
  tag = True
5
5
 
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
- 'azure-cli-core >= 2.25.0',
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.4',
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,4 +2,4 @@
2
2
 
3
3
  __author__ = 'Microsoft Corporation'
4
4
  __email__ = 'opencode@microsoft.com'
5
- __version__ = '3.3.4'
5
+ __version__ = '3.3.5'
@@ -13,7 +13,7 @@
13
13
  "testacr": {
14
14
  "username": "$USERNAME",
15
15
  "password": "$PASSWORD",
16
- "address": "$CONTAINER_REGISTRY_PASSWORD"
16
+ "address": "$CONTAINER_REGISTRY_SERVER"
17
17
  }
18
18
  }
19
19
  }
@@ -2,19 +2,53 @@
2
2
  "content": {
3
3
  "modulesContent": {
4
4
  "$edgeAgent": {
5
- "properties.desired.modules.sample_module": {
6
- "version": "1.0",
7
- "type": "docker",
8
- "status": "running",
9
- "restartPolicy": "always",
10
- "settings": {
11
- "image": "${MODULES.sample_module}",
12
- "createOptions": {}
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.routes.upstream": "FROM /messages/* INTO $upstream"
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)