iotedgedev 3.3.4__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/.devcontainer/Dockerfile +75 -0
- s/.devcontainer/devcontainer.json +40 -0
- s/.devcontainer/library-scripts/docker-in-docker-debian.sh +236 -0
- s/.env.tmp +108 -0
- s/.git/FETCH_HEAD +61 -0
- s/.git/HEAD +1 -0
- s/.git/config +12 -0
- s/.git/description +1 -0
- s/.git/hooks/applypatch-msg.sample +15 -0
- s/.git/hooks/commit-msg.sample +24 -0
- s/.git/hooks/fsmonitor-watchman.sample +173 -0
- s/.git/hooks/post-update.sample +8 -0
- s/.git/hooks/pre-applypatch.sample +14 -0
- s/.git/hooks/pre-commit.sample +49 -0
- s/.git/hooks/pre-merge-commit.sample +13 -0
- s/.git/hooks/pre-push.sample +53 -0
- s/.git/hooks/pre-rebase.sample +169 -0
- s/.git/hooks/pre-receive.sample +24 -0
- s/.git/hooks/prepare-commit-msg.sample +42 -0
- s/.git/hooks/push-to-checkout.sample +78 -0
- s/.git/hooks/update.sample +128 -0
- s/.git/index +0 -0
- s/.git/info/exclude +6 -0
- s/.git/logs/HEAD +1 -0
- s/.git/logs/refs/remotes/origin/EO +1 -0
- s/.git/logs/refs/remotes/origin/avagraw/security_fix +1 -0
- s/.git/logs/refs/remotes/origin/cherry-pick-rename +1 -0
- s/.git/logs/refs/remotes/origin/chyuan/fix-validation-not-fail-test +1 -0
- s/.git/logs/refs/remotes/origin/chyuan/update-linux-agent +1 -0
- s/.git/logs/refs/remotes/origin/dependabot/pip/pyyaml-5.4 +1 -0
- s/.git/logs/refs/remotes/origin/eliises/add-device-tagging-docs +1 -0
- s/.git/logs/refs/remotes/origin/main +1 -0
- s/.git/logs/refs/remotes/origin/ray-deps +1 -0
- s/.git/logs/refs/remotes/origin/ray-dev-setup +1 -0
- s/.git/logs/refs/remotes/origin/ray-tox +1 -0
- s/.git/logs/refs/remotes/origin/release-pipeline-automation +1 -0
- s/.git/logs/refs/remotes/origin/spmcdono/fix-pipeline-test-install +1 -0
- s/.git/logs/refs/remotes/origin/spmcdono/layered-deployments +1 -0
- s/.git/logs/refs/remotes/origin/spmcdono/pypi-package-test-pipeline +1 -0
- s/.git/logs/refs/remotes/origin/spmcdono/remove-py2 +1 -0
- s/.git/logs/refs/remotes/origin/spmcdono/remove-py2-dev +1 -0
- s/.git/logs/refs/remotes/origin/spmcdono/test-native-runtime-install +1 -0
- s/.git/logs/refs/remotes/origin/spmcdono/update-pipeline +1 -0
- s/.git/logs/refs/remotes/origin/user/marine/EliiseS/devcontainer +1 -0
- s/.git/logs/refs/remotes/origin/user/marine/fixsimver +1 -0
- s/.git/logs/refs/remotes/origin/user/marine/layereddeploymentsbuildtest +1 -0
- s/.git/logs/refs/remotes/origin/user/marine/master-to-main +1 -0
- s/.git/logs/refs/remotes/origin/user/marine/pipeline +1 -0
- s/.git/logs/refs/remotes/origin/user/vikas +1 -0
- s/.git/logs/refs/remotes/origin/user/vikas0212/verify-tests +1 -0
- s/.git/logs/refs/remotes/origin/user/vikas2 +1 -0
- s/.git/logs/refs/remotes/origin/user/vikas_pypi +1 -0
- s/.git/logs/refs/remotes/origin/user/vikas_pypi-1 +1 -0
- s/.git/logs/refs/remotes/origin/user/vikas_testing +1 -0
- s/.git/logs/refs/remotes/origin/user/xinzed/dps_conn_str +1 -0
- s/.git/logs/refs/remotes/origin/user/xinzed/update-python-docker +1 -0
- s/.git/logs/refs/remotes/origin/vikas/azure +1 -0
- s/.git/logs/refs/remotes/origin/vikas/dependebot +1 -0
- s/.git/logs/refs/remotes/origin/xinzed/3_1_0rc1 +1 -0
- s/.git/logs/refs/remotes/origin/xinzed/update-runtime +1 -0
- s/.git/objects/pack/pack-a8179feb7da51d11a42c37c5b3c8593cffe17075.idx +0 -0
- s/.git/objects/pack/pack-a8179feb7da51d11a42c37c5b3c8593cffe17075.pack +0 -0
- s/.git/refs/remotes/origin/EO +1 -0
- s/.git/refs/remotes/origin/avagraw/security_fix +1 -0
- s/.git/refs/remotes/origin/cherry-pick-rename +1 -0
- s/.git/refs/remotes/origin/chyuan/fix-validation-not-fail-test +1 -0
- s/.git/refs/remotes/origin/chyuan/update-linux-agent +1 -0
- s/.git/refs/remotes/origin/dependabot/pip/pyyaml-5.4 +1 -0
- s/.git/refs/remotes/origin/eliises/add-device-tagging-docs +1 -0
- s/.git/refs/remotes/origin/main +1 -0
- s/.git/refs/remotes/origin/ray-deps +1 -0
- s/.git/refs/remotes/origin/ray-dev-setup +1 -0
- s/.git/refs/remotes/origin/ray-tox +1 -0
- s/.git/refs/remotes/origin/release-pipeline-automation +1 -0
- s/.git/refs/remotes/origin/spmcdono/fix-pipeline-test-install +1 -0
- s/.git/refs/remotes/origin/spmcdono/layered-deployments +1 -0
- s/.git/refs/remotes/origin/spmcdono/pypi-package-test-pipeline +1 -0
- s/.git/refs/remotes/origin/spmcdono/remove-py2 +1 -0
- s/.git/refs/remotes/origin/spmcdono/remove-py2-dev +1 -0
- s/.git/refs/remotes/origin/spmcdono/test-native-runtime-install +1 -0
- s/.git/refs/remotes/origin/spmcdono/update-pipeline +1 -0
- s/.git/refs/remotes/origin/user/marine/EliiseS/devcontainer +1 -0
- s/.git/refs/remotes/origin/user/marine/fixsimver +1 -0
- s/.git/refs/remotes/origin/user/marine/layereddeploymentsbuildtest +1 -0
- s/.git/refs/remotes/origin/user/marine/master-to-main +1 -0
- s/.git/refs/remotes/origin/user/marine/pipeline +1 -0
- s/.git/refs/remotes/origin/user/vikas +1 -0
- s/.git/refs/remotes/origin/user/vikas0212/verify-tests +1 -0
- s/.git/refs/remotes/origin/user/vikas2 +1 -0
- s/.git/refs/remotes/origin/user/vikas_pypi +1 -0
- s/.git/refs/remotes/origin/user/vikas_pypi-1 +1 -0
- s/.git/refs/remotes/origin/user/vikas_testing +1 -0
- s/.git/refs/remotes/origin/user/xinzed/dps_conn_str +1 -0
- s/.git/refs/remotes/origin/user/xinzed/update-python-docker +1 -0
- s/.git/refs/remotes/origin/vikas/azure +1 -0
- s/.git/refs/remotes/origin/vikas/dependebot +1 -0
- s/.git/refs/remotes/origin/xinzed/3_1_0rc1 +1 -0
- s/.git/refs/remotes/origin/xinzed/update-runtime +1 -0
- s/.git/refs/tags/v0.49.0 +1 -0
- s/.git/refs/tags/v0.50.0 +1 -0
- s/.git/refs/tags/v0.51.0 +1 -0
- s/.git/refs/tags/v0.52.0 +1 -0
- s/.git/refs/tags/v0.53.0 +1 -0
- s/.git/refs/tags/v0.54.0 +1 -0
- s/.git/refs/tags/v0.55.0 +1 -0
- s/.git/refs/tags/v0.56.0 +1 -0
- s/.git/refs/tags/v0.57.0 +1 -0
- s/.git/refs/tags/v0.58.0 +1 -0
- s/.git/refs/tags/v0.59.0 +1 -0
- s/.git/refs/tags/v0.60.0 +1 -0
- s/.git/refs/tags/v0.61.0 +1 -0
- s/.git/refs/tags/v0.62.0 +1 -0
- s/.git/refs/tags/v0.63.0 +1 -0
- s/.git/refs/tags/v0.64.0 +1 -0
- s/.git/refs/tags/v0.65.0 +1 -0
- s/.git/refs/tags/v0.66.0 +1 -0
- s/.git/refs/tags/v0.67.0 +1 -0
- s/.git/refs/tags/v0.68.0 +1 -0
- s/.git/refs/tags/v0.69.0 +1 -0
- s/.git/refs/tags/v0.70.0 +1 -0
- s/.git/refs/tags/v0.71.0 +1 -0
- s/.git/refs/tags/v0.72.0 +1 -0
- s/.git/refs/tags/v0.73.0 +1 -0
- s/.git/refs/tags/v0.74.0 +1 -0
- s/.git/refs/tags/v0.75.0 +1 -0
- s/.git/refs/tags/v0.76.0 +1 -0
- s/.git/refs/tags/v0.77.0 +1 -0
- s/.git/refs/tags/v0.78.0 +1 -0
- s/.git/refs/tags/v0.79.0 +1 -0
- s/.git/refs/tags/v0.82.0 +1 -0
- s/.git/refs/tags/v0.82.0-container +1 -0
- s/.git/refs/tags/v1.0.0 +1 -0
- s/.git/refs/tags/v1.1.0 +1 -0
- s/.git/refs/tags/v1.2.0 +1 -0
- s/.git/refs/tags/v1.3.0 +1 -0
- s/.git/refs/tags/v2.0.0 +1 -0
- s/.git/refs/tags/v2.0.1 +1 -0
- s/.git/refs/tags/v2.0.2 +1 -0
- s/.git/refs/tags/v2.1.0 +1 -0
- s/.git/refs/tags/v2.1.1 +1 -0
- s/.git/refs/tags/v2.1.2 +1 -0
- s/.git/refs/tags/v2.1.3 +1 -0
- s/.git/refs/tags/v2.1.4 +1 -0
- s/.git/refs/tags/v2.1.6 +1 -0
- s/.git/refs/tags/v2.2.0 +1 -0
- s/.git/refs/tags/v3.0.0 +1 -0
- s/.git/refs/tags/v3.0.0-rc +1 -0
- s/.git/refs/tags/v3.1.0 +1 -0
- s/.git/refs/tags/v3.1.1 +1 -0
- s/.git/refs/tags/v3.1.2 +1 -0
- s/.git/refs/tags/v3.2.0 +1 -0
- s/.git/refs/tags/v3.2.0rc0 +1 -0
- s/.git/refs/tags/v3.3.0 +1 -0
- s/.git/refs/tags/v3.3.1 +1 -0
- s/.git/refs/tags/v3.3.2 +1 -0
- s/.git/refs/tags/v3.3.3 +1 -0
- s/.git/refs/tags/v3.3.3-rc0 +1 -0
- s/.git/refs/tags/v3.3.4 +1 -0
- s/.github/ISSUE_TEMPLATE/bug_report.md +16 -0
- s/.github/ISSUE_TEMPLATE/feature_request.md +7 -0
- s/.github/workflows/wiki.yml +54 -0
- s/.gitignore +103 -0
- s/.vscode/launch.json +26 -0
- s/.vscode/settings.json +30 -0
- s/CHANGELOG.md +156 -0
- s/CODE_OF_CONDUCT.md +1 -0
- s/CONTRIBUTING.md +122 -0
- s/LICENSE +14 -0
- s/MANIFEST.in +7 -0
- s/Makefile +87 -0
- s/README.md +204 -0
- s/assets/armdeployment.png +0 -0
- s/assets/armoutputs.png +0 -0
- s/assets/deploy/ARMDeployment/ARMDeployment.deployproj +36 -0
- s/assets/deploy/ARMDeployment/Deploy-AzureResourceGroup.ps1 +118 -0
- s/assets/deploy/ARMDeployment/azuredeploy.json +145 -0
- s/assets/deploy/ARMDeployment/azuredeploy.parameters.json +6 -0
- s/assets/deploy/ARMDeployment.sln +25 -0
- s/assets/edgedevtool2mins.png +0 -0
- s/assets/edgedevtoolintro.png +0 -0
- s/assets/edgedevtoolquickstartlarge.png +0 -0
- s/assets/edgedevtoolquickstartsmall.png +0 -0
- s/assets/edgedevtoolwsl.png +0 -0
- s/azure-pipelines.yml +144 -0
- s/build/lib/iotedgedev/__init__.py +6 -0
- s/build/lib/iotedgedev/args.py +18 -0
- s/build/lib/iotedgedev/azurecli.py +542 -0
- s/build/lib/iotedgedev/buildoptionsparser.py +151 -0
- s/build/lib/iotedgedev/buildprofile.py +5 -0
- s/build/lib/iotedgedev/cli.py +830 -0
- s/build/lib/iotedgedev/connectionstring.py +58 -0
- s/build/lib/iotedgedev/constants.py +12 -0
- s/build/lib/iotedgedev/containerregistry.py +5 -0
- s/build/lib/iotedgedev/decorators.py +116 -0
- s/build/lib/iotedgedev/deploymentmanifest.py +313 -0
- s/build/lib/iotedgedev/dockercls.py +255 -0
- s/build/lib/iotedgedev/dotnet.py +31 -0
- s/build/lib/iotedgedev/edge.py +33 -0
- s/build/lib/iotedgedev/envvars.py +240 -0
- s/build/lib/iotedgedev/iothub.py +65 -0
- s/build/lib/iotedgedev/module.py +62 -0
- s/build/lib/iotedgedev/modules.py +332 -0
- s/build/lib/iotedgedev/organizedgroup.py +48 -0
- s/build/lib/iotedgedev/output.py +57 -0
- s/build/lib/iotedgedev/simulator.py +58 -0
- s/build/lib/iotedgedev/solution.py +48 -0
- s/build/lib/iotedgedev/telemetry.py +155 -0
- s/build/lib/iotedgedev/telemetryconfig.py +85 -0
- s/build/lib/iotedgedev/telemetryuploader.py +53 -0
- s/build/lib/iotedgedev/template/.env.tmp +87 -0
- s/build/lib/iotedgedev/template/.gitignore +10 -0
- s/build/lib/iotedgedev/template/deployment.template.json +79 -0
- s/build/lib/iotedgedev/template/launch_c.json +50 -0
- s/build/lib/iotedgedev/template/launch_csharp.json +43 -0
- s/build/lib/iotedgedev/template/launch_java.json +27 -0
- s/build/lib/iotedgedev/template/launch_node.json +36 -0
- s/build/lib/iotedgedev/template/launch_python.json +22 -0
- s/build/lib/iotedgedev/utility.py +179 -0
- s/build/lib/iotedgedev/version.py +4 -0
- s/build.sh +150 -0
- s/cleanup.sh +7 -0
- s/dist/iotedgedev-3.3.4-py3-none-any.whl +0 -0
- s/docker/tool/build-docker.sh +168 -0
- s/docker/tool/deps.txt +7 -0
- s/docker/tool/linux/Dockerfile +7 -0
- s/docker/tool/linux/Dockerfile.base +61 -0
- s/docker/tool/linux/install-dev.sh +8 -0
- s/docker/tool/linux/run.ps1 +5 -0
- s/docker/tool/linux/run.sh +5 -0
- s/docker/tool/push-docker.sh +35 -0
- s/docker/tool/windows/Dockerfile +4 -0
- s/docker/tool/windows/Dockerfile.base +63 -0
- s/docker/tool/windows/install-dev.bat +4 -0
- s/docker/tool/windows/run.ps1 +30 -0
- s/docs/Azure-Setup.md +102 -0
- s/docs/Command-List.md +564 -0
- s/docs/Command-Tips.md +51 -0
- s/docs/Edge-Device-Setup.md +23 -0
- s/docs/Home.md +10 -0
- s/docs/Manual-Dev-Machine-Setup.md +77 -0
- s/docs/Migration-Guides.md +131 -0
- s/docs/Overview.md +66 -0
- s/docs/Python-Virtual-Environment-Setup.md +35 -0
- s/docs/Quickstart-with-IoT-Edge-Dev-Container.md +145 -0
- s/docs/Test-Coverage.md +7 -0
- s/docs/Troubleshooting.md +21 -0
- s/docs/Usage.md +123 -0
- s/docs/_Sidebar.md +13 -0
- s/iotedgedev/__init__.py +6 -0
- s/iotedgedev/args.py +18 -0
- s/iotedgedev/azurecli.py +542 -0
- s/iotedgedev/buildoptionsparser.py +151 -0
- s/iotedgedev/buildprofile.py +5 -0
- s/iotedgedev/cli.py +830 -0
- s/iotedgedev/connectionstring.py +58 -0
- s/iotedgedev/constants.py +12 -0
- s/iotedgedev/containerregistry.py +5 -0
- s/iotedgedev/decorators.py +116 -0
- s/iotedgedev/deploymentmanifest.py +313 -0
- s/iotedgedev/dockercls.py +255 -0
- s/iotedgedev/dotnet.py +31 -0
- s/iotedgedev/edge.py +33 -0
- s/iotedgedev/envvars.py +240 -0
- s/iotedgedev/iothub.py +65 -0
- s/iotedgedev/module.py +62 -0
- s/iotedgedev/modules.py +332 -0
- s/iotedgedev/organizedgroup.py +48 -0
- s/iotedgedev/output.py +57 -0
- s/iotedgedev/simulator.py +58 -0
- s/iotedgedev/solution.py +48 -0
- s/iotedgedev/telemetry.py +155 -0
- s/iotedgedev/telemetryconfig.py +85 -0
- s/iotedgedev/telemetryuploader.py +53 -0
- s/iotedgedev/template/.env.tmp +87 -0
- s/iotedgedev/template/.gitignore +10 -0
- s/iotedgedev/template/deployment.template.json +79 -0
- s/iotedgedev/template/launch_c.json +50 -0
- s/iotedgedev/template/launch_csharp.json +43 -0
- s/iotedgedev/template/launch_java.json +27 -0
- s/iotedgedev/template/launch_node.json +36 -0
- s/iotedgedev/template/launch_python.json +22 -0
- s/iotedgedev/utility.py +179 -0
- s/iotedgedev/version.py +4 -0
- s/iotedgedev.egg-info/PKG-INFO +21 -0
- s/iotedgedev.egg-info/SOURCES.txt +100 -0
- s/iotedgedev.egg-info/dependency_links.txt +1 -0
- s/iotedgedev.egg-info/entry_points.txt +3 -0
- s/iotedgedev.egg-info/not-zip-safe +1 -0
- s/iotedgedev.egg-info/requires.txt +18 -0
- s/iotedgedev.egg-info/top_level.txt +1 -0
- s/pull_request_template.md +9 -0
- s/pytest.ini +4 -0
- s/requirements.txt +12 -0
- s/requirements_dev.txt +17 -0
- s/scripts/gen-help-markdown.bat +177 -0
- s/scripts/install-pip.sh +1 -0
- s/scripts/setup-wsl.sh +7 -0
- s/setup.cfg +18 -0
- s/setup.py +66 -0
- s/tests/__init__.py +5 -0
- s/tests/assets/deployment.manifest_invalid.json +106 -0
- s/tests/assets/deployment.manifest_invalid_createoptions.json +102 -0
- s/tests/assets/deployment.manifest_invalid_schema.json +69 -0
- s/tests/assets/deployment.template.non_str_placeholder.json +79 -0
- s/tests/assets/deployment.template_1.json +163 -0
- s/tests/assets/deployment.template_2.json +163 -0
- s/tests/assets/deployment.template_3.json +174 -0
- s/tests/assets/deployment.template_4.json +79 -0
- s/tests/assets/deployment.template_invalidresult.json +183 -0
- s/tests/assets/deployment.template_without_schema_template.json +99 -0
- s/tests/assets/launch.json +225 -0
- s/tests/assets/launch_without_nodejs.json +194 -0
- s/tests/assets/test_solution_shared_lib/.gitignore +2 -0
- s/tests/assets/test_solution_shared_lib/.vscode/launch.json +43 -0
- s/tests/assets/test_solution_shared_lib/deployment.debug.template.json +100 -0
- s/tests/assets/test_solution_shared_lib/deployment.escapedpath.template.json +90 -0
- s/tests/assets/test_solution_shared_lib/deployment.template.json +106 -0
- s/tests/assets/test_solution_shared_lib/layered_deployment.flattened_props.template.json +21 -0
- s/tests/assets/test_solution_shared_lib/layered_deployment.no_modules.template.json +12 -0
- s/tests/assets/test_solution_shared_lib/libs/sharedlib/Class1.cs +12 -0
- s/tests/assets/test_solution_shared_lib/libs/sharedlib/sharedlib.csproj +7 -0
- s/tests/assets/test_solution_shared_lib/modules/non_module_project/placeholder.txt +0 -0
- s/tests/assets/test_solution_shared_lib/modules/sample_module/.gitignore +34 -0
- s/tests/assets/test_solution_shared_lib/modules/sample_module/Dockerfile.amd64 +18 -0
- s/tests/assets/test_solution_shared_lib/modules/sample_module/Dockerfile.amd64.debug +25 -0
- s/tests/assets/test_solution_shared_lib/modules/sample_module/Dockerfile.windows-amd64 +15 -0
- s/tests/assets/test_solution_shared_lib/modules/sample_module/Program.cs +91 -0
- s/tests/assets/test_solution_shared_lib/modules/sample_module/module.json +18 -0
- s/tests/assets/test_solution_shared_lib/modules/sample_module/sample_module.csproj +26 -0
- s/tests/assets/test_solution_shared_lib/sample_module_2/.gitignore +34 -0
- s/tests/assets/test_solution_shared_lib/sample_module_2/Dockerfile.amd64 +18 -0
- s/tests/assets/test_solution_shared_lib/sample_module_2/Dockerfile.amd64.debug +25 -0
- s/tests/assets/test_solution_shared_lib/sample_module_2/Dockerfile.windows-amd64 +15 -0
- s/tests/assets/test_solution_shared_lib/sample_module_2/Program.cs +91 -0
- s/tests/assets/test_solution_shared_lib/sample_module_2/module.json +18 -0
- s/tests/assets/test_solution_shared_lib/sample_module_2/sample_module_2.csproj +26 -0
- s/tests/test_azurecli.py +33 -0
- s/tests/test_buildoptionsparser.py +155 -0
- s/tests/test_cli.py +55 -0
- s/tests/test_config.py +28 -0
- s/tests/test_connectionstring.py +87 -0
- s/tests/test_decorators.py +44 -0
- s/tests/test_deploymentmanifest.py +106 -0
- s/tests/test_envvars.py +169 -0
- s/tests/test_iotedgedev_iothub_deploy.py +199 -0
- s/tests/test_iotedgedev_simulator.py +133 -0
- s/tests/test_iotedgedev_solution.py +457 -0
- s/tests/test_iotedgedev_solution_build.py +246 -0
- s/tests/test_iotedgedev_solution_tag.py +99 -0
- s/tests/test_utility.py +132 -0
- s/tests/utility.py +132 -0
- s/tox.ini +29 -0
- s/vsts_ci/.vsts-ci.yml +93 -0
- s/vsts_ci/darwin/continuous-build-darwin.yml +54 -0
- s/vsts_ci/linux/continuous-build-linux.yml +28 -0
- s/vsts_ci/win32/continuous-build-win32.yml +26 -0
s/iotedgedev/cli.py
ADDED
|
@@ -0,0 +1,830 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
import socket
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from fstrings import f
|
|
7
|
+
|
|
8
|
+
from .azurecli import AzureCli
|
|
9
|
+
from .constants import Constants
|
|
10
|
+
from .decorators import add_module_options, with_telemetry
|
|
11
|
+
from .dockercls import Docker
|
|
12
|
+
from .edge import Edge
|
|
13
|
+
from .envvars import EnvVars
|
|
14
|
+
from .iothub import IoTHub
|
|
15
|
+
from .modules import Modules
|
|
16
|
+
from .organizedgroup import OrganizedGroup
|
|
17
|
+
from .output import Output
|
|
18
|
+
from .simulator import Simulator
|
|
19
|
+
from .solution import Solution
|
|
20
|
+
from .utility import Utility
|
|
21
|
+
|
|
22
|
+
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'], max_content_width=120)
|
|
23
|
+
|
|
24
|
+
output = Output()
|
|
25
|
+
envvars = EnvVars(output)
|
|
26
|
+
envvars.load()
|
|
27
|
+
|
|
28
|
+
azure_cli = AzureCli(output, envvars)
|
|
29
|
+
default_subscriptionId = None
|
|
30
|
+
azure_cli_processing_complete = False
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
@click.group(context_settings=CONTEXT_SETTINGS, cls=OrganizedGroup)
|
|
34
|
+
@click.version_option()
|
|
35
|
+
@with_telemetry
|
|
36
|
+
def main():
|
|
37
|
+
pass
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@main.group(context_settings=CONTEXT_SETTINGS, help="Manage IoT Edge solutions", order=1)
|
|
41
|
+
@with_telemetry
|
|
42
|
+
def solution():
|
|
43
|
+
pass
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@main.group(context_settings=CONTEXT_SETTINGS, help="Manage IoT Edge simulator", order=1)
|
|
47
|
+
@with_telemetry
|
|
48
|
+
def simulator():
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@main.group(context_settings=CONTEXT_SETTINGS, help="Manage IoT Hub and IoT Edge devices", order=1)
|
|
53
|
+
@with_telemetry
|
|
54
|
+
def iothub():
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@main.group(context_settings=CONTEXT_SETTINGS, help="Manage Docker", order=1)
|
|
59
|
+
@with_telemetry
|
|
60
|
+
def docker():
|
|
61
|
+
pass
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@solution.command(context_settings=CONTEXT_SETTINGS,
|
|
65
|
+
short_help="Create a new IoT Edge solution",
|
|
66
|
+
help="Create a new IoT Edge solution, where NAME is the solution folder name. "
|
|
67
|
+
"Use \".\" as NAME to create in the current folder.")
|
|
68
|
+
@click.argument("name",
|
|
69
|
+
required=True)
|
|
70
|
+
@click.option("--edge-runtime-version",
|
|
71
|
+
"-er",
|
|
72
|
+
default="1.2",
|
|
73
|
+
show_default=True,
|
|
74
|
+
required=False,
|
|
75
|
+
help="Specify the IoT Edge Runtime Version. Currently available 1.0, 1.1, 1.2")
|
|
76
|
+
@add_module_options(envvars, init=True)
|
|
77
|
+
@with_telemetry
|
|
78
|
+
def new(name, module, template, edge_runtime_version, group_id):
|
|
79
|
+
if edge_runtime_version is not None:
|
|
80
|
+
if (str(edge_runtime_version) != "1.0" and str(edge_runtime_version) != "1.1" and str(edge_runtime_version) != "1.2"):
|
|
81
|
+
output.info('-edge-runtime-version `{0}` is not valid. Currently supported versions are 1.0, 1.1, 1.2'.format(edge_runtime_version))
|
|
82
|
+
sys.exit()
|
|
83
|
+
utility = Utility(envvars, output)
|
|
84
|
+
sol = Solution(output, utility)
|
|
85
|
+
sol.create(name, module, template, edge_runtime_version, group_id)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
main.add_command(new)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@solution.command(context_settings=CONTEXT_SETTINGS,
|
|
92
|
+
help="Create a new IoT Edge solution and provision Azure resources",
|
|
93
|
+
# hack to prevent Click truncating help messages
|
|
94
|
+
short_help="Create a new IoT Edge solution and provision Azure resources")
|
|
95
|
+
@click.option("--edge-runtime-version",
|
|
96
|
+
"-er",
|
|
97
|
+
default="1.2",
|
|
98
|
+
show_default=True,
|
|
99
|
+
required=False,
|
|
100
|
+
help="Specify the IoT Edge Runtime Version. Currently available 1.0, 1.1, 1.2")
|
|
101
|
+
@add_module_options(envvars, init=True)
|
|
102
|
+
@with_telemetry
|
|
103
|
+
def init(module, template, group_id, edge_runtime_version):
|
|
104
|
+
if edge_runtime_version is not None:
|
|
105
|
+
if (str(edge_runtime_version) != "1.0" and str(edge_runtime_version) != "1.1" and str(edge_runtime_version) != "1.2"):
|
|
106
|
+
output.info('-edge-runtime-version `{0}` is not valid. Currently supported versions are 1.0, 1.1, 1.2'.format(edge_runtime_version))
|
|
107
|
+
sys.exit()
|
|
108
|
+
utility = Utility(envvars, output)
|
|
109
|
+
|
|
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())
|
|
116
|
+
|
|
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())
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
main.add_command(init)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@solution.command(context_settings=CONTEXT_SETTINGS, help="Push, deploy, start, monitor")
|
|
128
|
+
@click.pass_context
|
|
129
|
+
@with_telemetry
|
|
130
|
+
def e2e(ctx):
|
|
131
|
+
ctx.invoke(init)
|
|
132
|
+
ctx.invoke(push)
|
|
133
|
+
ctx.invoke(deploy)
|
|
134
|
+
ctx.invoke(monitor)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@solution.command(context_settings=CONTEXT_SETTINGS,
|
|
138
|
+
short_help="Add a new module to the solution",
|
|
139
|
+
help="Add a new module to the solution, where NAME is the module name")
|
|
140
|
+
@add_module_options(envvars)
|
|
141
|
+
@with_telemetry
|
|
142
|
+
def add(name, template, group_id):
|
|
143
|
+
mod = Modules(envvars, output)
|
|
144
|
+
mod.add(name, template, group_id)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
main.add_command(add)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@solution.command(context_settings=CONTEXT_SETTINGS, help="Build the solution")
|
|
151
|
+
@click.option("--push",
|
|
152
|
+
"-p",
|
|
153
|
+
default=False,
|
|
154
|
+
show_default=True,
|
|
155
|
+
required=False,
|
|
156
|
+
is_flag=True,
|
|
157
|
+
help="Push module images to container registry")
|
|
158
|
+
@click.option("--deploy",
|
|
159
|
+
"-d",
|
|
160
|
+
"do_deploy", # an alias to prevent conflict with the deploy function
|
|
161
|
+
default=False,
|
|
162
|
+
show_default=True,
|
|
163
|
+
required=False,
|
|
164
|
+
is_flag=True,
|
|
165
|
+
help="Deploy modules to Edge device using deployment.json in the config folder")
|
|
166
|
+
@click.option("--file",
|
|
167
|
+
"-f",
|
|
168
|
+
"template_file",
|
|
169
|
+
default=envvars.DEPLOYMENT_CONFIG_TEMPLATE_FILE,
|
|
170
|
+
show_default=True,
|
|
171
|
+
required=False,
|
|
172
|
+
help="Specify the deployment manifest template file")
|
|
173
|
+
@click.option("--platform",
|
|
174
|
+
"-P",
|
|
175
|
+
default=envvars.DEFAULT_PLATFORM,
|
|
176
|
+
show_default=True,
|
|
177
|
+
required=False,
|
|
178
|
+
help="Specify the platform")
|
|
179
|
+
@click.pass_context
|
|
180
|
+
@with_telemetry
|
|
181
|
+
def build(ctx, push, do_deploy, template_file, platform):
|
|
182
|
+
mod = Modules(envvars, output)
|
|
183
|
+
mod.build_push(template_file, platform, no_push=not push)
|
|
184
|
+
|
|
185
|
+
if do_deploy:
|
|
186
|
+
ctx.invoke(deploy)
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
main.add_command(build)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
@solution.command(context_settings=CONTEXT_SETTINGS, help="Push module images to container registry")
|
|
193
|
+
@click.option('--deploy',
|
|
194
|
+
"-d",
|
|
195
|
+
"do_deploy", # an alias to prevent conflict with the deploy method
|
|
196
|
+
default=False,
|
|
197
|
+
show_default=True,
|
|
198
|
+
required=False,
|
|
199
|
+
is_flag=True,
|
|
200
|
+
help="Deploy modules to Edge device using deployment.json in the config folder")
|
|
201
|
+
@click.option('--no-build',
|
|
202
|
+
default=False,
|
|
203
|
+
show_default=True,
|
|
204
|
+
required=False,
|
|
205
|
+
is_flag=True,
|
|
206
|
+
help="Inform the push command to not build module images before pushing to container registry")
|
|
207
|
+
@click.option("--file",
|
|
208
|
+
"-f",
|
|
209
|
+
"template_file",
|
|
210
|
+
default=envvars.DEPLOYMENT_CONFIG_TEMPLATE_FILE,
|
|
211
|
+
show_default=True,
|
|
212
|
+
required=False,
|
|
213
|
+
help="Specify the deployment manifest template file")
|
|
214
|
+
@click.option("--platform",
|
|
215
|
+
"-P",
|
|
216
|
+
default=envvars.DEFAULT_PLATFORM,
|
|
217
|
+
show_default=True,
|
|
218
|
+
required=False,
|
|
219
|
+
help="Specify the platform")
|
|
220
|
+
@click.pass_context
|
|
221
|
+
@with_telemetry
|
|
222
|
+
def push(ctx, do_deploy, no_build, template_file, platform):
|
|
223
|
+
mod = Modules(envvars, output)
|
|
224
|
+
mod.push(template_file, platform, no_build=no_build)
|
|
225
|
+
|
|
226
|
+
if do_deploy:
|
|
227
|
+
ctx.invoke(deploy)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
main.add_command(push)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
@solution.command(context_settings=CONTEXT_SETTINGS, help="Deploy solution to IoT Edge device")
|
|
234
|
+
@click.option("--file",
|
|
235
|
+
"-f",
|
|
236
|
+
"manifest_file",
|
|
237
|
+
default=envvars.DEPLOYMENT_CONFIG_FILE_PATH,
|
|
238
|
+
show_default=True,
|
|
239
|
+
required=False,
|
|
240
|
+
help="Specify the deployment manifest file")
|
|
241
|
+
@with_telemetry
|
|
242
|
+
def deploy(manifest_file):
|
|
243
|
+
ensure_azure_cli_iot_ext()
|
|
244
|
+
edge = Edge(envvars, output, azure_cli)
|
|
245
|
+
edge.deploy(manifest_file)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
main.add_command(deploy)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
@iothub.command(
|
|
252
|
+
name="deploy",
|
|
253
|
+
context_settings=CONTEXT_SETTINGS,
|
|
254
|
+
help="Create a deployment in IoT Hub. For more information on how automatic deployments work see: https://docs.microsoft.com/en-us/azure/iot-edge/module-deployment-monitoring")
|
|
255
|
+
@click.option("--file",
|
|
256
|
+
"-f",
|
|
257
|
+
"manifest_file",
|
|
258
|
+
default=envvars.DEPLOYMENT_CONFIG_FILE_PATH,
|
|
259
|
+
show_default=True,
|
|
260
|
+
required=False,
|
|
261
|
+
help="Specify the deployment manifest file")
|
|
262
|
+
@click.option("--name",
|
|
263
|
+
"-n",
|
|
264
|
+
required=True,
|
|
265
|
+
help="Specify the name of the deployment that will be created in the IoT hub.")
|
|
266
|
+
@click.option("--priority",
|
|
267
|
+
"-p",
|
|
268
|
+
required=True,
|
|
269
|
+
help=("Specify the deployment priority as positive integer. "
|
|
270
|
+
"In the event that two or more deployments are targeted at the same device, the deployment with the highest numerical value for Priority will apply."))
|
|
271
|
+
@click.option("--target-condition",
|
|
272
|
+
"--tc",
|
|
273
|
+
"-t",
|
|
274
|
+
default=envvars.get_envvar("IOTHUB_DEPLOYMENT_TARGET_CONDITION"),
|
|
275
|
+
show_default=True,
|
|
276
|
+
required=True,
|
|
277
|
+
help=("Specify a target condition to determine which devices will be targeted with this deployment. "
|
|
278
|
+
"The condition is based on device twin tags or device twin reported properties and should match the expression format. "
|
|
279
|
+
"For example, tags.environment='test' and properties.reported.devicemodel='4000x'. "
|
|
280
|
+
"This property can be set via this parameter or in the .env under 'IOTHUB_DEPLOYMENT_TARGET_CONDITION'"))
|
|
281
|
+
@click.option("--device-tag",
|
|
282
|
+
"-dt",
|
|
283
|
+
default=envvars.get_envvar("DEVICE_TAGS"),
|
|
284
|
+
required=False,
|
|
285
|
+
help="Specify the tags to be added to the device twin")
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
@with_telemetry
|
|
289
|
+
def iothub_deploy(manifest_file, name, priority, target_condition, device_tag):
|
|
290
|
+
ensure_azure_cli_iot_ext()
|
|
291
|
+
iothub = IoTHub(envvars, output, None, azure_cli)
|
|
292
|
+
iothub.deploy(manifest_file, name, priority, target_condition)
|
|
293
|
+
if device_tag:
|
|
294
|
+
edge = Edge(envvars, output, azure_cli)
|
|
295
|
+
edge.tag(device_tag)
|
|
296
|
+
|
|
297
|
+
|
|
298
|
+
@solution.command(context_settings=CONTEXT_SETTINGS, help="Adds tags to device twin for automatic deployments")
|
|
299
|
+
@click.option("--tags",
|
|
300
|
+
"-t",
|
|
301
|
+
"tags",
|
|
302
|
+
required=True,
|
|
303
|
+
default=envvars.get_envvar("DEVICE_TAGS"),
|
|
304
|
+
show_default=True,
|
|
305
|
+
help="Specify the tags to be added to the device twin")
|
|
306
|
+
@with_telemetry
|
|
307
|
+
def tag(tags):
|
|
308
|
+
ensure_azure_cli_iot_ext()
|
|
309
|
+
edge = Edge(envvars, output, azure_cli)
|
|
310
|
+
edge.tag(tags)
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
@solution.command(context_settings=CONTEXT_SETTINGS,
|
|
314
|
+
help="Expand environment variables and placeholders in deployment manifest template file and copy to config folder",
|
|
315
|
+
# hack to prevent Click truncating help messages
|
|
316
|
+
short_help="Expand environment variables and placeholders in deployment manifest template file and copy to config folder")
|
|
317
|
+
@click.option("--file",
|
|
318
|
+
"-f",
|
|
319
|
+
"template_file",
|
|
320
|
+
default=envvars.DEPLOYMENT_CONFIG_TEMPLATE_FILE,
|
|
321
|
+
show_default=True,
|
|
322
|
+
required=False,
|
|
323
|
+
help="Specify the deployment manifest template file")
|
|
324
|
+
@click.option("--platform",
|
|
325
|
+
"-P",
|
|
326
|
+
default=envvars.DEFAULT_PLATFORM,
|
|
327
|
+
show_default=True,
|
|
328
|
+
required=False,
|
|
329
|
+
help="Specify the platform")
|
|
330
|
+
@click.option("--fail-on-validation-error",
|
|
331
|
+
"fail_on_validation_error",
|
|
332
|
+
is_flag=True,
|
|
333
|
+
default=False,
|
|
334
|
+
show_default=True,
|
|
335
|
+
required=False,
|
|
336
|
+
help="Fail the command when deployment manifest validation failed")
|
|
337
|
+
@with_telemetry
|
|
338
|
+
def genconfig(template_file, platform, fail_on_validation_error):
|
|
339
|
+
mod = Modules(envvars, output)
|
|
340
|
+
mod.build_push(template_file, platform, no_build=True, no_push=True, fail_on_validation_error=fail_on_validation_error)
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
main.add_command(genconfig)
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
@simulator.command(context_settings=CONTEXT_SETTINGS,
|
|
347
|
+
name="setup",
|
|
348
|
+
short_help="Setup IoT Edge simulator. This must be done before starting",
|
|
349
|
+
help="Setup IoT Edge simulator. This must be done before starting")
|
|
350
|
+
@click.option("--gateway-host",
|
|
351
|
+
"-g",
|
|
352
|
+
help="GatewayHostName value for the module to connect.",
|
|
353
|
+
required=False,
|
|
354
|
+
default=socket.getfqdn(),
|
|
355
|
+
show_default=True)
|
|
356
|
+
@click.option("--iothub-connection-string",
|
|
357
|
+
"-i",
|
|
358
|
+
help="Set Azure IoT Hub connection string. Note: Use double quotes when supplying this input.",
|
|
359
|
+
required=False)
|
|
360
|
+
@with_telemetry
|
|
361
|
+
def setup_simulator(gateway_host, iothub_connection_string):
|
|
362
|
+
sim = Simulator(envvars, output)
|
|
363
|
+
sim.setup(gateway_host, iothub_connection_string)
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
main.add_command(setup_simulator)
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
@simulator.command(context_settings=CONTEXT_SETTINGS,
|
|
370
|
+
name="start",
|
|
371
|
+
short_help="Start IoT Edge simulator",
|
|
372
|
+
help="Start IoT Edge simulator. To start in solution mode, use `iotedgdev simulator start -s [-v] [-b]`. "
|
|
373
|
+
"To start in single module mode, use `iotedgedev simulator start -i input1,input2 [-p 53000]`")
|
|
374
|
+
@click.option("--setup",
|
|
375
|
+
"-u",
|
|
376
|
+
is_flag=True,
|
|
377
|
+
default=False,
|
|
378
|
+
show_default=True,
|
|
379
|
+
help="Setup IoT Edge simulator before starting.")
|
|
380
|
+
@click.option("--solution",
|
|
381
|
+
"-s",
|
|
382
|
+
is_flag=True,
|
|
383
|
+
default=False,
|
|
384
|
+
show_default=True,
|
|
385
|
+
help="Start IoT Edge simulator in solution mode using the deployment.json in config folder.")
|
|
386
|
+
@click.option("--verbose",
|
|
387
|
+
"-v",
|
|
388
|
+
required=False,
|
|
389
|
+
is_flag=True,
|
|
390
|
+
default=False,
|
|
391
|
+
show_default=True,
|
|
392
|
+
help="Show the solution container logs.")
|
|
393
|
+
@click.option("--build",
|
|
394
|
+
"-b",
|
|
395
|
+
required=False,
|
|
396
|
+
is_flag=True,
|
|
397
|
+
default=False,
|
|
398
|
+
show_default=True,
|
|
399
|
+
help="Build the solution before starting IoT Edge simulator in solution mode.")
|
|
400
|
+
@click.option("--file",
|
|
401
|
+
"-f",
|
|
402
|
+
"manifest_file",
|
|
403
|
+
default=envvars.DEPLOYMENT_CONFIG_FILE_PATH,
|
|
404
|
+
show_default=True,
|
|
405
|
+
required=False,
|
|
406
|
+
help="Specify the deployment manifest file. When `--build` flag is set, specify a deployment manifest template and it will be built.")
|
|
407
|
+
@click.option("--platform",
|
|
408
|
+
"-P",
|
|
409
|
+
default=envvars.DEFAULT_PLATFORM,
|
|
410
|
+
show_default=True,
|
|
411
|
+
required=False,
|
|
412
|
+
help="Specify the platform")
|
|
413
|
+
@click.option("--inputs",
|
|
414
|
+
"-i",
|
|
415
|
+
required=False,
|
|
416
|
+
help="Start IoT Edge simulator in single module mode "
|
|
417
|
+
"using the specified comma-separated inputs of the target module, e.g., `input1,input2`.")
|
|
418
|
+
@click.option("--port",
|
|
419
|
+
"-p",
|
|
420
|
+
required=False,
|
|
421
|
+
default=53000,
|
|
422
|
+
show_default=True,
|
|
423
|
+
help="Port of the service for sending message.")
|
|
424
|
+
@click.option("--iothub-connection-string",
|
|
425
|
+
"-c",
|
|
426
|
+
help="Set Azure IoT Hub connection string when setup IoT Edge simulator. Note: Use double quotes when supplying this input.",
|
|
427
|
+
required=False)
|
|
428
|
+
@with_telemetry
|
|
429
|
+
def start_simulator(setup, solution, build, manifest_file, platform, verbose, inputs, port, iothub_connection_string):
|
|
430
|
+
sim = Simulator(envvars, output)
|
|
431
|
+
|
|
432
|
+
if setup:
|
|
433
|
+
sim.setup(socket.getfqdn(), iothub_connection_string)
|
|
434
|
+
|
|
435
|
+
if solution or not inputs:
|
|
436
|
+
sim.start_solution(manifest_file, platform, verbose, build)
|
|
437
|
+
else:
|
|
438
|
+
sim.start_single(inputs, port)
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
main.add_command(start_simulator)
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
@simulator.command(context_settings=CONTEXT_SETTINGS,
|
|
445
|
+
name="stop",
|
|
446
|
+
help="Stop IoT Edge simulator")
|
|
447
|
+
@with_telemetry
|
|
448
|
+
def stop_simulator():
|
|
449
|
+
sim = Simulator(envvars, output)
|
|
450
|
+
sim.stop()
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
main.add_command(stop_simulator)
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
@simulator.command(context_settings=CONTEXT_SETTINGS,
|
|
457
|
+
# short_help hack to prevent Click truncating help text (https://github.com/pallets/click/issues/486)
|
|
458
|
+
short_help="Get the credentials of target module such as connection string and certificate file path.",
|
|
459
|
+
help="Get the credentials of target module such as connection string and certificate file path.")
|
|
460
|
+
@click.option("--local",
|
|
461
|
+
"-l",
|
|
462
|
+
help="Set `localhost` to `GatewayHostName` for module to run on host natively.",
|
|
463
|
+
is_flag=True,
|
|
464
|
+
required=False,
|
|
465
|
+
default=False,
|
|
466
|
+
show_default=True)
|
|
467
|
+
@click.option("--output-file",
|
|
468
|
+
"-o",
|
|
469
|
+
help="Specify the output file to save the credentials. If the file exists, its content will be overwritten.",
|
|
470
|
+
required=False)
|
|
471
|
+
@with_telemetry
|
|
472
|
+
def modulecred(local, output_file):
|
|
473
|
+
sim = Simulator(envvars, output)
|
|
474
|
+
sim.modulecred(local, output_file)
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
@iothub.command(context_settings=CONTEXT_SETTINGS,
|
|
478
|
+
help="Monitor messages from IoT Edge device to IoT Hub",
|
|
479
|
+
# hack to prevent Click truncating help messages
|
|
480
|
+
short_help="Monitor messages from IoT Edge device to IoT Hub")
|
|
481
|
+
@click.option("--timeout",
|
|
482
|
+
"-t",
|
|
483
|
+
required=False,
|
|
484
|
+
help="Specify number of seconds to monitor for messages")
|
|
485
|
+
@with_telemetry
|
|
486
|
+
def monitor(timeout):
|
|
487
|
+
ensure_azure_cli_iot_ext()
|
|
488
|
+
utility = Utility(envvars, output)
|
|
489
|
+
ih = IoTHub(envvars, output, utility, azure_cli)
|
|
490
|
+
ih.monitor_events(timeout)
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
main.add_command(monitor)
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
def ensure_azure_cli_iot_ext():
|
|
497
|
+
if not azure_cli.extension_exists("azure-iot"):
|
|
498
|
+
try:
|
|
499
|
+
# Install fixed version of Azure CLI IoT extension
|
|
500
|
+
azure_cli.add_extension_with_source(Constants.azure_cli_iot_ext_source_url)
|
|
501
|
+
except Exception:
|
|
502
|
+
# Fall back to install latest Azure CLI IoT extension when fail
|
|
503
|
+
azure_cli.add_extension("azure-iot")
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
def validate_option(ctx, param, value):
|
|
507
|
+
global default_subscriptionId
|
|
508
|
+
global azure_cli_processing_complete
|
|
509
|
+
|
|
510
|
+
if param.name == "credentials":
|
|
511
|
+
if value and value[0] and value[1]:
|
|
512
|
+
output.param("CREDENTIALS", value, "Setting Credentials...", azure_cli_processing_complete)
|
|
513
|
+
|
|
514
|
+
if not azure_cli.login_account(*value):
|
|
515
|
+
sys.exit()
|
|
516
|
+
|
|
517
|
+
if param.name == "service_principal":
|
|
518
|
+
if value and value[0] and value[1] and value[2]:
|
|
519
|
+
output.param("SERVICE PRINCIPAL", value, "Setting Credentials...", azure_cli_processing_complete)
|
|
520
|
+
|
|
521
|
+
if not azure_cli.login_sp(*value):
|
|
522
|
+
sys.exit()
|
|
523
|
+
|
|
524
|
+
if param.name == "subscription":
|
|
525
|
+
output.param("SUBSCRIPTION", value, f("Setting Subscription to '{value}'..."), azure_cli_processing_complete)
|
|
526
|
+
|
|
527
|
+
# first verify that we have an existing auth token in cache, otherwise login using interactive
|
|
528
|
+
if not default_subscriptionId:
|
|
529
|
+
default_subscriptionId = azure_cli.user_has_logged_in()
|
|
530
|
+
if not default_subscriptionId and not azure_cli.login_interactive():
|
|
531
|
+
sys.exit()
|
|
532
|
+
|
|
533
|
+
if default_subscriptionId != value:
|
|
534
|
+
subscription = azure_cli.set_subscription(value)
|
|
535
|
+
if not subscription:
|
|
536
|
+
raise click.BadParameter(f('Please verify that your subscription Id or Name is correct'))
|
|
537
|
+
if len(subscription) < 36:
|
|
538
|
+
value = click.prompt(param.prompt, default=default_subscriptionId)
|
|
539
|
+
return validate_option(ctx, param, value)
|
|
540
|
+
|
|
541
|
+
if param.name == "resource_group_name":
|
|
542
|
+
output.param("RESOURCE GROUP NAME", value, f("Setting Resource Group Name to '{value}'..."), azure_cli_processing_complete)
|
|
543
|
+
|
|
544
|
+
envvars.RESOURCE_GROUP_NAME = value
|
|
545
|
+
if not azure_cli.resource_group_exists(value):
|
|
546
|
+
if not azure_cli.create_resource_group(value, envvars.RESOURCE_GROUP_LOCATION):
|
|
547
|
+
raise click.BadParameter(f('Could not find Resource Group {value}'))
|
|
548
|
+
else:
|
|
549
|
+
# resource group exist, so don't ask for location
|
|
550
|
+
envvars.RESOURCE_GROUP_LOCATION = azure_cli.get_resource_group_location(value)
|
|
551
|
+
|
|
552
|
+
if param.name == "resource_group_location":
|
|
553
|
+
output.param("RESOURCE GROUP LOCATION", value, f("Setting Resource Group Location to '{value}'..."), azure_cli_processing_complete)
|
|
554
|
+
|
|
555
|
+
envvars.RESOURCE_GROUP_LOCATION = value
|
|
556
|
+
|
|
557
|
+
if param.name == "iothub_sku":
|
|
558
|
+
|
|
559
|
+
output.param("IOT HUB SKU", value, f("Setting IoT Hub SKU to '{value}'..."), azure_cli_processing_complete)
|
|
560
|
+
envvars.IOTHUB_SKU = value
|
|
561
|
+
|
|
562
|
+
if param.name == "iothub_name":
|
|
563
|
+
output.param("IOT HUB", value, f("Setting IoT Hub to '{value}'..."), azure_cli_processing_complete)
|
|
564
|
+
envvars.IOTHUB_NAME = value
|
|
565
|
+
ensure_azure_cli_iot_ext()
|
|
566
|
+
if not azure_cli.iothub_exists(value, envvars.RESOURCE_GROUP_NAME):
|
|
567
|
+
# check if the active subscription already contains a free IoT Hub
|
|
568
|
+
# if yes ask if the user wants to create an S1
|
|
569
|
+
# otherwise exit
|
|
570
|
+
if envvars.IOTHUB_SKU == "F1":
|
|
571
|
+
free_iot_name, free_iot_rg = azure_cli.get_free_iothub()
|
|
572
|
+
if free_iot_name:
|
|
573
|
+
output.info("You already have a Free IoT Hub SKU in your subscription, "
|
|
574
|
+
"so you must either use that existing IoT Hub or create a new S1 IoT Hub. "
|
|
575
|
+
"Enter (F) to use the existing Free IoT Hub or enter (S) to create a new S1 IoT Hub:")
|
|
576
|
+
user_response = sys.stdin.readline().strip().upper()
|
|
577
|
+
if user_response == "S":
|
|
578
|
+
envvars.IOTHUB_SKU = "S1"
|
|
579
|
+
elif user_response == "F":
|
|
580
|
+
envvars.IOTHUB_NAME = free_iot_name
|
|
581
|
+
envvars.RESOURCE_GROUP_NAME = free_iot_rg
|
|
582
|
+
return free_iot_name
|
|
583
|
+
else:
|
|
584
|
+
sys.exit()
|
|
585
|
+
if not azure_cli.create_iothub(value, envvars.RESOURCE_GROUP_NAME, envvars.IOTHUB_SKU):
|
|
586
|
+
raise click.BadParameter(f('Could not create IoT Hub {value} in {envvars.RESOURCE_GROUP_NAME}'))
|
|
587
|
+
|
|
588
|
+
if param.name == "edge_device_id":
|
|
589
|
+
output.param("EDGE DEVICE", value, f("Setting Edge Device to '{value}'..."), azure_cli_processing_complete)
|
|
590
|
+
|
|
591
|
+
envvars.EDGE_DEVICE_ID = value
|
|
592
|
+
if not azure_cli.edge_device_exists(value, envvars.IOTHUB_NAME, envvars.RESOURCE_GROUP_NAME):
|
|
593
|
+
if not azure_cli.create_edge_device(value, envvars.IOTHUB_NAME, envvars.RESOURCE_GROUP_NAME):
|
|
594
|
+
raise click.BadParameter(f('Could not create IoT Edge Device {value} in {envvars.IOTHUB_NAME} in {envvars.RESOURCE_GROUP_NAME}'))
|
|
595
|
+
|
|
596
|
+
output.header("CONNECTION STRINGS")
|
|
597
|
+
envvars.IOTHUB_CONNECTION_STRING = azure_cli.get_iothub_connection_string(envvars.IOTHUB_NAME, envvars.RESOURCE_GROUP_NAME)
|
|
598
|
+
envvars.DEVICE_CONNECTION_STRING = azure_cli.get_device_connection_string(envvars.EDGE_DEVICE_ID, envvars.IOTHUB_NAME, envvars.RESOURCE_GROUP_NAME)
|
|
599
|
+
|
|
600
|
+
if envvars.IOTHUB_CONNECTION_STRING and envvars.DEVICE_CONNECTION_STRING:
|
|
601
|
+
output.info(f("IOTHUB_CONNECTION_STRING=\"{envvars.IOTHUB_CONNECTION_STRING}\""))
|
|
602
|
+
output.info(f("DEVICE_CONNECTION_STRING=\"{envvars.DEVICE_CONNECTION_STRING}\""))
|
|
603
|
+
|
|
604
|
+
azure_cli_processing_complete = True
|
|
605
|
+
|
|
606
|
+
output.line()
|
|
607
|
+
|
|
608
|
+
return value
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
def list_edge_devices_and_set_default():
|
|
612
|
+
if not azure_cli.list_edge_devices(envvars.IOTHUB_NAME):
|
|
613
|
+
sys.exit()
|
|
614
|
+
return "iotedgedev-edgedevice"
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
def list_iot_hubs_and_set_default():
|
|
618
|
+
if not azure_cli.list_iot_hubs(envvars.RESOURCE_GROUP_NAME):
|
|
619
|
+
sys.exit()
|
|
620
|
+
|
|
621
|
+
first_iothub = azure_cli.get_first_iothub(envvars.RESOURCE_GROUP_NAME)
|
|
622
|
+
if first_iothub:
|
|
623
|
+
return first_iothub
|
|
624
|
+
else:
|
|
625
|
+
subscription_rg_hash = hashlib.sha1((default_subscriptionId + envvars.RESOURCE_GROUP_NAME).encode('utf-8')).hexdigest()[:6]
|
|
626
|
+
return "iotedgedev-iothub-" + subscription_rg_hash
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
def list_resource_groups_and_set_default():
|
|
630
|
+
if not azure_cli.list_resource_groups():
|
|
631
|
+
sys.exit()
|
|
632
|
+
return "iotedgedev-rg"
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
def list_subscriptions_and_set_default():
|
|
636
|
+
global default_subscriptionId
|
|
637
|
+
# first verify that we have an existing auth token in cache, otherwise login using interactive
|
|
638
|
+
if not default_subscriptionId:
|
|
639
|
+
default_subscriptionId = azure_cli.user_has_logged_in()
|
|
640
|
+
|
|
641
|
+
if not default_subscriptionId and not azure_cli.login_interactive():
|
|
642
|
+
sys.exit()
|
|
643
|
+
|
|
644
|
+
output.header("SUBSCRIPTION")
|
|
645
|
+
|
|
646
|
+
if not azure_cli.list_subscriptions():
|
|
647
|
+
sys.exit()
|
|
648
|
+
default_subscriptionId = azure_cli.get_default_subscription()
|
|
649
|
+
return default_subscriptionId
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
def header_and_default(header, default, default2=None):
|
|
653
|
+
output.header(header)
|
|
654
|
+
if default == '' and default2 is not None:
|
|
655
|
+
return default2
|
|
656
|
+
return default
|
|
657
|
+
|
|
658
|
+
|
|
659
|
+
@iothub.command(context_settings=CONTEXT_SETTINGS,
|
|
660
|
+
help="Retrieve or create required Azure resources",
|
|
661
|
+
name="setup")
|
|
662
|
+
@click.option('--credentials',
|
|
663
|
+
envvar=envvars.get_envvar_key_if_val("CREDENTIALS"),
|
|
664
|
+
required=False,
|
|
665
|
+
hide_input=True,
|
|
666
|
+
default=(None, None),
|
|
667
|
+
type=(str, str),
|
|
668
|
+
callback=validate_option,
|
|
669
|
+
help="Enter Azure Credentials (username password).")
|
|
670
|
+
@click.option('--service-principal',
|
|
671
|
+
envvar=envvars.get_envvar_key_if_val("SERVICE_PRINCIPAL"),
|
|
672
|
+
required=False,
|
|
673
|
+
hide_input=True,
|
|
674
|
+
default=(None, None, None),
|
|
675
|
+
type=(str, str, str),
|
|
676
|
+
callback=validate_option,
|
|
677
|
+
help="Enter Azure Service Principal Credentials (username password tenant).")
|
|
678
|
+
@click.option('--subscription',
|
|
679
|
+
envvar=envvars.get_envvar_key_if_val("SUBSCRIPTION_ID"),
|
|
680
|
+
default=lambda: list_subscriptions_and_set_default(),
|
|
681
|
+
required=True,
|
|
682
|
+
callback=validate_option,
|
|
683
|
+
prompt="Select an Azure Subscription Name or Id:",
|
|
684
|
+
help="The Azure Subscription Name or Id.")
|
|
685
|
+
@click.option('--resource-group-location',
|
|
686
|
+
envvar=envvars.get_envvar_key_if_val("RESOURCE_GROUP_LOCATION"),
|
|
687
|
+
required=True,
|
|
688
|
+
default=lambda: header_and_default('RESOURCE GROUP LOCATION', envvars.RESOURCE_GROUP_LOCATION, 'westus'),
|
|
689
|
+
type=click.Choice(['australiaeast', 'australiasoutheast', 'brazilsouth', 'canadacentral', 'canadaeast', 'centralindia', 'centralus', 'eastasia', 'eastus', 'eastus2',
|
|
690
|
+
'japanwest', 'japaneast', 'northeurope', 'northcentralus', 'southindia', 'uksouth', 'ukwest', 'westus', 'westeurope', 'southcentralus', 'westcentralus', 'westus2']),
|
|
691
|
+
callback=validate_option,
|
|
692
|
+
prompt="Enter a Resource Group Location:",
|
|
693
|
+
help="The Resource Group Location.")
|
|
694
|
+
@click.option('--resource-group-name',
|
|
695
|
+
envvar=envvars.get_envvar_key_if_val("RESOURCE_GROUP_NAME"),
|
|
696
|
+
required=True,
|
|
697
|
+
default=lambda: list_resource_groups_and_set_default(),
|
|
698
|
+
type=str,
|
|
699
|
+
callback=validate_option,
|
|
700
|
+
prompt="Enter Resource Group Name (Creates a new Resource Group if not found):",
|
|
701
|
+
help="The Resource Group Name (Creates a new Resource Group if not found).")
|
|
702
|
+
@click.option('--iothub-sku',
|
|
703
|
+
envvar=envvars.get_envvar_key_if_val("IOTHUB_SKU"),
|
|
704
|
+
required=True,
|
|
705
|
+
default=lambda: header_and_default('IOTHUB SKU', 'F1'),
|
|
706
|
+
type=click.Choice(['F1', 'S1', 'S2', 'S3']),
|
|
707
|
+
callback=validate_option,
|
|
708
|
+
prompt="Enter IoT Hub SKU (F1|S1|S2|S3):",
|
|
709
|
+
help="The IoT Hub SKU.")
|
|
710
|
+
@click.option('--iothub-name',
|
|
711
|
+
envvar=envvars.get_envvar_key_if_val("IOTHUB_NAME"),
|
|
712
|
+
required=True,
|
|
713
|
+
default=lambda: list_iot_hubs_and_set_default(),
|
|
714
|
+
type=str,
|
|
715
|
+
callback=validate_option,
|
|
716
|
+
prompt='Enter the IoT Hub Name (Creates a new IoT Hub if not found):',
|
|
717
|
+
help='The IoT Hub Name (Creates a new IoT Hub if not found).')
|
|
718
|
+
@click.option('--edge-device-id',
|
|
719
|
+
envvar=envvars.get_envvar_key_if_val("EDGE_DEVICE_ID"),
|
|
720
|
+
required=True,
|
|
721
|
+
default=lambda: list_edge_devices_and_set_default(),
|
|
722
|
+
type=str,
|
|
723
|
+
callback=validate_option,
|
|
724
|
+
prompt='Enter the IoT Edge Device Id (Creates a new Edge Device if not found):',
|
|
725
|
+
help='The IoT Edge Device Id (Creates a new Edge Device if not found).')
|
|
726
|
+
@click.option('--update-dotenv',
|
|
727
|
+
"-u",
|
|
728
|
+
envvar=envvars.get_envvar_key_if_val("UPDATE_DOTENV"),
|
|
729
|
+
required=True,
|
|
730
|
+
default=False,
|
|
731
|
+
show_default=True,
|
|
732
|
+
is_flag=True,
|
|
733
|
+
prompt='Update the .env file with connection strings?',
|
|
734
|
+
help='If True, the current .env will be updated with the IoT Hub and Device connection strings.')
|
|
735
|
+
@with_telemetry
|
|
736
|
+
def setup_iothub(credentials,
|
|
737
|
+
service_principal,
|
|
738
|
+
subscription,
|
|
739
|
+
resource_group_name,
|
|
740
|
+
resource_group_location,
|
|
741
|
+
iothub_sku,
|
|
742
|
+
iothub_name,
|
|
743
|
+
edge_device_id,
|
|
744
|
+
update_dotenv):
|
|
745
|
+
if update_dotenv:
|
|
746
|
+
if envvars.backup_dotenv():
|
|
747
|
+
envvars.save_envvar("IOTHUB_CONNECTION_STRING", envvars.IOTHUB_CONNECTION_STRING)
|
|
748
|
+
envvars.save_envvar("DEVICE_CONNECTION_STRING", envvars.DEVICE_CONNECTION_STRING)
|
|
749
|
+
output.info("Updated current .env file")
|
|
750
|
+
|
|
751
|
+
|
|
752
|
+
@docker.command(context_settings=CONTEXT_SETTINGS,
|
|
753
|
+
help="Pull Edge runtime images from Microsoft Container Registry and push to your specified container registry. "
|
|
754
|
+
"Also, update config files to use CONTAINER_REGISTRY_* instead of the Microsoft Container Registry. See CONTAINER_REGISTRY environment variables.",
|
|
755
|
+
short_help="Pull Edge runtime images from MCR and push to your specified container registry",
|
|
756
|
+
name="setup")
|
|
757
|
+
@with_telemetry
|
|
758
|
+
def setup_registry():
|
|
759
|
+
utility = Utility(envvars, output)
|
|
760
|
+
dock = Docker(envvars, utility, output)
|
|
761
|
+
|
|
762
|
+
dock.setup_registry()
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
@docker.command(context_settings=CONTEXT_SETTINGS, help="Remove all the containers and images")
|
|
766
|
+
@click.option("--module",
|
|
767
|
+
"-m",
|
|
768
|
+
default=False,
|
|
769
|
+
show_default=True,
|
|
770
|
+
required=False,
|
|
771
|
+
is_flag=True,
|
|
772
|
+
help="Remove only the Edge module containers and images, not EdgeAgent or EdgeHub")
|
|
773
|
+
@click.option("--container",
|
|
774
|
+
"-c",
|
|
775
|
+
default=False,
|
|
776
|
+
show_default=True,
|
|
777
|
+
required=False,
|
|
778
|
+
is_flag=True,
|
|
779
|
+
help="Remove all the containers")
|
|
780
|
+
@click.option("--image",
|
|
781
|
+
"-i",
|
|
782
|
+
default=False,
|
|
783
|
+
show_default=True,
|
|
784
|
+
required=False,
|
|
785
|
+
is_flag=True,
|
|
786
|
+
help="Remove all the images")
|
|
787
|
+
@with_telemetry
|
|
788
|
+
def clean(module, container, image):
|
|
789
|
+
utility = Utility(envvars, output)
|
|
790
|
+
dock = Docker(envvars, utility, output)
|
|
791
|
+
|
|
792
|
+
if module:
|
|
793
|
+
dock.remove_modules()
|
|
794
|
+
|
|
795
|
+
if container:
|
|
796
|
+
dock.remove_containers()
|
|
797
|
+
|
|
798
|
+
if image:
|
|
799
|
+
dock.remove_images()
|
|
800
|
+
|
|
801
|
+
|
|
802
|
+
@docker.command(context_settings=CONTEXT_SETTINGS,
|
|
803
|
+
help="Open a new terminal window for EdgeAgent, EdgeHub and each Edge module and save to LOGS_PATH. "
|
|
804
|
+
"You can configure the terminal command with LOGS_CMD.",
|
|
805
|
+
short_help="Open a new terminal window for EdgeAgent, EdgeHub and each Edge module and save to LOGS_PATH")
|
|
806
|
+
@click.option("--show",
|
|
807
|
+
"-l",
|
|
808
|
+
default=False,
|
|
809
|
+
show_default=True,
|
|
810
|
+
required=False,
|
|
811
|
+
is_flag=True,
|
|
812
|
+
help="Open a new terminal window for EdgeAgent, EdgeHub and each Edge module. You can configure the terminal command with LOGS_CMD.")
|
|
813
|
+
@click.option("--save",
|
|
814
|
+
"-s",
|
|
815
|
+
default=False,
|
|
816
|
+
show_default=True,
|
|
817
|
+
required=False,
|
|
818
|
+
is_flag=True,
|
|
819
|
+
help="Save EdgeAgent, EdgeHub and each Edge module logs to LOGS_PATH.")
|
|
820
|
+
@with_telemetry
|
|
821
|
+
def log(show, save):
|
|
822
|
+
utility = Utility(envvars, output)
|
|
823
|
+
dock = Docker(envvars, utility, output)
|
|
824
|
+
dock.handle_logs_cmd(show, save)
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
main.add_command(log)
|
|
828
|
+
|
|
829
|
+
if __name__ == "__main__":
|
|
830
|
+
main()
|