Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,22 @@ Release History
0.10.9
+++++++++++++++

**Azure IoT Product Certification service**
**Azure IoT Product Certification service updates**

* Fix bug for `az iot product test create` sending a byte string instead of "regular" base64 string.

**Azure Digital Twins updates**

* Addition of Digital Twins Identity support focused around Managed Service Identity (MSI) and Identity based endpoint integration.
* Addition of Digital Twins networking functionality around private-links and private-endpoint connections. See "az dt network".

**IoT Hub updates**

* Improve http debug logging.
* Fix bug related to issue #296. Adds a clause to device-identity update that allows user to update primary-key / secondary-key
and primary-thumbprint / secondary-thumbprint values (respectively, per auth method) without needing to specify the auth_method in the update command.


0.10.8
+++++++++++++++

Expand Down
6 changes: 5 additions & 1 deletion azext_iot/_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from azext_iot.common.sas_token_auth import SasTokenAuthentication
from azext_iot.common.shared import SdkType
from azext_iot.constants import USER_AGENT
from msrestazure.azure_exceptions import CloudError

__all__ = [
Expand Down Expand Up @@ -70,7 +71,10 @@ def __init__(self, target, device_id=None, auth_override=None):

def get_sdk(self, sdk_type):
sdk_map = self._construct_sdk_map()
return sdk_map[sdk_type]()
sdk_client = sdk_map[sdk_type]()
sdk_client.config.enable_http_logger = True
sdk_client.config.add_user_agent(USER_AGENT)
return sdk_client

def _construct_sdk_map(self):
return {
Expand Down
14 changes: 11 additions & 3 deletions azext_iot/common/embedded_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,22 @@ def __init__(self):

def invoke(self, command: str, subscription: str = None):
output_file = StringIO()

command = self._ensure_json_output(command=command)
if subscription:
command = self._ensure_subscription(
command=command, subscription=subscription
)
self.error_code = (
self.az_cli.invoke(shlex.split(command), out_file=output_file) or 0
)

# TODO: Capture stderr?
try:
self.error_code = (
self.az_cli.invoke(shlex.split(command), out_file=output_file) or 0
)
except SystemExit as se:
# Support caller error handling
self.error_code = se.code

self.output = output_file.getvalue()
logger.debug(
"Embedded CLI received error code: %s, output: '%s'",
Expand Down
153 changes: 144 additions & 9 deletions azext_iot/digitaltwins/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,34 @@ def load_digitaltwins_help():
short-summary: Create a new Digital Twins instance.

examples:
- name: Create instance in target resource group with default location.
- name: Create instance in target resource group using the resource group location.
text: >
az dt create -n {instance_name} -g {resouce_group} -l eastus2euap
az dt create -n {instance_name} -g {resouce_group}

- name: Create instance in target resource group with specified location and tags.
text: >
az dt create -n {instance_name} -g {resouce_group} -l westcentralus --tags a=b c=d
az dt create -n {instance_name} -g {resouce_group} -l westus --tags a=b c=d

- name: Create instance in the target resource group with a system managed identity.
text: >
az dt create -n {instance_name} -g {resouce_group} --assign-identity

- name: Create instance in the target resource group with a system managed identity then
assign the identity to one or more scopes (space-separated) with the role of Contributor.
text: >
az dt create -n {instance_name} -g {resouce_group} --assign-identity
--scopes
"/subscriptions/a12345ea-bb21-994d-2263-c716348e32a1/resourceGroups/ProResourceGroup/providers/Microsoft.EventHub/namespaces/myEventHubNamespace/eventhubs/myEventHub"
"/subscriptions/a12345ea-bb21-994d-2263-c716348e32a1/resourceGroups/ProResourceGroup/providers/Microsoft.ServiceBus/namespaces/myServiceBusNamespace/topics/myTopic"

- name: Create instance in the target resource group with a system managed identity then
assign the identity to one or more scopes with a custom specified role.
text: >
az dt create -n {instance_name} -g {resouce_group} --assign-identity
--scopes
"/subscriptions/a12345ea-bb21-994d-2263-c716348e32a1/resourceGroups/ProResourceGroup/providers/Microsoft.EventHub/namespaces/myEventHubNamespace/eventhubs/myEventHub"
"/subscriptions/a12345ea-bb21-994d-2263-c716348e32a1/resourceGroups/ProResourceGroup/providers/Microsoft.ServiceBus/namespaces/myServiceBusNamespace/topics/myTopic"
--role MyCustomRole
"""

helps["dt show"] = """
Expand Down Expand Up @@ -72,9 +93,12 @@ def load_digitaltwins_help():
short-summary: Delete an existing Digital Twins instance.

examples:
- name: Delete an arbitrary instance.
- name: Delete an arbitrary instance in blocking fashion with a confirmation prompt.
text: >
az dt delete -n {instance_name}
- name: Delete an arbitrary instance with no blocking or prompt.
text: >
az dt delete -n {instance_name} -y --no-wait
"""

helps["dt endpoint"] = """
Expand Down Expand Up @@ -104,33 +128,52 @@ def load_digitaltwins_help():
helps["dt endpoint create eventhub"] = """
type: command
short-summary: Adds an EventHub endpoint to a Digital Twins instance.
Requires pre-created resource.
Requires pre-created resource. The instance must be created
with a managed identity to support identity based endpoint integration

examples:
- name: Adds an EventHub endpoint to a target instance.
- name: Adds an EventHub endpoint to a target instance using Key based auth.
text: >
az dt endpoint create eventhub --endpoint-name {endpoint_name}
--eventhub-resource-group {eventhub_resource_group}
--eventhub-namespace {eventhub_namespace}
--eventhub {eventhub_name}
--eventhub-policy {eventhub_policy}
-n {instance_name}

- name: Adds an EventHub endpoint to a target instance using Identity based auth.
text: >
az dt endpoint create eventhub --endpoint-name {endpoint_name}
--eventhub-resource-group {eventhub_resource_group}
--eventhub-namespace {eventhub_namespace}
--eventhub {eventhub_name}
--auth-type IdentityBased
-n {instance_name}
"""

helps["dt endpoint create servicebus"] = """
type: command
short-summary: Adds a ServiceBus Topic endpoint to a Digital Twins instance.
Requires pre-created resource.
Requires pre-created resource. The instance must be created
with a managed identity to support identity based endpoint integration

examples:
- name: Adds a ServiceBus Topic endpoint to a target instance.
- name: Adds a ServiceBus Topic endpoint to a target instance using Key based auth.
text: >
az dt endpoint create servicebus --endpoint-name {endpoint_name}
--servicebus-resource-group {servicebus_resource_group}
--servicebus-namespace {servicebus_namespace}
--servicebus-topic {servicebus_topic_name}
--servicebus-policy {servicebus_policy}
-n {instance_name}

- name: Adds a ServiceBus Topic endpoint to a target instance using Identity based auth.
text: >
az dt endpoint create servicebus --endpoint-name {endpoint_name}
--servicebus-resource-group {servicebus_resource_group}
--servicebus-namespace {servicebus_namespace}
--servicebus-topic {servicebus_topic_name}
-n {instance_name}
"""

helps["dt endpoint list"] = """
Expand Down Expand Up @@ -158,9 +201,101 @@ def load_digitaltwins_help():
short-summary: Remove an endpoint from a Digital Twins instance.

examples:
- name: Remove an endpoint from an instance.
- name: Remove an endpoint from an instance and block until the operation is complete.
text: >
az dt endpoint delete -n {instance_name} --endpoint-name {endpoint_name}
- name: Remove an endpoint from an instance without confirmation or blocking.
text: >
az dt endpoint delete -n {instance_name} --endpoint-name {endpoint_name} -y --no-wait
"""

helps["dt network"] = """
type: group
short-summary: Manage Digital Twins network configuration including private links and endpoint connections.
"""

helps["dt network private-link"] = """
type: group
short-summary: Manage Digital Twins instance private-link operations.
"""

helps["dt network private-link show"] = """
type: command
short-summary: Show a private-link associated with the instance.

examples:
- name: Show the private-link named "API" associated with the instance.
text: >
az dt network private-link show -n {instance_name} --link-name API
"""

helps["dt network private-link list"] = """
type: command
short-summary: List private-links associated with the Digital Twins instance.

examples:
- name: List all private-links associated with the instance.
text: >
az dt network private-link list -n {instance_name}
"""

helps["dt network private-endpoint"] = """
type: group
short-summary: Manage Digital Twins instance private-endpoints.
long-summary: Use 'az network private-endpoint create' to create a private-endpoint and link to a Digital Twins resource.
"""

helps["dt network private-endpoint connection"] = """
type: group
short-summary: Manage Digital Twins instance private-endpoint connections.
"""

helps["dt network private-endpoint connection list"] = """
type: command
short-summary: List private-endpoint connections associated with the Digital Twins instance.

examples:
- name: List all private-endpoint connections associated with the instance.
text: >
az dt network private-endpoint connection list -n {instance_name}
"""

helps["dt network private-endpoint connection show"] = """
type: command
short-summary: Show a private-endpoint connection associated with the Digital Twins instance.

examples:
- name: Show details of the private-endpoint connection named ba8408b6-1372-41b2-aef8-af43afc4729f.
text: >
az dt network private-endpoint connection show -n {instance_name} --cn ba8408b6-1372-41b2-aef8-af43afc4729f
"""

helps["dt network private-endpoint connection set"] = """
type: command
short-summary: Set the state of a private-endpoint connection associated with the Digital Twins instance.

examples:
- name: Approve a pending private-endpoint connection associated with the instance and add a description.
text: >
az dt network private-endpoint connection set -n {instance_name} --cn {connection_name} --status Approved --desc "A description."

- name: Reject a private-endpoint connection associated with the instance and add a description.
text: >
az dt network private-endpoint connection set -n {instance_name} --cn {connection_name} --status Rejected --desc "Does not comply."
"""

helps["dt network private-endpoint connection delete"] = """
type: command
short-summary: Delete a private-endpoint connection associated with the Digital Twins instance.

examples:
- name: Delete the private-endpoint connection named ba8408b6-1372-41b2-aef8-af43afc4729f with confirmation. Block until finished.
text: >
az dt network private-endpoint connection delete -n {instance_name} --cn ba8408b6-1372-41b2-aef8-af43afc4729f

- name: Delete the private-endpoint connection named ba8408b6-1372-41b2-aef8-af43afc4729f no confirmation. Return immediately.
text: >
az dt network private-endpoint connection delete -n {instance_name} --cn ba8408b6-1372-41b2-aef8-af43afc4729f -y --no-wait
"""

helps["dt role-assignment"] = """
Expand Down
35 changes: 30 additions & 5 deletions azext_iot/digitaltwins/command_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from azure.cli.core.profiles import ResourceType

"""
Load CLI commands
"""
Expand Down Expand Up @@ -39,12 +37,11 @@ def load_digitaltwins_commands(self, _):
with self.command_group(
"dt",
command_type=digitaltwins_resource_ops,
resource_type=ResourceType.MGMT_RESOURCE_RESOURCES,
) as cmd_group:
cmd_group.command("create", "create_instance")
cmd_group.show_command("show", "show_instance")
cmd_group.command("list", "list_instances")
cmd_group.command("delete", "delete_instance")
cmd_group.command("delete", "delete_instance", confirmation=True, supports_no_wait=True)

with self.command_group(
"dt endpoint", command_type=digitaltwins_resource_ops
Expand All @@ -65,7 +62,7 @@ def load_digitaltwins_commands(self, _):
"ProvisioningState:properties.provisioningState,CreatedTime:properties.createdTime}"
),
)
cmd_group.command("delete", "delete_endpoint")
cmd_group.command("delete", "delete_endpoint", confirmation=True, supports_no_wait=True)

with self.command_group(
"dt endpoint create", command_type=digitaltwins_resource_ops
Expand Down Expand Up @@ -140,3 +137,31 @@ def load_digitaltwins_commands(self, _):
)
cmd_group.command("update", "update_model")
cmd_group.command("delete", "delete_model")

with self.command_group(
"dt network",
command_type=digitaltwins_resource_ops,
) as cmd_group:
pass

with self.command_group(
"dt network private-link",
command_type=digitaltwins_resource_ops,
) as cmd_group:
cmd_group.show_command("show", "show_private_link")
cmd_group.command("list", "list_private_links")

with self.command_group(
"dt network private-endpoint",
command_type=digitaltwins_resource_ops,
) as cmd_group:
pass

with self.command_group(
"dt network private-endpoint connection",
command_type=digitaltwins_resource_ops,
) as cmd_group:
cmd_group.command("set", "set_private_endpoint_conn")
cmd_group.show_command("show", "show_private_endpoint_conn")
cmd_group.command("list", "list_private_endpoint_conns")
cmd_group.command("delete", "delete_private_endpoint_conn", confirmation=True, supports_no_wait=True)
Loading