зеркало из https://github.com/Azure/iotedgedev.git
Simplified API, azure setup from EnvVars (#49)
This commit is contained in:
Родитель
d253346e42
Коммит
3296f2fc4a
32
.env.tmp
32
.env.tmp
|
@ -3,13 +3,16 @@
|
|||
#
|
||||
|
||||
IOTHUB_CONNECTION_STRING=""
|
||||
|
||||
DEVICE_CONNECTION_STRING=""
|
||||
|
||||
#
|
||||
# CONTAINER REGISTRY
|
||||
#
|
||||
# To host your modules
|
||||
# "localhost:5000" - to use local registry
|
||||
# Settings for your container registry, set CONTAINER_REGISTRY_SERVER to the following:
|
||||
# Local Registry: "localhost:5000" - USERNAME/PASSWORD not required.
|
||||
# Azure Container Registry: "jong.azurecr.io", Also set USERNAME/PASSWORD
|
||||
# Docker Hub: "jongallant" - Your Docker hub username. Enter your Docker hub username into the CONTAINER_REGISTRY_USERNAME setting. Also set the PASSWORD.
|
||||
|
||||
CONTAINER_REGISTRY_SERVER="localhost:5000"
|
||||
CONTAINER_REGISTRY_USERNAME=""
|
||||
|
@ -38,7 +41,7 @@ RUNTIME_HOST_NAME="."
|
|||
|
||||
RUNTIME_TAG="1.0-preview"
|
||||
|
||||
RUNTIME_VERBOSITY="DEBUG"
|
||||
RUNTIME_VERBOSITY="INFO"
|
||||
# "DEBUG", "INFO", "ERROR", "WARNING"
|
||||
|
||||
#
|
||||
|
@ -58,10 +61,9 @@ CONTAINER_TAG=""
|
|||
DOTNET_VERBOSITY="q"
|
||||
# q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]
|
||||
|
||||
|
||||
DOTNET_EXE_DIR="./bin/Debug/netcoreapp2.0/publish"
|
||||
# The default EXE_DIR directory to pass to the Docker build command.
|
||||
|
||||
|
||||
#
|
||||
# SOLUTION SETTINGS
|
||||
#
|
||||
|
@ -81,4 +83,22 @@ LOGS_CMD="start /B start cmd.exe @cmd /k docker logs {0} -f"
|
|||
# "start /B start cmd.exe @cmd /k docker logs {0} -f" - for CMD
|
||||
# "docker logs {0} -f -new_console:sV" - for ConEmu
|
||||
|
||||
|
||||
#
|
||||
# AZURE SETTINGS
|
||||
#
|
||||
# These settings will override parameters to the `iotedgedev azure --setup` command.
|
||||
# CREDENTIALS="username password"
|
||||
# SERVICE_PRINCIPAL="username password tenant"
|
||||
# RESOURCE_GROUP_LOCATION="australiaeast|australiasoutheast|brazilsouth|canadacentral|canadaeast|centralindia|centralus|eastasia|eastus|eastus2|japanwest|japaneast|northeurope|northcentralus|southindia|uksouth|ukwest|westus|westeurope|southcentralus|westcentralus|westus2"
|
||||
# IOTHUB_SKU="F1|S1|S2|S3"
|
||||
# UPDATE_DOTENV="True|False"
|
||||
|
||||
SUBSCRIPTION_ID=""
|
||||
RESOURCE_GROUP_NAME=""
|
||||
RESOURCE_GROUP_LOCATION=""
|
||||
IOTHUB_NAME=""
|
||||
IOTHUB_SKU=""
|
||||
EDGE_DEVICE_ID=""
|
||||
CREDENTIALS=""
|
||||
SERVICE_PRINCIPAL=""
|
||||
UPDATE_DOTENV=""
|
||||
|
|
|
@ -76,9 +76,11 @@ venv
|
|||
|
||||
py36
|
||||
.pypirc
|
||||
test_solution
|
||||
tests/test_solution
|
||||
README
|
||||
|
||||
node_modules
|
||||
|
||||
/docker/linux/Dockerfile.expanded
|
||||
/docker/linux/Dockerfile.expanded
|
||||
|
||||
.pytest_cache
|
|
@ -2,7 +2,7 @@ include HISTORY.rst
|
|||
include LICENSE
|
||||
include README.md
|
||||
include iotedgedev/template/template.zip
|
||||
|
||||
include iotedgedev/monitor.js
|
||||
recursive-include tests *
|
||||
recursive-exclude * __pycache__
|
||||
recursive-exclude * *.py[co]
|
199
README.md
199
README.md
|
@ -20,45 +20,64 @@ The only thing you need to install is Docker. All of the other dev dependencies
|
|||
|
||||
`iotedgedev init`
|
||||
|
||||
1. Build and Deploy Modules
|
||||
1. Build IoT Edge Modules
|
||||
|
||||
`iotedgedev modules --build --deploy`
|
||||
`iotedgedev build`
|
||||
|
||||
1. Setup and Start the IoT Edge Runtime
|
||||
> You can also combine build and deploy with `iotedgedev build --deploy`
|
||||
|
||||
`iotedgedev runtime --setup --start`
|
||||
1. Deploy Modules to IoT Edge Device
|
||||
|
||||
`iotedgedev deploy`
|
||||
|
||||
1. Start the IoT Edge Runtime
|
||||
|
||||
`iotedgedev start`
|
||||
|
||||
1. Monitor Messages sent from IoT Edge to IoT Hub
|
||||
|
||||
`iotedgedev iothub --monitor-events`
|
||||
`iotedgedev monitor`
|
||||
|
||||
## Overview
|
||||
The **Azure IoT Edge Dev Tool** enables you to do all of the following with simple one-line CLI commands.
|
||||
|
||||
1. **Install**: Install the Azure IoT Edge Dev Tool:
|
||||
1. **Start Container**: Install the Azure IoT Edge Dev Tool:
|
||||
|
||||
`pip install azure-iot-edge-dev-tool`
|
||||
`docker run -it -v /var/run/docker.sock:/var/run/docker.sock -v c:/temp/iotedge:/iotedge jongallant/iotedgedev`
|
||||
|
||||
This container includes all of the dependencies you need for IoT Edge development, including:
|
||||
|
||||
-
|
||||
|
||||
You can also directly install the tool with: `pip install azure-iot-edge-dev-tool`
|
||||
|
||||
1. **Solution**: Create a new IoT Edge Solution that includes a sample module and all the the required configuration files.
|
||||
1. **Create Solution**: Create a new IoT Edge Solution that includes a sample module and all the the required configuration files.
|
||||
|
||||
`iotedgedev solution --create edgesolution1`
|
||||
`iotedgedev solution edgesolution1`
|
||||
|
||||
1. **Azure**: Creates or selects your Azure IoT Hub and Edge Device and updates your Environment Variables.
|
||||
`cd edgesolution1`
|
||||
|
||||
`iotedgedev azure --setup`
|
||||
1. **Setup Azure**: Creates or selects your Azure IoT Hub and Edge Device and updates your Environment Variables.
|
||||
|
||||
`iotedgedev azure`
|
||||
|
||||
> This must be run from the root of your solution, so make sure you cd into the `edgesolution1` folder before you run this command.
|
||||
|
||||
1. **Build & Deploy**: Build, Push and Deploy modules:
|
||||
|
||||
`iotedgedev modules --build --deploy`
|
||||
`iotedgedev build --deploy`
|
||||
|
||||
> This will `dotnet build`, `publish`, `docker build, tag and push` and `deploy modules` to your IoT Edge device.
|
||||
|
||||
If your module is not dotnet, then the dotnet build/publish steps will be skipped.
|
||||
|
||||
> This will `build`, `publish`, `docker build, tag and push` and `deploy modules` to your IoT Edge device.
|
||||
1. **Setup & Start**: Setup and Start the IoT Edge Runtime:
|
||||
|
||||
`iotedgedev runtime --setup --start`
|
||||
`iotedgedev start`
|
||||
|
||||
1. **View Messages**: View Messages Sent from IoT Edge to IoT Hub:
|
||||
|
||||
`iotedgedev iothub --monitor-events`
|
||||
`iotedgedev monitor`
|
||||
|
||||
1. **View Logs**: View and Save Docker log files:
|
||||
|
||||
|
@ -84,22 +103,28 @@ Please see [Azure IoT Edge Dev Resources](https://github.com/jonbgallant/azure-i
|
|||
|
||||
## Setup
|
||||
### Azure Setup
|
||||
|
||||
#### Manual Setup
|
||||
1. [**Create Azure IoT Hub**](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-csharp-csharp-getstarted#create-an-iot-hub)
|
||||
1. **Create Edge Device** using the Azure Portal
|
||||
- In your IoT Hub, click "IoT Edge", then click "Add IoT Edge Device"
|
||||
1. [**Create Azure Container Registry**](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-portal)
|
||||
> Only needed when you want to push your modules to a central registry. You can run a local registry by setting the .env/CONTAINER_REGISTRY_SERVER setting to `localhost:5000`.
|
||||
|
||||
- Make sure you enable Admin Access when you create the Azure Container Registry
|
||||
|
||||
#### Automated Setup
|
||||
|
||||
You can use the **Azure IoT Edge Dev Tool** to create a new IoT Hub and a new Edge device. This command will also print the corresponding connection strings:
|
||||
The following will show you how to setup your Azure Resources via the CLI instead of using the Portal.
|
||||
|
||||
First, create a solution with the following command:
|
||||
|
||||
`iotedgedev solution edgesolution1`
|
||||
|
||||
Then, cd into that solution:
|
||||
|
||||
`cd edgesolution`
|
||||
|
||||
Then, run the `iotedgedev azure` command to setup your Azure Resources. This command will bring you through a series of prompts to create Azure Resources and retrieve your IoT Hub and Edge Device connection strings and save them to the `.env` file in the root of the project. All subsequent commands will use those environment variables.
|
||||
|
||||
Here are all the `azure` command options:
|
||||
|
||||
> You can override all of these parameters with environment variables. Please see the .env file in your solution for details.
|
||||
|
||||
```
|
||||
iotedgedev azure --setup
|
||||
iotedgedev azure
|
||||
--credentials USERNAME PASSWORD
|
||||
--service-principal USERNAME PASSWORD TENANT
|
||||
--subscription THE_SUBSCRIPTION_ID
|
||||
--resource-group-location THE_RG_LOCATION
|
||||
--resource-group-name THE_RG_NAME
|
||||
|
@ -109,14 +134,75 @@ iotedgedev azure --setup
|
|||
--update-dotenv
|
||||
```
|
||||
|
||||
You can use the following `az cli` command to create a service principal:
|
||||
|
||||
> Note: Running `iotedgedev azure --setup` without the rest parameters will save you time from looking up the required parameter values. The command will help you choose the parameters in an interactive way
|
||||
```
|
||||
az ad sp create-for-rbac -n "iotedgedev01"
|
||||
```
|
||||
|
||||
> Note: Running `iotedgedev azure` without any other parameters will save you time from looking up the required parameter values. The command will help you choose the parameters in an interactive way.
|
||||
|
||||
Alternatively, you can deploy the IoT Hub **and** Container Registry with this **Deploy to Azure** template:
|
||||
|
||||
[![Azure Deployment](https://azuredeploy.net/deploybutton.png)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fjonbgallant%2Fazure-iot-edge-dev-tool%2Fmaster%2Fassets%2Fdeploy%2FARMDeployment%2Fazuredeploy.json)
|
||||
|
||||
> Note: If you do not need a Container Registry, or are planning to use a local registry, then you should run the **iotedgedev azure --setup** command instead of running this **Deploy to Azure** template, because the template includes a Container Registry.
|
||||
> Note: If you do not need a Container Registry, or are planning to use a local registry, then you should run the **iotedgedev azure** command instead of running this **Deploy to Azure** template, because the template includes a Container Registry.
|
||||
|
||||
#### Manual Setup
|
||||
1. [**Create Azure IoT Hub**](https://docs.microsoft.com/en-us/azure/iot-hub/iot-hub-csharp-csharp-getstarted#create-an-iot-hub)
|
||||
1. **Create Edge Device** using the Azure Portal
|
||||
- In your IoT Hub, click "IoT Edge", then click "Add IoT Edge Device"
|
||||
|
||||
1. **Container Registry**
|
||||
When you develop for IoT Edge, you need to host your images in a container registry, which the IoT Edge runtime will fetch the images from when it starts.
|
||||
|
||||
> By default, the IoT Edge Dev Tool, will use the Local Registry.
|
||||
|
||||
We have tested the following options, but you can host your images on any Docker compatible registry host.
|
||||
|
||||
1. Local Registry
|
||||
|
||||
Set CONTAINER_REGISTRY_SERVER to localhost:5000 and leave CONTAINER_REGISTRY_USERNAME/CONTAINER_REGISTRY_PASSWORD blank.
|
||||
|
||||
`CONTAINER_REGISTRY_SERVER="localhost:5000"`
|
||||
|
||||
1. Azure Container Registry
|
||||
|
||||
You can create an [**Azure Container Registry**](https://docs.microsoft.com/en-us/azure/container-registry/container-registry-get-started-portal) and host your images there.
|
||||
- Make sure you enable Admin Access when you create the Azure Container Registry
|
||||
|
||||
After created, open .env and set the following:
|
||||
|
||||
```
|
||||
CONTAINER_REGISTRY_SERVER="ACR URI"
|
||||
CONTAINER_REGISTRY_USERNAME="ACR USERNAME"
|
||||
CONTAINER_REGISTRY_PASSWORD="ACR PASSWORD"
|
||||
```
|
||||
|
||||
Example:
|
||||
```
|
||||
CONTAINER_REGISTRY_SERVER="jong.azurecr.io"
|
||||
CONTAINER_REGISTRY_USERNAME="jong"
|
||||
CONTAINER_REGISTRY_PASSWORD="p@$$w0rd"
|
||||
```
|
||||
|
||||
1. Docker Hub
|
||||
|
||||
You can also host your images on Docker Hub. Create a Docker Hub account and then open .env and enter the following:
|
||||
|
||||
```
|
||||
CONTAINER_REGISTRY_SERVER="DOCKER HUB USERNAME"
|
||||
CONTAINER_REGISTRY_USERNAME="DOCKER HUB USERNAME"
|
||||
CONTAINER_REGISTRY_PASSWORD="DOCKER HUB PASSWORD"
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
CONTAINER_REGISTRY_SERVER="jongallant"
|
||||
CONTAINER_REGISTRY_USERNAME="jongallant"
|
||||
CONTAINER_REGISTRY_PASSWORD="p@$$w0rd"
|
||||
```
|
||||
|
||||
### Dev Machine Setup
|
||||
|
||||
|
@ -129,12 +215,14 @@ You can use the IoT Edge Dev Tool container to avoid having to install all the d
|
|||
|
||||
> (Only runs on Linux Containers at this time. Windows Container support coming soon.)
|
||||
|
||||
1. Install Docker
|
||||
1. Install **[Docker](https://docs.docker.com/engine/installation/)**
|
||||
|
||||
1. Create Local Folder on Host Dev Machine that will contain your IoT Edge Solutions.
|
||||
|
||||
`c:/temp/iotedge`
|
||||
|
||||
> This allows you to use VS Code on your host machine and run all the `iotedgedev` commands in your container. We'll mount this folder to the container in the next step.
|
||||
|
||||
1. Start Container:
|
||||
|
||||
`docker run -it -v /var/run/docker.sock:/var/run/docker.sock -v c:/temp/iotedge:/iotedge jongallant/iotedgedev`
|
||||
|
@ -232,7 +320,8 @@ The following command will setup the folder structure required for this module
|
|||
> Replace `edgesolution1` with the name of your solution. Use `.` to create in the current folder.
|
||||
|
||||
```
|
||||
iotedgedev solution --create edgesolution1
|
||||
iotedgedev solution edgesolution1
|
||||
cd edgesolution1
|
||||
```
|
||||
|
||||
#### Folder Structure
|
||||
|
@ -251,7 +340,7 @@ When you create a new solution, it will have the following contents:
|
|||
1. **Configuration File Templates** - There are two files in the root of the solution:
|
||||
|
||||
- `deployment.template.json` - Contains the config that is deployed to your IoT Edge device. It contains references to your modules, module routes and desired property information.
|
||||
- `runtime.template.json` - Contains the config used by your IoT Edge runtime. It contains your device connection string, your container registry settings and is used when you call the `runtime --setup` command.
|
||||
- `runtime.template.json` - Contains the config used by your IoT Edge runtime. It contains your device connection string, your container registry settings and is used when you call the `iotedgedev setup` or `iotedgedev start` commands.
|
||||
|
||||
1. **.config folder** - All expanded config files are copied to this folder and these files are used at runtime.
|
||||
|
||||
|
@ -275,7 +364,7 @@ The settings used for this module are stored in a .env file in the root of your
|
|||
This tool offers a wizard-like command to guide you through setting up Azure and also setting up the Environment Variables properly.
|
||||
|
||||
```
|
||||
iotedgedev azure --setup
|
||||
iotedgedev azure
|
||||
```
|
||||
|
||||
### Step 3: Build and Deploy Modules
|
||||
|
@ -283,10 +372,10 @@ The settings used for this module are stored in a .env file in the root of your
|
|||
> Use `sudo` for Linux. You __will not__ be able to build on the Raspberry Pi, because the .NET Core SDK does not support ARM. You can build on an x86 based machine and deploy to Pi.
|
||||
|
||||
```
|
||||
iotedgedev modules --build --deploy
|
||||
iotedgedev build --deploy
|
||||
```
|
||||
|
||||
The- `--build` command will build each module in the `modules` folder and push it to your container registry. The- `--deploy` command will apply the generated `.config/deployment.json` configuration file to your IoT Edge device.
|
||||
The- `build` command will build each module in the `modules` folder and push it to your container registry. The- `--deploy` command will apply the generated `.config/deployment.json` configuration file to your IoT Edge device. You could also call `deploy` directly with `iotedgedev deploy`.
|
||||
|
||||
You can configure what modules will be built and deployed by using the `ACTIVE_MODULES` env var in the `.env` file. You can configure which Dockerfiles get built and deployed by using the `ACTIVE_DOCKER_DIRS` env var.
|
||||
|
||||
|
@ -295,15 +384,15 @@ You can configure what modules will be built and deployed by using the `ACTIVE_M
|
|||
> Use 'sudo' for Linux/RaspberryPi
|
||||
|
||||
```
|
||||
iotedgedev runtime --setup --start
|
||||
iotedgedev start
|
||||
```
|
||||
|
||||
The- `--setup` command will apply the `/.config/runtime.json` file to your IoT Edge device. The- `--start` command will start the IoT Edge runtime.
|
||||
The `start` command will apply the `/.config/runtime.json` file to your IoT Edge device and will start the IoT Edge runtime. You can also call `iotedgedev setup` and `iotedgedev start` independently.
|
||||
|
||||
### Step 5: Monitor Messages
|
||||
|
||||
```
|
||||
iotedgedev iothub --monitor-events
|
||||
iotedgedev monitor
|
||||
```
|
||||
|
||||
This will print messages sent from the device specified in DEVICE_CONNECTION_STRING. To use this command, you first need to install the [iothub-explorer](https://github.com/Azure/iothub-explorer) npm package with the following command:
|
||||
|
@ -336,7 +425,7 @@ After you have everything running from the IoT Edge Tool solution template, the
|
|||
dotnet new aziotedgemodule -o modules/mymodule
|
||||
```
|
||||
|
||||
Now, when you run `iotedgedev modules --build` you will see that `mymodule` is also built and pushed to your container registry.
|
||||
Now, when you run `iotedgedev build` you will see that `mymodule` is also built and pushed to your container registry.
|
||||
|
||||
1. Add Message Property
|
||||
|
||||
|
@ -390,14 +479,14 @@ After you have everything running from the IoT Edge Tool solution template, the
|
|||
|
||||
> You will notice that the IoT Edge Runtime automatically detects a new deployment, retrieves the new module, applies the new route and keeps sending messages.
|
||||
|
||||
`iotedgedev modules --build --deploy`
|
||||
`iotedgedev build --deploy`
|
||||
|
||||
1. Monitor Messages
|
||||
|
||||
Now when we view the messages flowing through the system, we'll see an additional 'abc' property:
|
||||
|
||||
```bash
|
||||
iotedgedev iothub --monitor-events
|
||||
iotedgedev monitor
|
||||
```
|
||||
|
||||
```javascript
|
||||
|
@ -434,8 +523,26 @@ The `iotedgedev` module has the following commands:
|
|||
**solution**
|
||||
|
||||
`iotedgedev solution`
|
||||
- `--create TEXT` Creates a new Azure IoT Edge Solution. Use `--create .` to create in current folder. Use `--create TEXT` to create in a subfolder.
|
||||
- `name` Creates a new Azure IoT Edge Solution. Use `.` to create in current folder. Use `iotedgedev solution [name]` to create in a subfolder.
|
||||
- `--create TEXT` Creates a new Azure IoT Edge Solution. Use `--create .` to create in current folder. Use `--create [name]` to create in a subfolder.
|
||||
|
||||
**build**
|
||||
`iotedgedev build` Builds and pushes modules specified in ACTIVE_MODULES Environment Variable to specified container registry. You can also pass a `--deploy` flag to build and deploy in one command: `iotedgedev build --deploy`
|
||||
|
||||
**deploy**
|
||||
`iotedgedev deploy` Deploys modules to Edge device using deployment.json in the /.config directory.
|
||||
|
||||
**start**
|
||||
`iotedgedev start` Setups up and Starts Edge Runtime. Calls iotedgectl setup and start.
|
||||
|
||||
**stop**
|
||||
`iotedgedev stop` Stops Edge Runtime. Calls iotedgectl stop.
|
||||
|
||||
**restart**
|
||||
`iotedgedev restart` Restarts Edge Runtime. Calls iotedgectl stop, removes module containers and images, calls iotedgectl setup (with --config-file) and then calls iotedgectl start.
|
||||
|
||||
**monitor**
|
||||
`iotedgedev monitor` Displays events that are sent from IoT Hub device to IoT Hub.
|
||||
|
||||
**azure**
|
||||
|
||||
|
@ -536,6 +643,8 @@ Instead of using a cloud based container registry, you can use a local Docker re
|
|||
1. Set `CONTAINER_REGISTRY_SERVER` in .env to `localhost:5000`. You can enter a different port if you'd like to.
|
||||
1. Add `localhost:5000` and `127.0.0.1:5000` to Docker -> Settings -> Daemon -> Insecure Registries
|
||||
|
||||
> In the latest `iotedgedev` build, step 2 above hasn't been required. But, if you run into issues, you may want to try adding those Insecure Registries.
|
||||
|
||||
`iotedgedev` will look for `localhost` in your setting and take care of the rest for you.
|
||||
|
||||
## IoT Edge Device Setup
|
||||
|
@ -549,7 +658,7 @@ iotedgectl start
|
|||
|
||||
Having said that, there's nothing stopping you from deploying `iotedgedev` to your IoT Edge device. It may be helpful if you want to run the `iotedgedev docker --clean` command to clean up Docker containers and images. Or if you want to run `iotedgedev docker --show-logs` to see all the log files on the device or `iotedgedev docker --save-logs` to output to the LOGS_PATH directory.
|
||||
|
||||
> Please note that the .NET Core SDK does not support ARM, so you will not be able to run `modules --build` or `modules --deploy` directly on a Raspberry Pi.
|
||||
> Please note that the .NET Core SDK does not support ARM, so you will not be able to run `build` directly on a Raspberry Pi.
|
||||
|
||||
### Raspberry Pi
|
||||
|
||||
|
@ -685,8 +794,12 @@ Please fork, branch and pull-request any changes you'd like to make.
|
|||
|
||||
`git clone https://github.com/jonbgallant/azure-iot-edge-dev-tool.git`
|
||||
|
||||
1. Rename `.env.tmp` in the root of the repo to `.env` and set the `IOTHUB_CONNECTION_STRING_` and `DEVICE_CONNECTION_STRING` values to settings from your IoT Hub and Edge Device. To set these values you could run `iotedgedev azure` in the root of the repo.
|
||||
|
||||
1. Install **[Microsoft Visual C++ Build Tools](http://landinghub.visualstudio.com/visual-cpp-build-tools)**
|
||||
|
||||
1. Run `npm install` from the root directory to install the required npm packages for iothub-explorer calls.
|
||||
|
||||
1. Install **OpenSSL 1.1.0g**
|
||||
- Windows
|
||||
1. [Download from OpenSSL's website](https://www.openssl.org/source/openssl-1.1.0g.tar.gz)
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
|
||||
__author__ = 'Jon Gallant'
|
||||
__email__ = 'info@jongallant.com'
|
||||
__version__ = '0.67.0'
|
||||
__version__ = '0.70.0'
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import sys
|
||||
|
||||
# We had to implement this custom arg parsing class because Click doesn't have a handler to detect command before any arguments are parsed, which we need for the dotenv load command. We don't want to load dotenv for some commands and we terse output for other commands.
|
||||
|
||||
|
||||
class Args():
|
||||
def get_current_command(self):
|
||||
if sys.argv and len(sys.argv) > 1:
|
||||
return sys.argv[1]
|
||||
else:
|
||||
return ''
|
|
@ -122,11 +122,17 @@ class AzureCli:
|
|||
"Azure CLI credentials not found. Please follow instructions below to login to the Azure CLI.")
|
||||
return None
|
||||
|
||||
def login(self, username, password):
|
||||
def login_account(self, username, password):
|
||||
|
||||
return self.invoke_az_cli_outproc(["login", "-u", username,
|
||||
"-p", password],
|
||||
"Error while trying to login to Azure. Try logging in with the interactive login mode (do not use the --credentials parameter).", suppress_output=True)
|
||||
"Error while trying to login to Azure. Make sure your account credentials are correct", suppress_output=True)
|
||||
|
||||
def login_sp(self, username, password, tenant):
|
||||
|
||||
return self.invoke_az_cli_outproc(["login", "--service-principal", "-u", username,
|
||||
"-p", password, "--tenant", tenant],
|
||||
"Error while trying to login to Azure. Make sure your service principal credentials are correct.", suppress_output=True)
|
||||
|
||||
def login_interactive(self):
|
||||
return self.invoke_az_cli_outproc(["login"],
|
||||
|
@ -187,6 +193,18 @@ class AzureCli:
|
|||
|
||||
return False
|
||||
|
||||
def get_resource_group_location(self, name):
|
||||
|
||||
self.output.status(f("Retrieving Resource Group '{name}' location..."))
|
||||
|
||||
with output_io_cls() as io:
|
||||
result = self.invoke_az_cli_outproc(["group", "show", "-n", name, "--query", "location", "--output", "tsv"],
|
||||
f("Could not retrieve Resource Group {name}'s location."), io)
|
||||
if result:
|
||||
return io.getvalue()
|
||||
else:
|
||||
return ''
|
||||
|
||||
def create_resource_group(self, name, location):
|
||||
self.output.status(
|
||||
f("Creating Resource Group '{name}' at '{location}'..."))
|
||||
|
|
|
@ -1,43 +1,47 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Console script for iotedgedev."""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import click
|
||||
import sys
|
||||
import os
|
||||
import hashlib
|
||||
import os
|
||||
import sys
|
||||
|
||||
import click
|
||||
from fstrings import f
|
||||
|
||||
from .azurecli import AzureCli
|
||||
from .dockercls import Docker
|
||||
from .envvars import EnvVars
|
||||
from .iothub import IoTHub
|
||||
from .modules import Modules
|
||||
from .output import Output
|
||||
from .runtime import Runtime
|
||||
from .solution import Solution
|
||||
from .utility import Utility
|
||||
from .envvars import EnvVars
|
||||
from .output import Output
|
||||
from .iothub import IoTHub
|
||||
from .azurecli import AzureCli
|
||||
|
||||
|
||||
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
|
||||
|
||||
output = Output()
|
||||
envvars = EnvVars(output)
|
||||
envvars.load()
|
||||
|
||||
azure_cli = AzureCli(output, envvars)
|
||||
default_subscriptionId = None
|
||||
azure_cli_processing_complete = False
|
||||
|
||||
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
|
||||
|
||||
|
||||
@click.group(context_settings=CONTEXT_SETTINGS, invoke_without_command=True)
|
||||
@click.version_option()
|
||||
@click.option(
|
||||
'--set-config',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Expands Environment Variables in *.template.json and copies to /.config.")
|
||||
@click.option('--set-config',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Expands Environment Variables in *.template.json and copies to /.config.")
|
||||
def main(set_config, az_cli=None):
|
||||
global azure_cli
|
||||
|
||||
ctx = click.get_current_context()
|
||||
if(az_cli):
|
||||
azure_cli = az_cli
|
||||
|
||||
|
@ -45,22 +49,23 @@ def main(set_config, az_cli=None):
|
|||
utility = Utility(envvars, output)
|
||||
utility.set_config()
|
||||
else:
|
||||
ctx = click.get_current_context()
|
||||
if ctx.invoked_subcommand is None:
|
||||
click.echo(ctx.get_help())
|
||||
sys.exit()
|
||||
|
||||
|
||||
@click.command(context_settings=CONTEXT_SETTINGS, help="Manage IoT Edge Solutions")
|
||||
@click.option(
|
||||
'--create',
|
||||
default=".",
|
||||
required=False,
|
||||
help="Creates a new Azure IoT Edge Solution. Use `--create .` to create in current folder. Use `--create TEXT` to create in a subfolder.")
|
||||
def solution(create):
|
||||
@click.option('--create',
|
||||
default=".",
|
||||
required=False,
|
||||
help="Creates a new Azure IoT Edge Solution. Use `--create .` to create in current folder. Use `--create TEXT` to create in a subfolder.")
|
||||
@click.argument("name", required=False)
|
||||
def solution(create, name):
|
||||
|
||||
if create:
|
||||
sol = Solution(output)
|
||||
sol = Solution(output)
|
||||
if name:
|
||||
sol.create(name)
|
||||
elif create:
|
||||
sol.create(create)
|
||||
|
||||
|
||||
|
@ -68,13 +73,14 @@ def solution(create):
|
|||
@click.pass_context
|
||||
def init(ctx):
|
||||
|
||||
utility = Utility(envvars, output, envvars_check=False)
|
||||
utility = Utility(envvars, output)
|
||||
|
||||
if len(os.listdir(os.getcwd())) == 0:
|
||||
solcmd = "iotedgedev solution --create ."
|
||||
solcmd = "iotedgedev solution ."
|
||||
output.header(solcmd)
|
||||
utility.call_proc(solcmd.split())
|
||||
|
||||
azsetupcmd = "iotedgedev azure --setup --update-dotenv"
|
||||
azsetupcmd = "iotedgedev azure --update-dotenv"
|
||||
output.header(azsetupcmd)
|
||||
utility.call_proc(azsetupcmd.split())
|
||||
|
||||
|
@ -86,34 +92,71 @@ def init(ctx):
|
|||
def e2e(ctx):
|
||||
|
||||
ctx.invoke(init)
|
||||
envvars.load(force=True)
|
||||
ctx.invoke(build)
|
||||
ctx.invoke(deploy)
|
||||
ctx.invoke(start)
|
||||
ctx.invoke(monitor)
|
||||
|
||||
utility = Utility(envvars, output, envvars_check=False)
|
||||
|
||||
buildcmd = "iotedgedev modules --build --deploy"
|
||||
output.header(buildcmd)
|
||||
utility.call_proc(buildcmd.split())
|
||||
runtimecmd = "iotedgedev runtime --setup --start"
|
||||
output.header(runtimecmd)
|
||||
utility.call_proc(runtimecmd.split())
|
||||
iothubcmd = "iotedgedev iothub --monitor-events"
|
||||
output.header(iothubcmd)
|
||||
utility.call_proc(iothubcmd.split())
|
||||
@click.command(context_settings=CONTEXT_SETTINGS, help="Builds all Modules in IoT Edge Solution.")
|
||||
@click.option('--deploy',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Deploys modules to Edge device using deployment.json in the /.config directory.")
|
||||
@click.pass_context
|
||||
def build(ctx, deploy):
|
||||
ctx.invoke(modules, build=True, deploy=deploy)
|
||||
|
||||
# Had to use call_proc, because @click.invoke doesn't honor prompts
|
||||
|
||||
@click.command(context_settings=CONTEXT_SETTINGS, help="Deploys Solution to IoT Edge Device.")
|
||||
@click.pass_context
|
||||
def deploy(ctx):
|
||||
ctx.invoke(modules, deploy=True)
|
||||
|
||||
|
||||
@click.command(context_settings=CONTEXT_SETTINGS, help="Starts the IoT Edge Runtime.")
|
||||
@click.pass_context
|
||||
def start(ctx):
|
||||
ctx.invoke(runtime, setup=True, start=True)
|
||||
|
||||
|
||||
@click.command(context_settings=CONTEXT_SETTINGS, help="Restarts the IoT Edge Runtime.")
|
||||
@click.pass_context
|
||||
def restart(ctx):
|
||||
ctx.invoke(runtime, restart=True)
|
||||
|
||||
|
||||
@click.command(context_settings=CONTEXT_SETTINGS, help="Stops the IoT Edge Runtime.")
|
||||
@click.pass_context
|
||||
def stop(ctx):
|
||||
ctx.invoke(runtime, stop=True)
|
||||
|
||||
|
||||
@click.command(context_settings=CONTEXT_SETTINGS, help="Monitors Messages from IoT Edge to IoT Hub.")
|
||||
@click.option('--timeout',
|
||||
required=False,
|
||||
help="Number of milliseconds to monitor for events.")
|
||||
@click.pass_context
|
||||
def monitor(ctx, timeout):
|
||||
ctx.invoke(iothub, monitor_events=True, timeout=timeout)
|
||||
|
||||
|
||||
@click.command(context_settings=CONTEXT_SETTINGS, help="Monitor IoT Hub Events")
|
||||
@click.option(
|
||||
'--monitor-events',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Displays events that are sent from IoT Hub device to IoT Hub.")
|
||||
def iothub(monitor_events):
|
||||
@click.option('--monitor-events',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Displays events that are sent from IoT Hub device to IoT Hub.")
|
||||
@click.option('--timeout',
|
||||
required=False,
|
||||
help="Number of milliseconds to monitor for events.")
|
||||
def iothub(monitor_events, timeout):
|
||||
if monitor_events:
|
||||
utility = Utility(envvars, output)
|
||||
ih = IoTHub(envvars, output, utility)
|
||||
ih.monitor_events()
|
||||
ih = IoTHub(envvars, utility, output)
|
||||
ih.monitor_events(timeout)
|
||||
|
||||
|
||||
def validate_option(ctx, param, value):
|
||||
|
@ -122,15 +165,20 @@ def validate_option(ctx, param, value):
|
|||
|
||||
if param.name == "credentials":
|
||||
if value and value[0] and value[1]:
|
||||
output.param("CREDENTIALS", value, "Setting Credentials...",
|
||||
azure_cli_processing_complete)
|
||||
output.param("CREDENTIALS", value, "Setting Credentials...", azure_cli_processing_complete)
|
||||
|
||||
if not azure_cli.login(*value):
|
||||
if not azure_cli.login_account(*value):
|
||||
sys.exit()
|
||||
|
||||
if param.name == "service_principal":
|
||||
if value and value[0] and value[1] and value[2]:
|
||||
output.param("SERVICE PRINCIPAL", value, "Setting Credentials...", azure_cli_processing_complete)
|
||||
|
||||
if not azure_cli.login_sp(*value):
|
||||
sys.exit()
|
||||
|
||||
if param.name == "subscription":
|
||||
output.param("SUBSCRIPTION", value, f(
|
||||
"Setting Subscription to '{value}'..."), azure_cli_processing_complete)
|
||||
output.param("SUBSCRIPTION", value, f("Setting Subscription to '{value}'..."), azure_cli_processing_complete)
|
||||
|
||||
# first verify that we have an existing auth token in cache, otherwise login using interactive
|
||||
if not default_subscriptionId:
|
||||
|
@ -140,35 +188,31 @@ def validate_option(ctx, param, value):
|
|||
|
||||
if default_subscriptionId != value:
|
||||
if not azure_cli.set_subscription(value):
|
||||
raise click.BadParameter(
|
||||
f('Please verify that your subscription Id or Name is correct'))
|
||||
|
||||
if param.name == "resource_group_location":
|
||||
|
||||
output.param("RESOURCE GROUP LOCATION", value, f(
|
||||
"Setting Resource Group Location to '{value}'..."), azure_cli_processing_complete)
|
||||
|
||||
envvars.RESOURCE_GROUP_LOCATION = value
|
||||
raise click.BadParameter(f('Please verify that your subscription Id or Name is correct'))
|
||||
|
||||
if param.name == "resource_group_name":
|
||||
output.param("RESOURCE GROUP NAME", value, f(
|
||||
"Setting Resource Group Name to '{value}'..."), azure_cli_processing_complete)
|
||||
output.param("RESOURCE GROUP NAME", value, f("Setting Resource Group Name to '{value}'..."), azure_cli_processing_complete)
|
||||
|
||||
envvars.RESOURCE_GROUP_NAME = value
|
||||
if not azure_cli.resource_group_exists(value):
|
||||
if not azure_cli.create_resource_group(value, envvars.RESOURCE_GROUP_LOCATION):
|
||||
raise click.BadParameter(
|
||||
f('Could not find Resource Group {value}'))
|
||||
raise click.BadParameter(f('Could not find Resource Group {value}'))
|
||||
else:
|
||||
# resource group exist, so don't ask for location
|
||||
envvars.RESOURCE_GROUP_LOCATION = azure_cli.get_resource_group_location(value)
|
||||
|
||||
if param.name == "resource_group_location":
|
||||
output.param("RESOURCE GROUP LOCATION", value, f("Setting Resource Group Location to '{value}'..."), azure_cli_processing_complete)
|
||||
|
||||
envvars.RESOURCE_GROUP_LOCATION = value
|
||||
|
||||
if param.name == "iothub_sku":
|
||||
|
||||
output.param("IOT HUB SKU", value, f(
|
||||
"Setting IoT Hub SKU to '{value}'..."), azure_cli_processing_complete)
|
||||
output.param("IOT HUB SKU", value, f("Setting IoT Hub SKU to '{value}'..."), azure_cli_processing_complete)
|
||||
envvars.IOTHUB_SKU = value
|
||||
|
||||
if param.name == "iothub_name":
|
||||
output.param("IOT HUB", value, f(
|
||||
"Setting IoT Hub to '{value}'..."), azure_cli_processing_complete)
|
||||
output.param("IOT HUB", value, f("Setting IoT Hub to '{value}'..."), azure_cli_processing_complete)
|
||||
envvars.IOTHUB_NAME = value
|
||||
if not azure_cli.extension_exists("azure-cli-iot-ext"):
|
||||
azure_cli.add_extension("azure-cli-iot-ext")
|
||||
|
@ -179,7 +223,7 @@ def validate_option(ctx, param, value):
|
|||
if envvars.IOTHUB_SKU == "F1":
|
||||
free_iot_name, free_iot_rg = azure_cli.get_free_iothub()
|
||||
if free_iot_name:
|
||||
output.info("You already have a Free IoT Hub SKU in your subscription, so you must either use that existing IoT Hub or create a new S1 IoT Hub. Enter (F) to use the existing Free IoT Hub or enter (S) to create a new S1 IoT Hub")
|
||||
output.info("You already have a Free IoT Hub SKU in your subscription, so you must either use that existing IoT Hub or create a new S1 IoT Hub. Enter (F) to use the existing Free IoT Hub or enter (S) to create a new S1 IoT Hub:")
|
||||
user_response = sys.stdin.readline().strip().upper()
|
||||
if user_response == "S":
|
||||
envvars.IOTHUB_SKU = "S1"
|
||||
|
@ -190,30 +234,23 @@ def validate_option(ctx, param, value):
|
|||
else:
|
||||
sys.exit()
|
||||
if not azure_cli.create_iothub(value, envvars.RESOURCE_GROUP_NAME, envvars.IOTHUB_SKU):
|
||||
raise click.BadParameter(
|
||||
f('Could not create IoT Hub {value} in {envvars.RESOURCE_GROUP_NAME}'))
|
||||
raise click.BadParameter(f('Could not create IoT Hub {value} in {envvars.RESOURCE_GROUP_NAME}'))
|
||||
|
||||
if param.name == "edge_device_id":
|
||||
output.param("EDGE DEVICE", value, f(
|
||||
"Setting Edge Device to '{value}'..."), azure_cli_processing_complete)
|
||||
output.param("EDGE DEVICE", value, f("Setting Edge Device to '{value}'..."), azure_cli_processing_complete)
|
||||
|
||||
envvars.EDGE_DEVICE_ID = value
|
||||
if not azure_cli.edge_device_exists(value, envvars.IOTHUB_NAME, envvars.RESOURCE_GROUP_NAME):
|
||||
if not azure_cli.create_edge_device(value, envvars.IOTHUB_NAME, envvars.RESOURCE_GROUP_NAME):
|
||||
raise click.BadParameter(
|
||||
f('Could not create IoT Edge Device {value} in {envvars.IOTHUB_NAME} in {envvars.RESOURCE_GROUP_NAME}'))
|
||||
raise click.BadParameter(f('Could not create IoT Edge Device {value} in {envvars.IOTHUB_NAME} in {envvars.RESOURCE_GROUP_NAME}'))
|
||||
|
||||
output.header("CONNECTION STRINGS")
|
||||
envvars.IOTHUB_CONNECTION_STRING = azure_cli.get_iothub_connection_string(
|
||||
envvars.IOTHUB_NAME, envvars.RESOURCE_GROUP_NAME)
|
||||
envvars.DEVICE_CONNECTION_STRING = azure_cli.get_device_connection_string(
|
||||
envvars.EDGE_DEVICE_ID, envvars.IOTHUB_NAME, envvars.RESOURCE_GROUP_NAME)
|
||||
envvars.IOTHUB_CONNECTION_STRING = azure_cli.get_iothub_connection_string(envvars.IOTHUB_NAME, envvars.RESOURCE_GROUP_NAME)
|
||||
envvars.DEVICE_CONNECTION_STRING = azure_cli.get_device_connection_string(envvars.EDGE_DEVICE_ID, envvars.IOTHUB_NAME, envvars.RESOURCE_GROUP_NAME)
|
||||
|
||||
if envvars.IOTHUB_CONNECTION_STRING and envvars.DEVICE_CONNECTION_STRING:
|
||||
output.info(
|
||||
f("IOTHUB_CONNECTION_STRING=\"{envvars.IOTHUB_CONNECTION_STRING}\""))
|
||||
output.info(
|
||||
f("DEVICE_CONNECTION_STRING=\"{envvars.DEVICE_CONNECTION_STRING}\""))
|
||||
output.info(f("IOTHUB_CONNECTION_STRING=\"{envvars.IOTHUB_CONNECTION_STRING}\""))
|
||||
output.info(f("DEVICE_CONNECTION_STRING=\"{envvars.DEVICE_CONNECTION_STRING}\""))
|
||||
|
||||
azure_cli_processing_complete = True
|
||||
|
||||
|
@ -236,8 +273,7 @@ def list_iot_hubs_and_set_default():
|
|||
if first_iothub:
|
||||
return first_iothub
|
||||
else:
|
||||
subscription_rg_hash = hashlib.sha1(
|
||||
(default_subscriptionId + envvars.RESOURCE_GROUP_NAME).encode('utf-8')).hexdigest()[:6]
|
||||
subscription_rg_hash = hashlib.sha1((default_subscriptionId + envvars.RESOURCE_GROUP_NAME).encode('utf-8')).hexdigest()[:6]
|
||||
return "iotedgedev-iothub-" + subscription_rg_hash
|
||||
|
||||
|
||||
|
@ -264,78 +300,93 @@ def list_subscriptions_and_set_default():
|
|||
return default_subscriptionId
|
||||
|
||||
|
||||
def header_and_default(header, default):
|
||||
output.header(header)
|
||||
return default
|
||||
|
||||
|
||||
@click.command(context_settings=CONTEXT_SETTINGS, help="Manage Azure Resources")
|
||||
@click.option(
|
||||
'--setup',
|
||||
required=True,
|
||||
is_flag=True,
|
||||
help="Reads the required Azure resources configuration from your subscription. Creates new or uses existing Azure resources")
|
||||
@click.option(
|
||||
'--credentials',
|
||||
required=False,
|
||||
hide_input=True,
|
||||
default=(None, None),
|
||||
type=(str, str),
|
||||
callback=validate_option,
|
||||
help="The credentials (username password) to use to login to Azure. If --credentials not specified, you will login in the interactive mode.")
|
||||
@click.option(
|
||||
'--subscription',
|
||||
default=lambda: list_subscriptions_and_set_default(),
|
||||
required=True,
|
||||
callback=validate_option,
|
||||
prompt="Enter the first 3 characters of the Azure subscription name or id to use. Hit Enter to use the default subscription.",
|
||||
help="The Azure subscription name or id to use.")
|
||||
@click.option(
|
||||
'--resource-group-location',
|
||||
required=False,
|
||||
default='westus',
|
||||
type=click.Choice(['australiaeast', 'australiasoutheast', 'brazilsouth', 'canadacentral', 'canadaeast', 'centralindia', 'centralus', 'eastasia', 'eastus', 'eastus2',
|
||||
'japanwest', 'japaneast', 'northeurope', 'northcentralus', 'southindia', 'uksouth', 'ukwest', 'westus', 'westeurope', 'southcentralus', 'westcentralus', 'westus2']),
|
||||
callback=validate_option,
|
||||
help="The location of the new Resource Group. If --resource-group-location not specified, the default will be West US.")
|
||||
@click.option(
|
||||
'--resource-group-name',
|
||||
required=True,
|
||||
default=lambda: list_resource_groups_and_set_default(),
|
||||
type=str,
|
||||
callback=validate_option,
|
||||
prompt="Enter the name of the Resource Group to use or create. Creates a new Resource Group if not found",
|
||||
help="The name of the Resource Group to use or create. Creates a new Resource Group if not found.")
|
||||
@click.option(
|
||||
'--iothub-sku',
|
||||
required=False,
|
||||
default='F1',
|
||||
type=click.Choice(['F1', 'S1', 'S2', 'S3']),
|
||||
callback=validate_option,
|
||||
help="The SKU of the new IoT Hub. If --iothub-sku not specified, the default will be F1 (free).")
|
||||
@click.option(
|
||||
'--iothub-name',
|
||||
required=True,
|
||||
default=lambda: list_iot_hubs_and_set_default(),
|
||||
type=str,
|
||||
callback=validate_option,
|
||||
prompt='Enter the IoT Hub name to be used. Creates a new IoT Hub if not found',
|
||||
help='The IoT Hub name to be used. Creates a new IoT Hub if not found.')
|
||||
@click.option(
|
||||
'--edge-device-id',
|
||||
required=True,
|
||||
default=lambda: list_edge_devices_and_set_default(),
|
||||
type=str,
|
||||
callback=validate_option,
|
||||
prompt='Enter the IoT Edge Device Id to be used. Creates a new Edge Device if not found',
|
||||
help='The IoT Edge Device Id to be used. Creates a new Edge Device if not found.')
|
||||
@click.option(
|
||||
'--update-dotenv',
|
||||
required=True,
|
||||
default=False,
|
||||
is_flag=True,
|
||||
prompt='Update the current .env with these connection strings?',
|
||||
help='If set, the current .env will be updated with the corresponding connection strings.')
|
||||
@click.option('--setup',
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Retrieves or creates the required Azure Resources.")
|
||||
@click.option('--credentials',
|
||||
envvar=envvars.get_envvar_key_if_val("CREDENTIALS"),
|
||||
required=False,
|
||||
hide_input=True,
|
||||
default=(None, None),
|
||||
type=(str, str),
|
||||
callback=validate_option,
|
||||
help="Enter Azure Credentials (username password).")
|
||||
@click.option('--service-principal',
|
||||
envvar=envvars.get_envvar_key_if_val("SERVICE_PRINCIPAL"),
|
||||
required=False,
|
||||
hide_input=True,
|
||||
default=(None, None, None),
|
||||
type=(str, str, str),
|
||||
callback=validate_option,
|
||||
help="Enter Azure Service Principal Credentials (username password tenant).")
|
||||
@click.option('--subscription',
|
||||
envvar=envvars.get_envvar_key_if_val("SUBSCRIPTION_ID"),
|
||||
default=lambda: list_subscriptions_and_set_default(),
|
||||
required=True,
|
||||
callback=validate_option,
|
||||
prompt="Select an Azure Subscription Name or Id:",
|
||||
help="The Azure Subscription Name or Id.")
|
||||
@click.option('--resource-group-name',
|
||||
envvar=envvars.get_envvar_key_if_val("RESOURCE_GROUP_NAME"),
|
||||
required=True,
|
||||
default=lambda: list_resource_groups_and_set_default(),
|
||||
type=str,
|
||||
callback=validate_option,
|
||||
prompt="Enter Resource Group Name (Creates a new Resource Group if not found):",
|
||||
help="The Resource Group Name (Creates a new Resource Group if not found).")
|
||||
@click.option('--resource-group-location',
|
||||
envvar=envvars.get_envvar_key_if_val("RESOURCE_GROUP_LOCATION"),
|
||||
required=True,
|
||||
default=lambda: header_and_default('RESOURCE GROUP LOCATION', envvars.RESOURCE_GROUP_LOCATION),
|
||||
type=click.Choice(['australiaeast', 'australiasoutheast', 'brazilsouth', 'canadacentral', 'canadaeast', 'centralindia', 'centralus', 'eastasia', 'eastus', 'eastus2',
|
||||
'japanwest', 'japaneast', 'northeurope', 'northcentralus', 'southindia', 'uksouth', 'ukwest', 'westus', 'westeurope', 'southcentralus', 'westcentralus', 'westus2']),
|
||||
callback=validate_option,
|
||||
prompt="Enter a Resource Group Location:",
|
||||
help="The Resource Group Location.")
|
||||
@click.option('--iothub-sku',
|
||||
envvar=envvars.get_envvar_key_if_val("IOTHUB_SKU"),
|
||||
required=True,
|
||||
default=lambda: header_and_default('IOTHUB SKU', 'F1'),
|
||||
type=click.Choice(['F1', 'S1', 'S2', 'S3']),
|
||||
callback=validate_option,
|
||||
prompt="Enter IoT Hub SKU (F1|S1|S3|S3):",
|
||||
help="The IoT Hub SKU.")
|
||||
@click.option('--iothub-name',
|
||||
envvar=envvars.get_envvar_key_if_val("IOTHUB_NAME"),
|
||||
required=True,
|
||||
default=lambda: list_iot_hubs_and_set_default(),
|
||||
type=str,
|
||||
callback=validate_option,
|
||||
prompt='Enter the IoT Hub Name (Creates a new IoT Hub if not found):',
|
||||
help='The IoT Hub Name (Creates a new IoT Hub if not found).')
|
||||
@click.option('--edge-device-id',
|
||||
envvar=envvars.get_envvar_key_if_val("EDGE_DEVICE_ID"),
|
||||
required=True,
|
||||
default=lambda: list_edge_devices_and_set_default(),
|
||||
type=str,
|
||||
callback=validate_option,
|
||||
prompt='Enter the IoT Edge Device Id (Creates a new Edge Device if not found):',
|
||||
help='The IoT Edge Device Id (Creates a new Edge Device if not found).')
|
||||
@click.option('--update-dotenv',
|
||||
envvar=envvars.get_envvar_key_if_val("UPDATE_DOTENV"),
|
||||
required=True,
|
||||
default=False,
|
||||
is_flag=True,
|
||||
prompt='Update the .env file with connection strings?',
|
||||
help='If True, the current .env will be updated with the IoT Hub and Device connection strings.')
|
||||
def azure(setup,
|
||||
credentials,
|
||||
service_principal,
|
||||
subscription,
|
||||
resource_group_location,
|
||||
resource_group_name,
|
||||
resource_group_location,
|
||||
iothub_sku,
|
||||
iothub_name,
|
||||
edge_device_id,
|
||||
|
@ -343,27 +394,22 @@ def azure(setup,
|
|||
|
||||
if update_dotenv:
|
||||
if envvars.backup_dotenv():
|
||||
|
||||
envvars.save_envvar("IOTHUB_CONNECTION_STRING",
|
||||
envvars.IOTHUB_CONNECTION_STRING)
|
||||
envvars.save_envvar("DEVICE_CONNECTION_STRING",
|
||||
envvars.DEVICE_CONNECTION_STRING)
|
||||
envvars.save_envvar("IOTHUB_CONNECTION_STRING", envvars.IOTHUB_CONNECTION_STRING)
|
||||
envvars.save_envvar("DEVICE_CONNECTION_STRING", envvars.DEVICE_CONNECTION_STRING)
|
||||
output.info("Updated current .env file")
|
||||
|
||||
|
||||
@click.command(context_settings=CONTEXT_SETTINGS, help="Build and Deploy IoT Edge Modules")
|
||||
@click.option(
|
||||
'--build',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Builds and pushes modules specified in ACTIVE_MODULES Environment Variable to specified container registry.")
|
||||
@click.option(
|
||||
'--deploy',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Deploys modules to Edge device using deployment.json in the /.config directory.")
|
||||
@click.option('--build',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Builds and pushes modules specified in ACTIVE_MODULES Environment Variable to specified container registry.")
|
||||
@click.option('--deploy',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Deploys modules to Edge device using deployment.json in the /.config directory.")
|
||||
def modules(build, deploy):
|
||||
utility = Utility(envvars, output)
|
||||
dock = Docker(envvars, utility, output)
|
||||
|
@ -377,36 +423,31 @@ def modules(build, deploy):
|
|||
|
||||
|
||||
@click.command(context_settings=CONTEXT_SETTINGS, help="Manage IoT Edge Runtime")
|
||||
@click.option(
|
||||
'--setup',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Setup Edge Runtime using runtime.json in /.config directory.")
|
||||
@click.option(
|
||||
'--start',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Starts Edge Runtime. Calls iotedgectl start.")
|
||||
@click.option(
|
||||
'--stop',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Stops Edge Runtime. Calls iotedgectl stop.")
|
||||
@click.option(
|
||||
'--restart',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Restarts Edge Runtime. Calls iotedgectl stop, removes module containers and images, calls iotedgectl setup (with --config-file) and then calls iotedgectl start.")
|
||||
@click.option(
|
||||
'--status',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Edge Runtime Status. Calls iotedgectl status.")
|
||||
@click.option('--setup',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Setup Edge Runtime using runtime.json in /.config directory.")
|
||||
@click.option('--start',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Starts Edge Runtime. Calls iotedgectl start.")
|
||||
@click.option('--stop',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Stops Edge Runtime. Calls iotedgectl stop.")
|
||||
@click.option('--restart',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Restarts Edge Runtime. Calls iotedgectl stop, removes module containers and images, calls iotedgectl setup (with --config-file) and then calls iotedgectl start.")
|
||||
@click.option('--status',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Edge Runtime Status. Calls iotedgectl status.")
|
||||
def runtime(setup, start, stop, restart, status):
|
||||
|
||||
utility = Utility(envvars, output)
|
||||
|
@ -430,59 +471,51 @@ def runtime(setup, start, stop, restart, status):
|
|||
|
||||
|
||||
@click.command(context_settings=CONTEXT_SETTINGS, help="Docker Utilities")
|
||||
@click.option(
|
||||
'--setup-registry',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Pulls Edge Runtime from Docker Hub and pushes to your specified container registry. Also, updates config files to use CONTAINER_REGISTRY_* instead of the Microsoft Docker hub. See CONTAINER_REGISTRY Environment Variables.")
|
||||
@click.option(
|
||||
'--clean',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Removes all the Docker containers and Images.")
|
||||
@click.option(
|
||||
'--remove-modules',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Removes only the edge modules Docker containers and images specified in ACTIVE_MODULES, not edgeAgent or edgeHub.")
|
||||
@click.option(
|
||||
'--remove-containers',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Removes all the Docker containers")
|
||||
@click.option('--setup-registry',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Pulls Edge Runtime from Docker Hub and pushes to your specified container registry. Also, updates config files to use CONTAINER_REGISTRY_* instead of the Microsoft Docker hub. See CONTAINER_REGISTRY Environment Variables.")
|
||||
@click.option('--clean',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Removes all the Docker containers and Images.")
|
||||
@click.option('--remove-modules',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Removes only the edge modules Docker containers and images specified in ACTIVE_MODULES, not edgeAgent or edgeHub.")
|
||||
@click.option('--remove-containers',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Removes all the Docker containers")
|
||||
@click.option('--remove-images', default=False, required=False,
|
||||
is_flag=True, help="Removes all the Docker images.")
|
||||
@click.option(
|
||||
'--logs',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Opens a new terminal window for edgeAgent, edgeHub and each edge module and saves to LOGS_PATH. You can configure the terminal command with LOGS_CMD.")
|
||||
@click.option(
|
||||
'--show-logs',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Opens a new terminal window for edgeAgent, edgeHub and each edge module. You can configure the terminal command with LOGS_CMD.")
|
||||
@click.option(
|
||||
'--save-logs',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Saves edgeAgent, edgeHub and each edge module logs to LOGS_PATH.")
|
||||
def docker(
|
||||
setup_registry,
|
||||
clean,
|
||||
remove_modules,
|
||||
remove_containers,
|
||||
remove_images,
|
||||
logs,
|
||||
show_logs,
|
||||
save_logs):
|
||||
@click.option('--logs',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Opens a new terminal window for edgeAgent, edgeHub and each edge module and saves to LOGS_PATH. You can configure the terminal command with LOGS_CMD.")
|
||||
@click.option('--show-logs',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Opens a new terminal window for edgeAgent, edgeHub and each edge module. You can configure the terminal command with LOGS_CMD.")
|
||||
@click.option('--save-logs',
|
||||
default=False,
|
||||
required=False,
|
||||
is_flag=True,
|
||||
help="Saves edgeAgent, edgeHub and each edge module logs to LOGS_PATH.")
|
||||
def docker(setup_registry,
|
||||
clean,
|
||||
remove_modules,
|
||||
remove_containers,
|
||||
remove_images,
|
||||
logs,
|
||||
show_logs,
|
||||
save_logs):
|
||||
|
||||
utility = Utility(envvars, output)
|
||||
dock = Docker(envvars, utility, output)
|
||||
|
@ -511,6 +544,9 @@ def docker(
|
|||
dock.handle_logs_cmd(show_logs, save_logs)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
main.add_command(runtime)
|
||||
main.add_command(modules)
|
||||
main.add_command(docker)
|
||||
|
@ -519,7 +555,9 @@ main.add_command(iothub)
|
|||
main.add_command(azure)
|
||||
main.add_command(init)
|
||||
main.add_command(e2e)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main.add_command(build)
|
||||
main.add_command(deploy)
|
||||
main.add_command(start)
|
||||
main.add_command(restart)
|
||||
main.add_command(stop)
|
||||
main.add_command(monitor)
|
||||
|
|
|
@ -3,13 +3,12 @@ from enum import Enum
|
|||
import os
|
||||
import zipfile
|
||||
from .moduletype import ModuleType
|
||||
|
||||
import sys
|
||||
|
||||
class Docker:
|
||||
|
||||
def __init__(self, envvars, utility, output):
|
||||
self.envvars = envvars
|
||||
self.envvars.check()
|
||||
self.utility = utility
|
||||
self.utility.set_config()
|
||||
self.output = output
|
||||
|
@ -31,7 +30,8 @@ class Docker:
|
|||
if "localhost" in self.envvars.CONTAINER_REGISTRY_SERVER:
|
||||
self.init_local_registry()
|
||||
|
||||
self.login_registry()
|
||||
#removing call to login because I don't think it is actually needed anymore. It could have been left over from before we started using auth_config in the push calls.
|
||||
#self.login_registry()
|
||||
self.output.line()
|
||||
|
||||
def init_local_registry(self):
|
||||
|
|
|
@ -1,21 +1,32 @@
|
|||
from dotenv import load_dotenv, set_key
|
||||
import os
|
||||
import platform
|
||||
import socket
|
||||
import sys
|
||||
from shutil import copyfile
|
||||
|
||||
from dotenv import load_dotenv, set_key
|
||||
from fstrings import f
|
||||
from .connectionstring import IoTHubConnectionString, DeviceConnectionString
|
||||
|
||||
from .args import Args
|
||||
from .connectionstring import DeviceConnectionString, IoTHubConnectionString
|
||||
|
||||
|
||||
class EnvVars:
|
||||
def __init__(self, output):
|
||||
self.output = output
|
||||
self.checked = False
|
||||
self.loaded = False
|
||||
self.args = Args()
|
||||
self.current_command = self.args.get_current_command()
|
||||
self.terse_commands = ['azure', 'solution']
|
||||
self.bypass_dotenv_load_commands = ['init', 'e2e']
|
||||
|
||||
# for some commands we don't want verbose dotenv load output
|
||||
self.verbose = self.current_command not in self.terse_commands
|
||||
|
||||
def backup_dotenv(self):
|
||||
dotenv_file = self.get_dotenv_file()
|
||||
dotenv_path = os.path.join(os.getcwd(), dotenv_file)
|
||||
dotenv_backup_path= dotenv_path+".backup"
|
||||
dotenv_backup_path = dotenv_path + ".backup"
|
||||
try:
|
||||
copyfile(dotenv_path, dotenv_backup_path)
|
||||
self.output.info(f("Successfully backed up {dotenv_path} to {dotenv_backup_path}"))
|
||||
|
@ -24,7 +35,7 @@ class EnvVars:
|
|||
self.output.error(f("Could not backup {dotenv_path} to {dotenv_backup_path}"))
|
||||
self.output.error(str(e))
|
||||
return False
|
||||
|
||||
|
||||
def load_dotenv(self):
|
||||
dotenv_file = self.get_dotenv_file()
|
||||
dotenv_path = os.path.join(os.getcwd(), dotenv_file)
|
||||
|
@ -32,14 +43,13 @@ class EnvVars:
|
|||
try:
|
||||
if os.path.exists(dotenv_path):
|
||||
load_dotenv(dotenv_path)
|
||||
self.output.info(
|
||||
"Environment Variables loaded from: {0} ({1})".format(dotenv_file, dotenv_path))
|
||||
if self.verbose:
|
||||
self.output.info("Environment Variables loaded from: {0} ({1})".format(dotenv_file, dotenv_path))
|
||||
else:
|
||||
self.output.info(
|
||||
"{0} file not found on disk. Without a file on disk, you must specify all Environment Variables at the system level. ({1})".format(dotenv_file, dotenv_path))
|
||||
if self.verbose:
|
||||
self.output.info("{0} file not found on disk. Without a file on disk, you must specify all Environment Variables at the system level. ({1})".format(dotenv_file, dotenv_path))
|
||||
except Exception as ex:
|
||||
self.output.error("Error while trying to load .env file: {0}. {1}".format(
|
||||
dotenv_path, str(ex)))
|
||||
self.output.error("Error while trying to load .env file: {0}. {1}".format(dotenv_path, str(ex)))
|
||||
|
||||
def get_dotenv_file(self):
|
||||
default_dotenv_file = ".env"
|
||||
|
@ -47,82 +57,86 @@ class EnvVars:
|
|||
if not "DOTENV_FILE" in os.environ:
|
||||
return default_dotenv_file
|
||||
else:
|
||||
dotenv_file_from_environ = os.environ["DOTENV_FILE"].strip(
|
||||
"\"").strip("'")
|
||||
dotenv_file_from_environ = os.environ["DOTENV_FILE"].strip("\"").strip("'")
|
||||
if dotenv_file_from_environ:
|
||||
return dotenv_file_from_environ
|
||||
|
||||
return default_dotenv_file
|
||||
|
||||
def check(self):
|
||||
if not self.checked:
|
||||
|
||||
self.output.header("ENVIRONMENT VARIABLES")
|
||||
|
||||
def load(self, force=False):
|
||||
|
||||
# for some commands we don't want to load dotenv
|
||||
if self.current_command in self.bypass_dotenv_load_commands and not force:
|
||||
return
|
||||
|
||||
if not self.loaded or force:
|
||||
if self.verbose:
|
||||
self.output.header("ENVIRONMENT VARIABLES")
|
||||
|
||||
self.load_dotenv()
|
||||
|
||||
try:
|
||||
try:
|
||||
self.IOTHUB_CONNECTION_STRING = self.get_envvar(
|
||||
"IOTHUB_CONNECTION_STRING")
|
||||
self.IOTHUB_CONNECTION_INFO = IoTHubConnectionString(
|
||||
self.IOTHUB_CONNECTION_STRING)
|
||||
self.IOTHUB_CONNECTION_STRING = self.get_envvar("IOTHUB_CONNECTION_STRING")
|
||||
|
||||
if self.IOTHUB_CONNECTION_STRING:
|
||||
self.IOTHUB_CONNECTION_INFO = IoTHubConnectionString(self.IOTHUB_CONNECTION_STRING)
|
||||
|
||||
except Exception as ex:
|
||||
self.output.error(
|
||||
"Unable to parse IOTHUB_CONNECTION_STRING Environment Variable. Please ensure that you have the right connection string set.")
|
||||
self.output.error("Unable to parse IOTHUB_CONNECTION_STRING Environment Variable. Please ensure that you have the right connection string set.")
|
||||
self.output.error(str(ex))
|
||||
sys.exit(-1)
|
||||
|
||||
try:
|
||||
self.DEVICE_CONNECTION_STRING = self.get_envvar(
|
||||
"DEVICE_CONNECTION_STRING")
|
||||
self.DEVICE_CONNECTION_INFO = DeviceConnectionString(
|
||||
self.DEVICE_CONNECTION_STRING)
|
||||
self.DEVICE_CONNECTION_STRING = self.get_envvar("DEVICE_CONNECTION_STRING")
|
||||
|
||||
if self.DEVICE_CONNECTION_STRING:
|
||||
self.DEVICE_CONNECTION_INFO = DeviceConnectionString(self.DEVICE_CONNECTION_STRING)
|
||||
|
||||
except Exception as ex:
|
||||
self.output.error(
|
||||
"Unable to parse DEVICE_CONNECTION_STRING Environment Variable. Please ensure that you have the right connection string set.")
|
||||
self.output.error("Unable to parse DEVICE_CONNECTION_STRING Environment Variable. Please ensure that you have the right connection string set.")
|
||||
self.output.error(str(ex))
|
||||
sys.exit(-1)
|
||||
|
||||
self.RUNTIME_HOST_NAME = self.get_envvar("RUNTIME_HOST_NAME")
|
||||
self.RUNTIME_HOST_NAME = self.get_envvar("RUNTIME_HOST_NAME", default=".")
|
||||
if self.RUNTIME_HOST_NAME == ".":
|
||||
self.set_envvar("RUNTIME_HOST_NAME", socket.gethostname())
|
||||
|
||||
self.RUNTIME_HOME_DIR = self.get_envvar("RUNTIME_HOME_DIR")
|
||||
self.RUNTIME_HOME_DIR = self.get_envvar("RUNTIME_HOME_DIR", default=".")
|
||||
if self.RUNTIME_HOME_DIR == ".":
|
||||
self.set_envvar("RUNTIME_HOME_DIR",
|
||||
self.get_runtime_home_dir())
|
||||
self.set_envvar("RUNTIME_HOME_DIR", self.get_runtime_home_dir())
|
||||
|
||||
self.RUNTIME_CONFIG_DIR = self.get_envvar("RUNTIME_CONFIG_DIR")
|
||||
self.RUNTIME_CONFIG_DIR = self.get_envvar("RUNTIME_CONFIG_DIR", default=".")
|
||||
if self.RUNTIME_CONFIG_DIR == ".":
|
||||
self.set_envvar("RUNTIME_CONFIG_DIR",
|
||||
self.get_runtime_config_dir())
|
||||
self.set_envvar("RUNTIME_CONFIG_DIR", self.get_runtime_config_dir())
|
||||
|
||||
self.ACTIVE_MODULES = self.get_envvar("ACTIVE_MODULES")
|
||||
self.ACTIVE_MODULES = self.get_envvar("ACTIVE_MODULES")
|
||||
self.ACTIVE_DOCKER_ARCH = self.get_envvar("ACTIVE_DOCKER_ARCH")
|
||||
|
||||
self.CONTAINER_REGISTRY_SERVER = self.get_envvar(
|
||||
"CONTAINER_REGISTRY_SERVER", False)
|
||||
self.CONTAINER_REGISTRY_USERNAME = self.get_envvar(
|
||||
"CONTAINER_REGISTRY_USERNAME", False)
|
||||
self.CONTAINER_REGISTRY_PASSWORD = self.get_envvar(
|
||||
"CONTAINER_REGISTRY_PASSWORD", False)
|
||||
self.CONTAINER_TAG = self.get_envvar("CONTAINER_TAG", False)
|
||||
self.CONTAINER_REGISTRY_SERVER = self.get_envvar("CONTAINER_REGISTRY_SERVER")
|
||||
self.CONTAINER_REGISTRY_USERNAME = self.get_envvar("CONTAINER_REGISTRY_USERNAME")
|
||||
self.CONTAINER_REGISTRY_PASSWORD = self.get_envvar("CONTAINER_REGISTRY_PASSWORD")
|
||||
self.CONTAINER_TAG = self.get_envvar("CONTAINER_TAG")
|
||||
self.RUNTIME_TAG = self.get_envvar("RUNTIME_TAG")
|
||||
self.RUNTIME_VERBOSITY = self.get_envvar("RUNTIME_VERBOSITY")
|
||||
self.MODULES_CONFIG_FILE = self.get_envvar(
|
||||
"MODULES_CONFIG_FILE")
|
||||
self.RUNTIME_CONFIG_FILE = self.get_envvar(
|
||||
"RUNTIME_CONFIG_FILE")
|
||||
self.MODULES_CONFIG_FILE = self.get_envvar("MODULES_CONFIG_FILE")
|
||||
self.RUNTIME_CONFIG_FILE = self.get_envvar("RUNTIME_CONFIG_FILE")
|
||||
self.LOGS_PATH = self.get_envvar("LOGS_PATH")
|
||||
self.MODULES_PATH = self.get_envvar("MODULES_PATH")
|
||||
self.IOT_REST_API_VERSION = self.get_envvar(
|
||||
"IOT_REST_API_VERSION")
|
||||
self.IOT_REST_API_VERSION = self.get_envvar("IOT_REST_API_VERSION")
|
||||
self.DOTNET_VERBOSITY = self.get_envvar("DOTNET_VERBOSITY")
|
||||
self.DOTNET_EXE_DIR = self.get_envvar("DOTNET_EXE_DIR", False)
|
||||
self.DOTNET_EXE_DIR = self.get_envvar("DOTNET_EXE_DIR")
|
||||
self.LOGS_CMD = self.get_envvar("LOGS_CMD")
|
||||
self.SUBSCRIPTION_ID = self.get_envvar("SUBSCRIPTION_ID")
|
||||
self.RESOURCE_GROUP_NAME = self.get_envvar("RESOURCE_GROUP_NAME")
|
||||
self.RESOURCE_GROUP_LOCATION = self.get_envvar("RESOURCE_GROUP_LOCATION")
|
||||
self.IOTHUB_NAME = self.get_envvar("IOTHUB_NAME")
|
||||
self.IOTHUB_SKU = self.get_envvar("IOTHUB_SKU")
|
||||
self.EDGE_DEVICE_ID = self.get_envvar("EDGE_DEVICE_ID")
|
||||
self.CREDENTIALS = self.get_envvar("CREDENTIALS")
|
||||
self.UPDATE_DOTENV = self.get_envvar("UPDATE_DOTENV")
|
||||
|
||||
if "DOCKER_HOST" in os.environ:
|
||||
self.DOCKER_HOST = self.get_envvar("DOCKER_HOST", False)
|
||||
self.DOCKER_HOST = self.get_envvar("DOCKER_HOST")
|
||||
else:
|
||||
self.DOCKER_HOST = None
|
||||
except Exception as ex:
|
||||
|
@ -131,7 +145,7 @@ class EnvVars:
|
|||
self.output.error("Variable that caused exception: " + str(ex))
|
||||
sys.exit(-1)
|
||||
|
||||
self.checked = True
|
||||
self.loaded = True
|
||||
|
||||
def __getattribute__(self, name):
|
||||
try:
|
||||
|
@ -140,20 +154,31 @@ class EnvVars:
|
|||
if name in os.environ:
|
||||
return self.get_envvar(name)
|
||||
else:
|
||||
raise e
|
||||
raise e
|
||||
|
||||
def get_envvar(self, key, required=True):
|
||||
def get_envvar(self, key, required=False, default=None):
|
||||
val = ""
|
||||
|
||||
|
||||
if key in os.environ:
|
||||
val = os.environ[key].strip()
|
||||
|
||||
|
||||
if required and not val:
|
||||
self.output.error(
|
||||
"Environment Variable {0} not set. Either add to .env file or to your system's Environment Variables".format(key))
|
||||
self.output.error("Environment Variable {0} not set. Either add to .env file or to your system's Environment Variables".format(key))
|
||||
sys.exit(-1)
|
||||
|
||||
return val
|
||||
# if we have a val return it, if not and we have a default then return default, otherwise return None.
|
||||
if val:
|
||||
return val
|
||||
elif default:
|
||||
return default
|
||||
else:
|
||||
return ''
|
||||
|
||||
def get_envvar_key_if_val(self, key):
|
||||
if key in os.environ and os.environ.get(key):
|
||||
return key
|
||||
else:
|
||||
return None
|
||||
|
||||
def set_envvar(self, key, value):
|
||||
os.environ[key] = value
|
||||
|
@ -164,8 +189,7 @@ class EnvVars:
|
|||
dotenv_path = os.path.join(os.getcwd(), dotenv_file)
|
||||
set_key(dotenv_path, key, value)
|
||||
except Exception:
|
||||
self.output.error(
|
||||
f("Could not update the environment variable {key} in file {dotenv_path}"))
|
||||
self.output.error(f("Could not update the environment variable {key} in file {dotenv_path}"))
|
||||
sys.exit(-1)
|
||||
|
||||
def get_runtime_home_dir(self):
|
||||
|
|
|
@ -1,15 +1,25 @@
|
|||
import os
|
||||
|
||||
|
||||
class IoTHub:
|
||||
def __init__(self, envvars, output, utility):
|
||||
def __init__(self, envvars, utility, output):
|
||||
self.envvars = envvars
|
||||
self.envvars.check()
|
||||
self.output = output
|
||||
self.utility = utility
|
||||
|
||||
def monitor_events(self):
|
||||
def monitor_events(self, timeout=0):
|
||||
if timeout == None:
|
||||
timeout = 0
|
||||
|
||||
try:
|
||||
self.utility.call_proc(['iothub-explorer', '--login', self.envvars.IOTHUB_CONNECTION_STRING,
|
||||
'monitor-events', self.envvars.DEVICE_CONNECTION_INFO.DeviceId], shell=not self.envvars.is_posix())
|
||||
if timeout == 0:
|
||||
self.utility.call_proc(['iothub-explorer', '--login', self.envvars.IOTHUB_CONNECTION_STRING,
|
||||
'monitor-events', self.envvars.DEVICE_CONNECTION_INFO.DeviceId], shell=not self.envvars.is_posix())
|
||||
else:
|
||||
monitor_js = os.path.join(os.path.split(__file__)[0], "monitor.js")
|
||||
|
||||
self.utility.call_proc(['node', monitor_js, self.envvars.IOTHUB_CONNECTION_STRING,
|
||||
self.envvars.DEVICE_CONNECTION_INFO.DeviceId, timeout], shell=not self.envvars.is_posix())
|
||||
except Exception as ex:
|
||||
self.output.error(
|
||||
"Problem while trying to call iothub-explorer. Please ensure that you have installed the iothub-explorer npm package with: npm i -g iothub-explorer.")
|
||||
|
|
|
@ -9,7 +9,6 @@ from .modulesprocessorfactory import ModulesProcessorFactory
|
|||
class Modules:
|
||||
def __init__(self, envvars, utility, output, dock):
|
||||
self.envvars = envvars
|
||||
self.envvars.check()
|
||||
self.utility = utility
|
||||
self.utility.set_config()
|
||||
self.output = output
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
const { spawn } = require('child_process');
|
||||
var kill = require('tree-kill');
|
||||
|
||||
var ls = spawn('iothub-explorer', ['monitor-events', '--login', process.argv[2], process.argv[3]], { shell: true }).on('error', function (err) { console.log(err); throw err });
|
||||
|
||||
setTimeout(function () { kill(ls.pid) }, process.argv[4])
|
||||
|
||||
ls.stdout.on('data', (data) => {
|
||||
console.log(`${data}`);
|
||||
});
|
||||
|
||||
ls.stderr.on('data', (data) => {
|
||||
console.log(`ERROR: ${data}`);
|
||||
});
|
||||
|
|
@ -1,27 +1,28 @@
|
|||
import click
|
||||
|
||||
|
||||
class Output:
|
||||
|
||||
def info(self, text):
|
||||
click.secho(text, fg='yellow')
|
||||
self.echo(text, color='yellow')
|
||||
|
||||
def status(self, text):
|
||||
self.info(text)
|
||||
self.line()
|
||||
|
||||
def prompt(self, text):
|
||||
click.secho(text, fg='white')
|
||||
self.echo(text, color='white')
|
||||
|
||||
def error(self, text):
|
||||
click.secho("ERROR: " + text, fg='red')
|
||||
self.echo("ERROR: " + text, color='red')
|
||||
|
||||
def header(self, text):
|
||||
self.line()
|
||||
s = "======== {0} ========".format(text).upper()
|
||||
m = "="*len(s)
|
||||
click.secho(m, fg='white')
|
||||
click.secho(s, fg='white')
|
||||
click.secho(m, fg='white')
|
||||
self.echo(m, color='white')
|
||||
self.echo(s, color='white')
|
||||
self.echo(m, color='white')
|
||||
self.line()
|
||||
|
||||
def param(self, text, value, status, suppress):
|
||||
|
@ -34,7 +35,13 @@ class Output:
|
|||
self.line()
|
||||
|
||||
def procout(self, text):
|
||||
click.secho(text, dim=True)
|
||||
self.echo(text, dim=True)
|
||||
|
||||
def line(self):
|
||||
click.secho("")
|
||||
self.echo(text="")
|
||||
|
||||
def echo(self, text, color="", dim=False):
|
||||
try:
|
||||
click.secho(text, fg=color, dim=dim)
|
||||
except:
|
||||
print (text)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
class Runtime:
|
||||
def __init__(self, envvars, utility, output, dock):
|
||||
self.envvars = envvars
|
||||
self.envvars.check()
|
||||
self.utility = utility
|
||||
self.utility.set_config()
|
||||
self.dock = dock
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import os
|
||||
import zipfile
|
||||
|
||||
|
||||
class Solution:
|
||||
def __init__(self, output):
|
||||
self.output = output
|
||||
|
@ -22,4 +23,6 @@ class Solution:
|
|||
zipf.extractall(name)
|
||||
|
||||
os.rename(os.path.join(name, ".env.tmp"), os.path.join(name, ".env"))
|
||||
self.output.footer("Azure IoT Edge Solution created")
|
||||
self.output.footer("Azure IoT Edge Solution Created")
|
||||
if name != "":
|
||||
self.output.info("Execute 'cd {0}' to navigate to your new solution.".format(name))
|
||||
|
|
|
@ -9,8 +9,10 @@ DEVICE_CONNECTION_STRING=""
|
|||
#
|
||||
# CONTAINER REGISTRY
|
||||
#
|
||||
# To host your modules
|
||||
# "localhost:5000" - to use local registry
|
||||
# Settings for your container registry, set CONTAINER_REGISTRY_SERVER to the following:
|
||||
# Local Registry: "localhost:5000" - USERNAME/PASSWORD not required.
|
||||
# Azure Container Registry: "jong.azurecr.io", Also set USERNAME/PASSWORD
|
||||
# Docker Hub: "jongallant" - Your Docker hub username. Enter your Docker hub username into the CONTAINER_REGISTRY_USERNAME setting. Also set the PASSWORD.
|
||||
|
||||
CONTAINER_REGISTRY_SERVER="localhost:5000"
|
||||
CONTAINER_REGISTRY_USERNAME=""
|
||||
|
@ -39,7 +41,7 @@ RUNTIME_HOST_NAME="."
|
|||
|
||||
RUNTIME_TAG="1.0-preview"
|
||||
|
||||
RUNTIME_VERBOSITY="DEBUG"
|
||||
RUNTIME_VERBOSITY="INFO"
|
||||
# "DEBUG", "INFO", "ERROR", "WARNING"
|
||||
|
||||
#
|
||||
|
@ -81,4 +83,22 @@ LOGS_CMD="start /B start cmd.exe @cmd /k docker logs {0} -f"
|
|||
# "start /B start cmd.exe @cmd /k docker logs {0} -f" - for CMD
|
||||
# "docker logs {0} -f -new_console:sV" - for ConEmu
|
||||
|
||||
|
||||
#
|
||||
# AZURE SETTINGS
|
||||
#
|
||||
# These settings will override parameters to the `iotedgedev azure --setup` command.
|
||||
# CREDENTIALS="username password"
|
||||
# SERVICE_PRINCIPAL="username password tenant"
|
||||
# RESOURCE_GROUP_LOCATION="australiaeast|australiasoutheast|brazilsouth|canadacentral|canadaeast|centralindia|centralus|eastasia|eastus|eastus2|japanwest|japaneast|northeurope|northcentralus|southindia|uksouth|ukwest|westus|westeurope|southcentralus|westcentralus|westus2"
|
||||
# IOTHUB_SKU="F1|S1|S2|S3"
|
||||
# UPDATE_DOTENV="True|False"
|
||||
|
||||
SUBSCRIPTION_ID=""
|
||||
RESOURCE_GROUP_NAME=""
|
||||
RESOURCE_GROUP_LOCATION=""
|
||||
IOTHUB_NAME=""
|
||||
IOTHUB_SKU=""
|
||||
EDGE_DEVICE_ID=""
|
||||
CREDENTIALS=""
|
||||
SERVICE_PRINCIPAL=""
|
||||
UPDATE_DOTENV=""
|
||||
|
|
Двоичные данные
iotedgedev/template/template.zip
Двоичные данные
iotedgedev/template/template.zip
Двоичный файл не отображается.
|
@ -14,11 +14,10 @@ else:
|
|||
from urllib import quote, urlencode
|
||||
from .moduletype import ModuleType
|
||||
|
||||
|
||||
class Utility:
|
||||
def __init__(self, envvars, output, envvars_check=True):
|
||||
def __init__(self, envvars, output):
|
||||
self.envvars = envvars
|
||||
if envvars_check:
|
||||
self.envvars.check()
|
||||
self.output = output
|
||||
self.config_set = False
|
||||
|
||||
|
@ -99,7 +98,6 @@ class Utility:
|
|||
def set_config(self, force=False):
|
||||
|
||||
if not self.config_set or force:
|
||||
self.envvars.check()
|
||||
self.output.header("PROCESSING CONFIG FILES")
|
||||
|
||||
config_output_dir = ".config"
|
||||
|
@ -133,4 +131,3 @@ class Utility:
|
|||
self.output.line()
|
||||
|
||||
self.config_set = True
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -20,6 +20,7 @@
|
|||
},
|
||||
"homepage": "https://github.com/jonbgallant/azure-iot-edge-dev-tool#readme",
|
||||
"dependencies": {
|
||||
"iothub-explorer": "^1.1.20"
|
||||
"iothub-explorer": "^1.1.20",
|
||||
"tree-kill": "^1.2.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[bumpversion]
|
||||
current_version = 0.67.0
|
||||
current_version = 0.70.0
|
||||
commit = True
|
||||
tag = True
|
||||
|
||||
|
|
2
setup.py
2
setup.py
|
@ -52,7 +52,7 @@ test_requirements = [
|
|||
|
||||
setup(
|
||||
name='azure-iot-edge-dev-tool',
|
||||
version='0.67.0',
|
||||
version='0.70.0',
|
||||
description="The Azure IoT Edge Dev Tool package greatly simplifies your IoT Edge development process by automating many of your routine manual tasks, such as building, deploying, pushing modules and configuring your IoT Edge Runtime.",
|
||||
long_description="See https://github.com/jonbgallant/azure-iot-edge-dev-tool for usage instructions.",
|
||||
author="Jon Gallant",
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Unit test package for iotedgedev."""
|
|
@ -1,173 +1,145 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Tests for `iotedgedev` package."""
|
||||
|
||||
|
||||
import unittest
|
||||
import pytest
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
|
||||
import click
|
||||
from click.testing import CliRunner
|
||||
from iotedgedev.envvars import EnvVars
|
||||
from iotedgedev.output import Output
|
||||
# from iotedgedev import cli
|
||||
|
||||
from distutils.dir_util import copy_tree
|
||||
from filecmp import dircmp
|
||||
from iotedgedev import cli
|
||||
from iotedgedev.azurecli import AzureCli
|
||||
|
||||
from dotenv import load_dotenv, find_dotenv
|
||||
|
||||
load_dotenv(find_dotenv())
|
||||
|
||||
test_solution = "test_solution"
|
||||
root_dir = os.getcwd()
|
||||
nodesolution = "node_solution"
|
||||
tests_dir = os.path.join(root_dir, "tests")
|
||||
env_file = os.path.join(root_dir, ".env")
|
||||
test_solution = "test_solution"
|
||||
node_solution = "node_solution"
|
||||
test_solution_dir = os.path.join(tests_dir, test_solution)
|
||||
node_solution_dir = os.path.join(tests_dir, node_solution)
|
||||
|
||||
|
||||
class TestAzureCli(AzureCli):
|
||||
def invoke_az_cli(self, args, error_message=None, io=None):
|
||||
return True
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def create_solution(request):
|
||||
|
||||
cli = __import__("iotedgedev.cli", fromlist=['main'])
|
||||
# print cli
|
||||
# out, err = capsys.readouterr()
|
||||
# print out
|
||||
|
||||
runner = CliRunner()
|
||||
os.chdir(tests_dir)
|
||||
result = runner.invoke(cli.main, ['solution', test_solution])
|
||||
print (result.output)
|
||||
assert 'AZURE IOT EDGE SOLUTION CREATED' in result.output
|
||||
|
||||
shutil.copyfile(env_file, os.path.join(test_solution_dir, '.env'))
|
||||
os.chdir(test_solution_dir)
|
||||
|
||||
def clean():
|
||||
os.chdir(root_dir)
|
||||
shutil.rmtree(test_solution_dir, ignore_errors=True)
|
||||
request.addfinalizer(clean)
|
||||
return
|
||||
|
||||
|
||||
class TestIoTEdgeDev(unittest.TestCase):
|
||||
@pytest.fixture
|
||||
def test_build_modules(request):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
"""SETUP"""
|
||||
print("SETTING UP TEST SOLUTION")
|
||||
try:
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli.main, ['solution', '--create', test_solution])
|
||||
# print(result.output)
|
||||
#assert result.exit_code == 0
|
||||
#assert 'Azure IoT Edge solution created' in result.output
|
||||
os.chdir(test_solution_dir)
|
||||
|
||||
shutil.copyfile('.env', os.path.join(os.getcwd(), test_solution, '.env'))
|
||||
os.chdir(test_solution)
|
||||
cli = __import__("iotedgedev.cli", fromlist=['main'])
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli.main, ['build'])
|
||||
print (result.output)
|
||||
|
||||
except Exception as ex:
|
||||
print(str(ex))
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(self):
|
||||
"""TEARDOWN"""
|
||||
os.chdir("..")
|
||||
shutil.rmtree(os.path.join(root_dir, test_solution), ignore_errors=True)
|
||||
|
||||
def test_version(self):
|
||||
"""VERSION"""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli.main, ['--version'])
|
||||
print(result.output)
|
||||
assert result.exit_code == 0
|
||||
assert 'version' in result.output
|
||||
|
||||
def test_help(self):
|
||||
"""HELP"""
|
||||
runner = CliRunner()
|
||||
help_result = runner.invoke(cli.main, ['--help'])
|
||||
assert help_result.exit_code == 0
|
||||
assert 'Show this message and exit.' in help_result.output
|
||||
|
||||
def test_modules_build_deploy(self):
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli.main, ['modules', '--build'])
|
||||
print(result.output)
|
||||
assert result.exit_code == 0
|
||||
assert '0 Error(s)' in result.output
|
||||
result = runner.invoke(cli.main, ['modules', '--deploy'])
|
||||
print(result.output)
|
||||
assert result.exit_code == 0
|
||||
assert 'Edge Device configuration successfully deployed' in result.output
|
||||
|
||||
def test_alternate_dotenv_file(self):
|
||||
dotenv_file = ".env.test"
|
||||
shutil.copyfile('../.env', dotenv_file)
|
||||
os.environ["DOTENV_FILE"] = dotenv_file
|
||||
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli.main, ['--set-config'])
|
||||
print(result.output)
|
||||
assert result.exit_code == 0
|
||||
test_string = "Environment Variables loaded from: " + dotenv_file
|
||||
assert test_string in result.output
|
||||
|
||||
# TODO implement the mock AzureCli class
|
||||
'''
|
||||
def test_azure_setup_command(self):
|
||||
dotenv_file = ".env.test"
|
||||
shutil.copyfile('../.env', dotenv_file)
|
||||
os.environ["DOTENV_FILE"] = dotenv_file
|
||||
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli.main, [
|
||||
'azure', '--setup',
|
||||
'--credentials', 'username', 'password',
|
||||
'--subscription', '12341234-1234-1234-1234-123412341234',
|
||||
'--resource-group-name', 'iotedgedev-rg',
|
||||
'--iothub-name', 'iotedgedev-iothub',
|
||||
'--edge-device-id', 'iotedgedev-edgedevice',
|
||||
'--update-dotenv'
|
||||
], az_cli = TestAzureCli(sys.stdout) )
|
||||
print(result.output)
|
||||
assert result.exit_code == 0
|
||||
test_string = "Environment Variables loaded from: " + dotenv_file
|
||||
assert test_string in result.output
|
||||
'''
|
||||
|
||||
# TODO: Figure out why tox messes with the paths.
|
||||
'''
|
||||
def test_runtime_setup(self):
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli.main, ['runtime', '--setup'])
|
||||
print(result.output)
|
||||
assert result.exit_code == 0
|
||||
assert 'Runtime setup successfully.' in result.output
|
||||
|
||||
def test_docker_logs(self):
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli.main, ['docker', '--save-logs'])
|
||||
print(result.output)
|
||||
assert result.exit_code == 0
|
||||
assert 'Log files successfully saved' in result.output
|
||||
'''
|
||||
|
||||
# TODO: Figure out why tox doesn't work in this case. Manually test it for now.
|
||||
'''
|
||||
def test_no_dotenv_file(self):
|
||||
dotenv_file = ".env.nofile"
|
||||
os.environ["DOTENV_FILE"] = dotenv_file
|
||||
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli.main, ['--set-config'])
|
||||
print(result.output)
|
||||
assert result.exit_code == 0
|
||||
test_string = "{0} file not found on disk".format(dotenv_file)
|
||||
assert test_string in result.output
|
||||
'''
|
||||
assert 'BUILD COMPLETE' in result.output
|
||||
|
||||
|
||||
class TestNodeSolution(unittest.TestCase):
|
||||
@pytest.fixture
|
||||
def test_deploy_modules(request):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(self):
|
||||
"""SETUP"""
|
||||
print("SETTING UP NODE TEST SOLUTION")
|
||||
try:
|
||||
node_sol_path = os.path.join("tests", nodesolution)
|
||||
shutil.copyfile('.env', os.path.join(os.getcwd(), node_sol_path, '.env'))
|
||||
os.chdir(node_sol_path)
|
||||
os.chdir(test_solution_dir)
|
||||
|
||||
except Exception as ex:
|
||||
print(str(ex))
|
||||
cli = __import__("iotedgedev.cli", fromlist=['main'])
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli.main, ['deploy'])
|
||||
print (result.output)
|
||||
|
||||
def test_modules_build_deploy(self):
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli.main, ['modules', '--build'])
|
||||
print(result.output)
|
||||
assert result.exit_code == 0
|
||||
assert 'BUILD COMPLETE' in result.output
|
||||
result = runner.invoke(cli.main, ['modules', '--deploy'])
|
||||
print(result.output)
|
||||
assert result.exit_code == 0
|
||||
assert 'Edge Device configuration successfully deployed' in result.output
|
||||
assert 'DEPLOY COMPLETE' in result.output
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_start_runtime(request):
|
||||
|
||||
os.chdir(test_solution_dir)
|
||||
|
||||
cli = __import__("iotedgedev.cli", fromlist=['main'])
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli.main, ['start'])
|
||||
print (result.output)
|
||||
|
||||
assert 'Runtime started' in result.output
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_monitor(request, capfd):
|
||||
|
||||
os.chdir(test_solution_dir)
|
||||
|
||||
cli = __import__("iotedgedev.cli", fromlist=['main'])
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli.main, ['monitor', '--timeout', '40000'])
|
||||
out, err = capfd.readouterr()
|
||||
print (out)
|
||||
print (err)
|
||||
print (result.output)
|
||||
|
||||
assert 'application properties' in out
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_stop(request):
|
||||
|
||||
os.chdir(test_solution_dir)
|
||||
|
||||
cli = __import__("iotedgedev.cli", fromlist=['main'])
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli.main, ['stop'])
|
||||
print (result.output)
|
||||
|
||||
assert 'Runtime stopped' in result.output
|
||||
|
||||
|
||||
def test_e2e(test_build_modules, test_deploy_modules, test_start_runtime, test_monitor, test_stop):
|
||||
print ('Testing E2E')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def setup_node_solution(request):
|
||||
|
||||
shutil.copyfile(env_file, os.path.join(node_solution_dir, '.env'))
|
||||
os.chdir(node_solution_dir)
|
||||
|
||||
def clean():
|
||||
os.chdir(root_dir)
|
||||
request.addfinalizer(clean)
|
||||
return
|
||||
|
||||
|
||||
def test_node(setup_node_solution, test_build_modules, test_deploy_modules, test_start_runtime, test_monitor, test_stop):
|
||||
print ('Testing Node Solution')
|
||||
|
||||
|
||||
'''
|
||||
def test_load_no_dotenv():
|
||||
|
||||
dotenv_file = ".env.nofile"
|
||||
os.environ["DOTENV_FILE"] = dotenv_file
|
||||
|
||||
# cli_inst =
|
||||
# runner = CliRunner()
|
||||
# result = runner.invoke(cli.main, ['--set-config'])
|
||||
# print result.output
|
||||
# assert result.exit_code == 0
|
||||
# assert '.env.test file not found on disk.' in result.output
|
||||
# assert 'PROCESSING' in result.output
|
||||
'''
|
||||
|
|
20
tox.ini
20
tox.ini
|
@ -1,10 +1,10 @@
|
|||
[tox]
|
||||
envlist = py27, py36
|
||||
|
||||
[travis]
|
||||
python =
|
||||
3.6: py36
|
||||
2.7: py27
|
||||
#[travis]
|
||||
#python =
|
||||
# 3.6: py36
|
||||
# 2.7: py27
|
||||
|
||||
#[testenv:flake8]
|
||||
#basepython=python
|
||||
|
@ -12,16 +12,18 @@ python =
|
|||
#commands=flake8 iotedgedev
|
||||
|
||||
[testenv]
|
||||
setenv =
|
||||
PYTHONPATH = {toxinidir}
|
||||
deps=pytest
|
||||
commands=pytest -s
|
||||
#setenv =
|
||||
# PYTHONPATH = {toxinidir}
|
||||
|
||||
commands =
|
||||
python setup.py test
|
||||
#commands =
|
||||
# python setup.py test
|
||||
|
||||
passenv = APPDATA ProgramFiles USERPROFILE PROGRAMDATA
|
||||
|
||||
|
||||
; If you want to make tox run the tests with the same versions, create a
|
||||
; requirements.txt with the pinned versions and uncomment the following lines:
|
||||
; deps =
|
||||
; -r{toxinidir}/requirements.txt
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче