-
Notifications
You must be signed in to change notification settings - Fork 382
Description
Context
- OS and version used: Oracle Linux 8.10 (Tenable OT OS)
- Python version: Python 3.12.11
- pip version: uv 0.8.15 used to create docker image, but installed pip 25.0.1 to get package list
- list of installed packages:
Click to show package list
(ce-tenable-ot-extractor) appuser@7b4a22d5a924:~$ venv/bin/pip3 list
Package Version
----------------------- ------------------
aiohappyeyeballs 2.6.1
aiohttp 3.12.15
aiosignal 1.4.0
annotated-types 0.7.0
anyio 4.10.0
APScheduler 3.11.0
arrow 1.3.0
attrs 25.3.0
azure-core 1.35.0
azure-iot-device 2.14.0
azure-storage-blob 12.26.0
backoff 2.2.1
ce_tenable_ot_extractor 0.3.2.dev7+ba48086
certifi 2025.8.3
cffi 1.17.1
charset-normalizer 3.4.3
click 8.2.1
cryptography 45.0.7
defusedxml 0.7.1
deprecation 2.1.0
frozenlist 1.7.0
gql 4.0.0
graphql-core 3.2.6
idna 3.10
inflection 0.5.1
isodate 0.7.2
janus 2.0.0
markdown-it-py 4.0.0
marshmallow 3.26.1
mdurl 0.1.2
multidict 6.6.4
numpy 2.3.2
packaging 25.0
paho-mqtt 1.6.1
pandas 2.3.1
pip 25.0.1
propcache 0.3.2
pycparser 2.22
pydantic 2.11.7
pydantic_core 2.33.2
pydantic-extra-types 2.10.5
pydantic-settings 2.10.1
Pygments 2.19.2
PySocks 1.7.1
pyTenable 1.8.4
python-box 7.3.2
python-dateutil 2.9.0.post0
python-dotenv 1.1.1
pytz 2025.2
requests 2.32.5
requests-toolbelt 1.0.0
requests-unixsocket2 1.0.1
restfly 1.5.1
rich 14.1.0
semver 3.0.4
shellingham 1.5.4
six 1.17.0
sniffio 1.3.1
typer 0.17.4
types-python-dateutil 2.9.0.20250822
typing_extensions 4.15.0
typing-inspection 0.4.1
tzdata 2025.2
tzlocal 5.3.1
urllib3 2.5.0
yarl 1.20.1
- cloned repo: Not used
-support bundle:
support_bundle_2025_09_07_21_33_44_UTC.zip
Description of the issue
I am experiencing the same issue as this person: #821
When I use IoTHubModuleClient.create_from_edge_environment().get_twin(), I only get the properties, but not other module twin data.
Expected twin
This is the twin data I get from the Azure Portal:
{
"etag": "AAAAAAAAAAM=",
"deviceId": "kim-tenable-ot-01",
"deviceEtag": "ODEzNTY3NDk=",
"moduleId": "tenable-ot-extractor",
"version": 51625,
"properties": {
"desired": {
"$metadata": {
"$lastUpdated": "2025-07-24T17:56:03.5921753Z",
"$lastUpdatedVersion": 3,
"settings": {
"$lastUpdated": "2025-07-24T17:51:56.7026873Z",
"$lastUpdatedVersion": 2,
"tenable_ot_api_key": {
"$lastUpdated": "2025-07-24T17:51:56.7026873Z",
"$lastUpdatedVersion": 2
},
"tenable_ot_url": {
"$lastUpdated": "2025-07-24T17:51:56.7026873Z",
"$lastUpdatedVersion": 2
},
"upload_interval": {
"$lastUpdated": "2025-07-24T17:51:56.7026873Z",
"$lastUpdatedVersion": 2
}
},
"test-settings": {
"$lastUpdated": "2025-07-24T17:56:03.5921753Z",
"$lastUpdatedVersion": 3,
"foo": {
"$lastUpdated": "2025-07-24T17:56:03.5921753Z",
"$lastUpdatedBy": "deployment_dev_v0_1_5-0-g41cdd32",
"$lastUpdatedByDigest": "638792387321632884",
"$lastUpdatedVersion": 3
}
}
},
"$version": 3,
"settings": {
"tenable_ot_api_key": "XXX=",
"tenable_ot_url": "https://host.docker.internal",
"upload_interval": "30"
}
},
"reported": {
"$metadata": {
"$lastUpdated": "2025-09-07T19:51:02.6298212Z",
"connectionStatus": {
"$lastUpdated": "2025-09-07T19:51:02.6298212Z"
},
"lastHeartbeatTime": {
"$lastUpdated": "2025-09-07T19:51:02.6298212Z"
},
"moduleStatus": {
"$lastUpdated": "2025-09-07T19:51:02.6298212Z"
}
},
"$version": 51622,
"connectionStatus": "connected",
"lastHeartbeatTime": "2025-09-07T19:51:02.516048+00:00",
"moduleStatus": "running"
}
},
"configurations": {
"deployment_dev_v0_1_3-0-ga3244e0": {
"status": "Targeted"
},
"deployment_dev_v0_1_4-0-gc44df30": {
"status": "Targeted"
},
"deployment_dev_v0_1_4-1-g95f3fc7": {
"status": "Targeted"
},
"deployment_dev_v0_1_5-0-g41cdd32": {
"status": "Applied"
}
},
"modelId": "",
"status": "enabled",
"statusUpdateTime": "0001-01-01T00:00:00.0000000Z",
"lastActivityTime": "2025-09-07T19:49:30.2062010Z",
"connectionState": "Connected",
"cloudToDeviceMessageCount": 0,
"authenticationType": "sas"
}Actually received twin
This is what my python code actually gets. As you can see, it's only the properties key, but it doesn't even include the properties key itself and no metadata.
{
"desired": {
"$version": 3,
"settings": {
"tenable_ot_api_key": "XXX=",
"tenable_ot_url": "https://host.docker.internal",
"upload_interval": "30"
},
"test-settings": {
"foo": "bar"
}
},
"reported": {
"$version": 51699,
"connectionStatus": "connected",
"lastHeartbeatTime": "2025-09-07T21:20:13.223778+00:00",
"moduleStatus": "running"
}
}Attempted solutions
I tried all the suggestions in the other issue, but they didn't help.
I added the dns section to my /etc/docker/daemon.json:
[Kim@tenable-q82xbzqn ~]$ cat /etc/docker/daemon.json
{
"bip": "172.17.0.254/24",
"fixed-cidr": "172.17.0.128/25",
"mtu": 9000,
"log-driver": "local",
"dns": ["1.1.1.1"]
}
I also tried the OPs suggestion of adjusting the /etc/aziot/config.toml to add /etc/hosts binds:
# [agent.config]
# image = "mcr.microsoft.com/azureiotedge-agent:1.5"
createOptions = { HostConfig = { Binds = ["/iotedge/storage:/iotedge/storage", "/etc/hosts:/etc/hosts"] } }
I did run sudo iotedge config apply and tried rebooting. But none of this helped.
And I am not using a proxy.
Code sample exhibiting the issue
from pprint import pprint
from azure.iot.device import IoTHubModuleClient
def get_module_twin_edge_env():
print('Creating client from edge environment...')
client = IoTHubModuleClient.create_from_edge_environment()
print('Getting twin...')
twin = client.get_twin()
pprint(twin)
print('Shutting down client...')
client.shutdown()
def main():
get_module_twin_edge_env()
if __name__ == "__main__":
main()Console log of the issue
The easiest way to reproduce is to exec a shell in an existing IoT Edge module that has python installed and isn't already connected to the IoTHub.
If the main process is already connected, you will get errors like 'azure.iot.device.common.transport_exceptions.ConnectionDroppedError: Unexpected disconnection\n'.
[Kim@tenable-q82xbzqn ~]$ docker ps | grep extractor
6aa2f8e46529 crcentryproduks.azurecr.io/tenable-ot-extractor:develop-0.3.2.dev8-b20084e "ce_tenable_ot_extra…" 8 minutes ago Up 8 minutes tenable-ot-extractor
[Kim@tenable-q82xbzqn ~]$ docker exec -it 6aa2f8e46529 bash
appuser@6aa2f8e46529:~$ cat > test.py
from pprint import pprint
from azure.iot.device import IoTHubModuleClient
def get_module_twin_edge_env():
print('Creating client from edge environment...')
client = IoTHubModuleClient.create_from_edge_environment()
print('Getting twin...')
twin = client.get_twin()
pprint(twin)
print('Shutting down client...')
client.shutdown()
def main():
get_module_twin_edge_env()
if __name__ == "__main__":
main()
appuser@6aa2f8e46529:~$ python test.py
Creating client from edge environment...
Getting twin...
{'desired': {'$version': 3,
'settings': {'tenable_ot_api_key': 'XXX=',
'tenable_ot_url': 'https://host.docker.internal',
'upload_interval': '30'},
'test-settings': {'foo': 'bar'}},
'reported': {'$version': 51699,
'connectionStatus': 'connected',
'lastHeartbeatTime': '2025-09-07T21:20:13.223778+00:00',
'moduleStatus': 'running'}}
Shutting down client...
appuser@6aa2f8e46529:~$Conclusion
Thank you so much in advance for your help.