зеркало из https://github.com/Azure/iotedgedev.git
Support new schema of deployment.json with backward compatibility (#222)
* Support modulesContent * Extract get_desired_property method * Add test cases for get_desired_property method
This commit is contained in:
Родитель
7b148eb3ac
Коммит
bc695307b7
|
@ -43,7 +43,11 @@ class DeploymentManifest:
|
|||
}
|
||||
}"""
|
||||
|
||||
self.utility.nested_set(self.json, ["moduleContent", "$edgeAgent", "properties.desired", "modules", module_name], json.loads(new_module))
|
||||
try:
|
||||
self.utility.nested_set(self.get_module_content(), ["$edgeAgent", "properties.desired", "modules", module_name], json.loads(new_module))
|
||||
except KeyError as err:
|
||||
self.output.error("Missing key {0} in file {1}".format(err, self.path))
|
||||
sys.exit(1)
|
||||
|
||||
self.add_default_route(module_name)
|
||||
|
||||
|
@ -52,24 +56,61 @@ class DeploymentManifest:
|
|||
new_route_name = "{0}ToIoTHub".format(module_name)
|
||||
new_route = "FROM /messages/modules/{0}/outputs/* INTO $upstream".format(module_name)
|
||||
|
||||
self.utility.nested_set(self.json, ["moduleContent", "$edgeHub", "properties.desired", "routes", new_route_name], new_route)
|
||||
try:
|
||||
self.utility.nested_set(self.get_module_content(), ["$edgeHub", "properties.desired", "routes", new_route_name], new_route)
|
||||
except KeyError as err:
|
||||
self.output.error("Missing key {0} in file {1}".format(err, self.path))
|
||||
sys.exit(1)
|
||||
|
||||
def get_user_modules(self):
|
||||
"""Get user modules from deployment manifest"""
|
||||
try:
|
||||
modules = self.get_desired_property("$edgeAgent", "modules")
|
||||
return list(modules.keys())
|
||||
except KeyError as err:
|
||||
self.output.error("Missing key {0} in file {1}".format(err, self.path))
|
||||
sys.exit(1)
|
||||
|
||||
def get_system_modules(self):
|
||||
"""Get system modules from deployment manifest"""
|
||||
try:
|
||||
modules = self.get_desired_property("$edgeAgent", "systemModules")
|
||||
return list(modules.keys())
|
||||
except KeyError as err:
|
||||
self.output.error("Missing key {0} in file {1}".format(err, self.path))
|
||||
sys.exit(1)
|
||||
|
||||
def get_modules_to_process(self):
|
||||
"""Get modules to process from deployment manifest template"""
|
||||
user_modules = self.json.get("moduleContent", {}).get("$edgeAgent", {}).get("properties.desired", {}).get("modules", {})
|
||||
modules_to_process = []
|
||||
for _, module_info in user_modules.items():
|
||||
image = module_info.get("settings", {}).get("image", "")
|
||||
# If the image is placeholder, e.g., ${MODULES.NodeModule.amd64}, parse module folder and platform from the placeholder
|
||||
if image.startswith("${") and image.endswith("}") and len(image.split(".")) > 2:
|
||||
first_dot = image.index(".")
|
||||
second_dot = image.index(".", first_dot + 1)
|
||||
module_dir = image[first_dot+1:second_dot]
|
||||
module_platform = image[second_dot+1:image.index("}")]
|
||||
modules_to_process.append((module_dir, module_platform))
|
||||
return modules_to_process
|
||||
try:
|
||||
user_modules = self.get_desired_property("$edgeAgent", "modules")
|
||||
modules_to_process = []
|
||||
for _, module_info in user_modules.items():
|
||||
image = module_info["settings"]["image"]
|
||||
# If the image is placeholder, e.g., ${MODULES.NodeModule.amd64}, parse module folder and platform from the placeholder
|
||||
if image.startswith("${") and image.endswith("}") and len(image.split(".")) > 2:
|
||||
first_dot = image.index(".")
|
||||
second_dot = image.index(".", first_dot + 1)
|
||||
module_dir = image[first_dot+1:second_dot]
|
||||
module_platform = image[second_dot+1:image.index("}")]
|
||||
modules_to_process.append((module_dir, module_platform))
|
||||
return modules_to_process
|
||||
except KeyError as err:
|
||||
self.output.error("Missing key {0} in file {1}".format(err, self.path))
|
||||
sys.exit(1)
|
||||
|
||||
def get_desired_property(self, module, prop):
|
||||
return self.get_module_content()[module]["properties.desired"][prop]
|
||||
|
||||
def save(self):
|
||||
"""Dump the JSON to the disk"""
|
||||
with open(self.path, "w") as deployment_manifest:
|
||||
json.dump(self.json, deployment_manifest, indent=2)
|
||||
|
||||
def get_module_content(self):
|
||||
if "modulesContent" in self.json:
|
||||
return self.json["modulesContent"]
|
||||
elif "moduleContent" in self.json:
|
||||
return self.json["moduleContent"]
|
||||
else:
|
||||
raise KeyError("modulesContent")
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"moduleContent": {
|
||||
"modulesContent": {
|
||||
"$edgeAgent": {
|
||||
"properties.desired": {
|
||||
"schemaVersion": "1.0",
|
||||
|
|
|
@ -8,6 +8,7 @@ from hashlib import sha256
|
|||
from hmac import HMAC
|
||||
from time import time
|
||||
|
||||
from .deploymentmanifest import DeploymentManifest
|
||||
from .moduletype import ModuleType
|
||||
|
||||
if sys.version_info.major >= 3:
|
||||
|
@ -107,12 +108,10 @@ class Utility:
|
|||
return len(asterisk_list) > 0 and (asterisk_list[0] == "*" or item in asterisk_list)
|
||||
|
||||
def get_modules_in_config(self, moduleType):
|
||||
modules_config = json.load(open(self.envvars.DEPLOYMENT_CONFIG_FILE_PATH))
|
||||
deployment_manifest = DeploymentManifest(self.envvars, self.output, self, self.envvars.DEPLOYMENT_CONFIG_FILE_PATH, False)
|
||||
|
||||
props = modules_config["moduleContent"]["$edgeAgent"]["properties.desired"]
|
||||
|
||||
system_modules = props["systemModules"]
|
||||
user_modules = props["modules"]
|
||||
system_modules = deployment_manifest.get_system_modules()
|
||||
user_modules = deployment_manifest.get_user_modules()
|
||||
|
||||
if moduleType == ModuleType.System:
|
||||
return system_modules
|
||||
|
|
|
@ -18,6 +18,3 @@ universal = 1
|
|||
exclude = docs
|
||||
|
||||
[aliases]
|
||||
|
||||
[pytest]
|
||||
norecursedirs=tests/utility
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"moduleContent": {
|
||||
"modulesContent": {
|
||||
"$edgeAgent": {
|
||||
"properties.desired": {
|
||||
"schemaVersion": "1.0",
|
||||
|
@ -29,7 +29,7 @@
|
|||
}
|
||||
},
|
||||
"modules": {
|
||||
"temp-sensor-module": {
|
||||
"tempSensor": {
|
||||
"version": "1.0",
|
||||
"type": "docker",
|
||||
"status": "running",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"moduleContent": {
|
||||
"modulesContent": {
|
||||
"$edgeAgent": {
|
||||
"properties.desired": {
|
||||
"schemaVersion": "1.0",
|
||||
|
@ -29,7 +29,7 @@
|
|||
}
|
||||
},
|
||||
"modules": {
|
||||
"temp-sensor-module": {
|
||||
"tempSensor": {
|
||||
"version": "1.0",
|
||||
"type": "docker",
|
||||
"status": "running",
|
||||
|
|
|
@ -1,90 +1,90 @@
|
|||
{
|
||||
"moduleContent": {
|
||||
"$edgeAgent": {
|
||||
"properties.desired": {
|
||||
"schemaVersion": "1.0",
|
||||
"runtime": {
|
||||
"type": "docker",
|
||||
"settings": {
|
||||
"minDockerVersion": "v1.25",
|
||||
"loggingOptions": ""
|
||||
}
|
||||
},
|
||||
"systemModules": {
|
||||
"edgeAgent": {
|
||||
"type": "docker",
|
||||
"settings": {
|
||||
"image": "mcr.microsoft.com/azureiotedge-agent:1.0",
|
||||
"createOptions": ""
|
||||
}
|
||||
},
|
||||
"edgeHub": {
|
||||
"type": "docker",
|
||||
"status": "running",
|
||||
"restartPolicy": "always",
|
||||
"settings": {
|
||||
"image": "mcr.microsoft.com/azureiotedge-hub:1.0",
|
||||
"createOptions": "{\"HostConfig\":{\"PortBindings\":{\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": {
|
||||
"temp-sensor-module": {
|
||||
"version": "1.0",
|
||||
"type": "docker",
|
||||
"status": "running",
|
||||
"restartPolicy": "always",
|
||||
"settings": {
|
||||
"image": "mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:1.0",
|
||||
"createOptions": ""
|
||||
}
|
||||
},
|
||||
"csharpmodule": {
|
||||
"version": "1.0",
|
||||
"type": "docker",
|
||||
"status": "running",
|
||||
"restartPolicy": "always",
|
||||
"settings": {
|
||||
"image": "${MODULES.csharpmodule.amd64}",
|
||||
"createOptions": ""
|
||||
}
|
||||
},
|
||||
"csharpfunction": {
|
||||
"version": "1.0",
|
||||
"type": "docker",
|
||||
"status": "running",
|
||||
"restartPolicy": "always",
|
||||
"settings": {
|
||||
"image": "${MODULES.csharpfunction.amd64.debug}",
|
||||
"createOptions": ""
|
||||
}
|
||||
},
|
||||
"csharpmodule2": {
|
||||
"version": "1.0",
|
||||
"type": "docker",
|
||||
"status": "running",
|
||||
"restartPolicy": "always",
|
||||
"settings": {
|
||||
"image": "${MODULES.csharpmodule2.amd64}",
|
||||
"createOptions": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"modulesContent": {
|
||||
"$edgeAgent": {
|
||||
"properties.desired": {
|
||||
"schemaVersion": "1.0",
|
||||
"runtime": {
|
||||
"type": "docker",
|
||||
"settings": {
|
||||
"minDockerVersion": "v1.25",
|
||||
"loggingOptions": ""
|
||||
}
|
||||
},
|
||||
"$edgeHub": {
|
||||
"properties.desired": {
|
||||
"schemaVersion": "1.0",
|
||||
"routes": {
|
||||
"sensorTocsharpmodule": "FROM /messages/modules/tempSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/csharpmodule/inputs/input1\")",
|
||||
"csharpmoduleToIoTHub": "FROM /messages/modules/csharpmodule/outputs/* INTO $upstream",
|
||||
"csharpfunctionToIoTHub": "FROM /messages/modules/csharpfunction/outputs/* INTO $upstream",
|
||||
"csharpmodule2ToIoTHub": "FROM /messages/modules/csharpmodule2/outputs/* INTO $upstream"
|
||||
},
|
||||
"storeAndForwardConfiguration": {
|
||||
"timeToLiveSecs": 7200
|
||||
}
|
||||
"systemModules": {
|
||||
"edgeAgent": {
|
||||
"type": "docker",
|
||||
"settings": {
|
||||
"image": "mcr.microsoft.com/azureiotedge-agent:1.0",
|
||||
"createOptions": ""
|
||||
}
|
||||
},
|
||||
"edgeHub": {
|
||||
"type": "docker",
|
||||
"status": "running",
|
||||
"restartPolicy": "always",
|
||||
"settings": {
|
||||
"image": "mcr.microsoft.com/azureiotedge-hub:1.0",
|
||||
"createOptions": "{\"HostConfig\":{\"PortBindings\":{\"8883/tcp\":[{\"HostPort\":\"8883\"}],\"443/tcp\":[{\"HostPort\":\"443\"}]}}}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"modules": {
|
||||
"tempSensor": {
|
||||
"version": "1.0",
|
||||
"type": "docker",
|
||||
"status": "running",
|
||||
"restartPolicy": "always",
|
||||
"settings": {
|
||||
"image": "mcr.microsoft.com/azureiotedge-simulated-temperature-sensor:1.0",
|
||||
"createOptions": ""
|
||||
}
|
||||
},
|
||||
"csharpmodule": {
|
||||
"version": "1.0",
|
||||
"type": "docker",
|
||||
"status": "running",
|
||||
"restartPolicy": "always",
|
||||
"settings": {
|
||||
"image": "${MODULES.csharpmodule.amd64}",
|
||||
"createOptions": ""
|
||||
}
|
||||
},
|
||||
"csharpfunction": {
|
||||
"version": "1.0",
|
||||
"type": "docker",
|
||||
"status": "running",
|
||||
"restartPolicy": "always",
|
||||
"settings": {
|
||||
"image": "${MODULES.csharpfunction.amd64.debug}",
|
||||
"createOptions": ""
|
||||
}
|
||||
},
|
||||
"csharpmodule2": {
|
||||
"version": "1.0",
|
||||
"type": "docker",
|
||||
"status": "running",
|
||||
"restartPolicy": "always",
|
||||
"settings": {
|
||||
"image": "${MODULES.csharpmodule2.amd64}",
|
||||
"createOptions": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"$edgeHub": {
|
||||
"properties.desired": {
|
||||
"schemaVersion": "1.0",
|
||||
"routes": {
|
||||
"sensorTocsharpmodule": "FROM /messages/modules/tempSensor/outputs/temperatureOutput INTO BrokeredEndpoint(\"/modules/csharpmodule/inputs/input1\")",
|
||||
"csharpmoduleToIoTHub": "FROM /messages/modules/csharpmodule/outputs/* INTO $upstream",
|
||||
"csharpfunctionToIoTHub": "FROM /messages/modules/csharpfunction/outputs/* INTO $upstream",
|
||||
"csharpmodule2ToIoTHub": "FROM /messages/modules/csharpmodule2/outputs/* INTO $upstream"
|
||||
},
|
||||
"storeAndForwardConfiguration": {
|
||||
"timeToLiveSecs": 7200
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
import os
|
||||
import sys
|
||||
|
||||
sys.path.append(os.path.join(os.path.dirname(__file__), "utility"))
|
|
@ -7,7 +7,8 @@ from iotedgedev.deploymentmanifest import DeploymentManifest
|
|||
from iotedgedev.envvars import EnvVars
|
||||
from iotedgedev.output import Output
|
||||
from iotedgedev.utility import Utility
|
||||
from utility import assert_list_equal
|
||||
|
||||
from .utility import assert_list_equal
|
||||
|
||||
pytestmark = pytest.mark.unit
|
||||
|
||||
|
@ -31,6 +32,36 @@ def deployment_manifest():
|
|||
return _deployment_manifest
|
||||
|
||||
|
||||
def test_get_desired_property(deployment_manifest):
|
||||
deployment_manifest = deployment_manifest(test_file_1)
|
||||
props = deployment_manifest.get_desired_property("$edgeHub", "schemaVersion")
|
||||
assert props == "1.0"
|
||||
|
||||
|
||||
def test_get_desired_property_nonexistent_module(deployment_manifest):
|
||||
deployment_manifest = deployment_manifest(test_file_1)
|
||||
with pytest.raises(KeyError):
|
||||
deployment_manifest.get_desired_property("nonexistentModule", "schemaVersion")
|
||||
|
||||
|
||||
def test_get_desired_property_nonexistent_prop(deployment_manifest):
|
||||
deployment_manifest = deployment_manifest(test_file_1)
|
||||
with pytest.raises(KeyError):
|
||||
deployment_manifest.get_desired_property("$edgeHub", "nonexistentProp")
|
||||
|
||||
|
||||
def test_get_user_modules(deployment_manifest):
|
||||
deployment_manifest = deployment_manifest(test_file_1)
|
||||
user_modules = deployment_manifest.get_user_modules()
|
||||
assert_list_equal(user_modules, ["tempSensor", "csharpmodule", "csharpfunction"])
|
||||
|
||||
|
||||
def test_get_system_modules(deployment_manifest):
|
||||
deployment_manifest = deployment_manifest(test_file_1)
|
||||
system_modules = deployment_manifest.get_system_modules()
|
||||
assert_list_equal(system_modules, ["edgeAgent", "edgeHub"])
|
||||
|
||||
|
||||
def test_get_modules_to_process(deployment_manifest):
|
||||
deployment_manifest = deployment_manifest(test_file_1)
|
||||
modules_to_process = deployment_manifest.get_modules_to_process()
|
||||
|
|
|
@ -269,4 +269,4 @@ def add_module_and_verify(main, runner, template):
|
|||
print(result.output)
|
||||
assert 'ADD COMPLETE' in result.output
|
||||
assert os.path.exists(os.path.join(os.environ["MODULES_PATH"], module_name))
|
||||
assert module_name in json.load(open(os.environ["DEPLOYMENT_CONFIG_TEMPLATE_FILE"]))["moduleContent"]["$edgeAgent"]["properties.desired"]["modules"]
|
||||
assert module_name in json.load(open(os.environ["DEPLOYMENT_CONFIG_TEMPLATE_FILE"]))["modulesContent"]["$edgeAgent"]["properties.desired"]["modules"]
|
||||
|
|
|
@ -5,7 +5,8 @@ import pytest
|
|||
from iotedgedev.envvars import EnvVars
|
||||
from iotedgedev.output import Output
|
||||
from iotedgedev.utility import Utility
|
||||
from utility import assert_json_file_equal
|
||||
|
||||
from .utility import assert_json_file_equal
|
||||
|
||||
pytestmark = pytest.mark.unit
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import json
|
|||
|
||||
|
||||
def assert_list_equal(list1, list2):
|
||||
return len(list1) == len(list2) and sorted(list1) == sorted(list2)
|
||||
assert len(list1) == len(list2) and sorted(list1) == sorted(list2)
|
||||
|
||||
|
||||
def assert_json_file_equal(file1, file2):
|
Загрузка…
Ссылка в новой задаче