def get_device_twin(self, central_dns_suffix): from azext_iot.common._azure import get_iot_central_tokens tokens = get_iot_central_tokens( self._cmd, self._app_id, self._token, central_dns_suffix ) exception = None # The device could be in any hub associated with the given app. # We must search through each IoT Hub until device is found. for token_group in tokens.values(): sas_token = token_group["iothubTenantSasToken"]["sasToken"] endpoint = find_between(sas_token, "SharedAccessSignature sr=", "&sig=") target = {"entity": endpoint} auth = BasicSasTokenAuthentication(sas_token=sas_token) service_sdk = SdkResolver(target=target, auth_override=auth).get_sdk( SdkType.service_sdk ) try: return service_sdk.devices.get_twin( id=self._device_id, raw=True ).response.json() except CloudError as e: if exception is None: exception = CLIError(unpack_msrest_error(e)) raise CLIError("Could not get device twin")
def update(self, twin_id, json_patch, etag=None): json_patch = process_json_arg(content=json_patch, argument_name="json-patch") json_patch_collection = [] if isinstance(json_patch, dict): json_patch_collection.append(json_patch) elif isinstance(json_patch, list): json_patch_collection.extend(json_patch) else: raise CLIError( f"--json-patch content must be an object or array. Actual type was: {type(json_patch).__name__}" ) logger.info("Patch payload %s", json.dumps(json_patch_collection)) try: options = TwinOptions(if_match=(etag if etag else "*")) self.twins_sdk.update(id=twin_id, patch_document=json_patch_collection, digital_twins_update_options=options, raw=True) return self.get(twin_id=twin_id) except ErrorResponseException as e: raise CLIError(unpack_msrest_error(e))
def get(self, id, get_definition=False): try: return self.model_sdk.get_by_id( id=id, include_model_definition=get_definition, raw=True).response.json() except ErrorResponseException as e: raise CLIError(unpack_msrest_error(e))
def add_relationship( self, twin_id, target_twin_id, relationship_id, relationship, replace=False, properties=None, ): relationship_request = { "$targetId": target_twin_id, "$relationshipName": relationship, } if properties: properties = process_json_arg(content=properties, argument_name="properties") relationship_request.update(properties) logger.info("Relationship payload %s", json.dumps(relationship_request)) try: options = TwinOptions(if_none_match=(None if replace else "*")) return self.twins_sdk.add_relationship( id=twin_id, relationship_id=relationship_id, relationship=relationship_request, digital_twins_add_relationship_options=options, raw=True, ).response.json() except ErrorResponseException as e: raise CLIError(unpack_msrest_error(e))
def iot_digitaltwin_invoke_command(cmd, interface, device_id, command_name, command_payload=None, timeout=10, hub_name=None, resource_group_name=None, login=None): device_interfaces = _iot_digitaltwin_interface_list(cmd, device_id, hub_name, resource_group_name, login) interface_list = _get_device_default_interface_dict(device_interfaces) target_interface = next((item for item in interface_list if item['name'] == interface), None) if not target_interface: raise CLIError('Target interface is not implemented by the device!') if command_payload: if exists(command_payload): command_payload = str(read_file_content(command_payload)) target_json = None try: target_json = shell_safe_json_parse(command_payload) except ValueError: pass if target_json or isinstance(target_json, bool): command_payload = target_json target = get_iot_hub_connection_string(cmd, hub_name, resource_group_name, login=login) service_sdk, errors = _bind_sdk(target, SdkType.service_sdk) try: result = service_sdk.invoke_interface_command(device_id, interface, command_name, command_payload, connect_timeout_in_seconds=timeout, response_timeout_in_seconds=timeout) return result except errors.CloudError as e: raise CLIError(unpack_msrest_error(e))
def delete_relationship(self, twin_id, relationship_id): try: self.twins_sdk.delete_relationship(id=twin_id, relationship_id=relationship_id, if_match="*") except ErrorResponseException as e: raise CLIError(unpack_msrest_error(e))
def list_by_resouce_group(self, resource_group_name): try: return self.mgmt_sdk.digital_twins.list_by_resource_group( resource_group_name=resource_group_name ) except ErrorResponseException as e: raise CLIError(unpack_msrest_error(e))
def get_relationship(self, twin_id, relationship_id): try: return self.twins_sdk.get_relationship_by_id( id=twin_id, relationship_id=relationship_id, raw=True).response.json() except ErrorResponseException as e: raise CLIError(unpack_msrest_error(e))
def set_private_endpoint_conn( self, name, conn_name, status, description, actions_required=None, group_ids=None, resource_group_name=None, ): target_instance = self.find_instance( name=name, resource_group_name=resource_group_name ) if not resource_group_name: resource_group_name = self.get_rg(target_instance) try: return self.mgmt_sdk.private_endpoint_connections.create_or_update( resource_group_name=resource_group_name, resource_name=name, private_endpoint_connection_name=conn_name, properties={ "privateLinkServiceConnectionState": { "status": status, "description": description, "actions_required": actions_required, }, "groupIds": group_ids, }, ) except ErrorResponseException as e: raise CLIError(unpack_msrest_error(e))
def get_model(self, model_id, expand=False): try: return self.mgmt_sdk.get_model_async(model_id=model_id, expand=expand, raw=True).response.json() except CloudError as e: raise CLIError(unpack_msrest_error(e))
def update_relationship(self, twin_id, relationship_id, json_patch, etag=None): json_patch = process_json_arg(content=json_patch, argument_name="json-patch") json_patch_collection = [] if isinstance(json_patch, dict): json_patch_collection.append(json_patch) if isinstance(json_patch, list): json_patch_collection.extend(json_patch) logger.info("Patch payload %s", json.dumps(json_patch_collection)) try: options = TwinOptions(if_match=(etag if etag else "*")) self.twins_sdk.update_relationship( id=twin_id, relationship_id=relationship_id, patch_document=json_patch_collection, digital_twins_update_relationship_options=options, ) return self.get_relationship(twin_id=twin_id, relationship_id=relationship_id) except ErrorResponseException as e: raise CLIError(unpack_msrest_error(e))
def get_component(self, twin_id, component_path): try: return self.twins_sdk.get_component(id=twin_id, component_path=component_path, raw=True).response.json() except ErrorResponseException as e: raise CLIError(unpack_msrest_error(e))
def device_twin_show(cmd, device_id, app_id, central_dns_suffix="azureiotcentral.com"): from azext_iot.common._azure import get_iot_central_tokens tokens = get_iot_central_tokens(cmd, app_id, central_dns_suffix) exception = None # The device could be in any hub associated with the given app. # We must search through each IoT Hub until device is found. for token_group in tokens.values(): sas_token = token_group["iothubTenantSasToken"]["sasToken"] endpoint = find_between(sas_token, "SharedAccessSignature sr=", "&sig=") target = {"entity": endpoint} auth = BasicSasTokenAuthentication(sas_token=sas_token) service_sdk, errors = _bind_sdk(target, SdkType.service_sdk, auth=auth) try: return service_sdk.get_twin(device_id) except errors.CloudError as e: if exception is None: exception = CLIError(unpack_msrest_error(e)) raise exception
def list_relationships(self, twin_id, incoming_relationships=False, relationship=None): if not incoming_relationships: return self.twins_sdk.list_relationships( id=twin_id, relationship_name=relationship) incoming_pager = self.twins_sdk.list_incoming_relationships(id=twin_id) incoming_result = [] try: while True: incoming_result.extend(incoming_pager.advance_page()) except StopIteration: pass except ErrorResponseException as e: raise CLIError(unpack_msrest_error(e)) if relationship: incoming_result = [ edge for edge in incoming_result if edge.relationship_name and edge.relationship_name == relationship ] return incoming_result
def get(self, name, resource_group_name): try: return self.mgmt_sdk.digital_twins.get( resource_name=name, resource_group_name=resource_group_name ) except ErrorResponseException as e: raise CLIError(unpack_msrest_error(e))
def create(self, name, resource_group_name, location=None, tags=None, timeout=20): if tags: tags = validate_key_value_pairs(tags) if not location: from azext_iot.common.embedded_cli import EmbeddedCLI resource_group_meta = EmbeddedCLI().invoke( "group show --name {}".format(resource_group_name)).as_json() location = resource_group_meta["location"] try: return self.mgmt_sdk.digital_twins.create_or_update( resource_name=name, resource_group_name=resource_group_name, location=location, tags=tags, long_running_operation_timeout=timeout, ) except CloudError as e: raise e except ErrorResponseException as err: raise CLIError(unpack_msrest_error(err))
def _device_interface_elements(cmd, device_id, interface, target_type, hub_name, resource_group_name, login): target = get_iot_hub_connection_string(cmd, hub_name, resource_group_name, login=login) service_sdk, errors = _bind_sdk(target, SdkType.service_sdk) interface_elements = [] try: payload = {'id': {}} payload['id'] = interface target_payload = shell_safe_json_parse(str(payload)) interface_def = service_sdk.invoke_interface_command( device_id, INTERFACE_MODELDEFINITION, INTERFACE_COMMANDNAME, target_payload) if interface_def and interface_def.get('contents'): interface_contents = interface_def.get('contents') for content in interface_contents: if isinstance(content.get('@type'), list) and target_type in content.get('@type'): interface_elements.append(content) elif content.get('@type') == target_type: interface_elements.append(content) return interface_elements except errors.CloudError as e: raise CLIError(unpack_msrest_error(e)) except Exception: # pylint: disable=broad-except # returning an empty collection to continue return []
def iot_digitaltwin_property_update(cmd, interface_payload, device_id, hub_name=None, resource_group_name=None, login=None): if exists(interface_payload): interface_payload = str(read_file_content(interface_payload)) target_json = None try: target_json = shell_safe_json_parse(interface_payload) except ValueError: pass if target_json: interface_payload = target_json target = get_iot_hub_connection_string(cmd, hub_name, resource_group_name, login=login) service_sdk, errors = _bind_sdk(target, SdkType.service_sdk) try: result = service_sdk.update_interfaces(device_id, interfaces=interface_payload) return result except errors.CloudError as e: raise CLIError(unpack_msrest_error(e))
def find_instance(self, name, resource_group_name=None): if resource_group_name: try: return self.get(name=name, resource_group_name=resource_group_name) except ErrorResponseException as e: raise CLIError(unpack_msrest_error(e)) dt_collection_pager = self.list() dt_collection = [] try: while True: dt_collection.extend(dt_collection_pager.advance_page()) except StopIteration: pass compare_name = name.lower() filter_result = [ instance for instance in dt_collection if instance.name.lower() == compare_name ] if filter_result: if len(filter_result) > 1: raise CLIError( "Ambiguous DT instance name. Please include the DT instance resource group." ) return filter_result[0] raise CLIError( "DT instance: '{}' not found by auto-discovery. " "Provide resource group via -g for direct lookup.".format(name) )
def _device_interface_elements(cmd, device_id, interface, target_type, hub_name, resource_group_name, login): discovery = IotHubDiscovery(cmd) target = discovery.get_target(hub_name=hub_name, resource_group_name=resource_group_name, login=login) service_sdk, errors = _bind_sdk(target, SdkType.service_sdk) interface_elements = [] try: payload = {"id": {}} payload["id"] = interface target_payload = shell_safe_json_parse(str(payload)) interface_def = service_sdk.invoke_interface_command( device_id, INTERFACE_MODELDEFINITION, INTERFACE_COMMANDNAME, target_payload) if interface_def and interface_def.get("contents"): interface_contents = interface_def.get("contents") for content in interface_contents: if isinstance(content.get("@type"), list) and target_type in content.get("@type"): interface_elements.append(content) elif content.get("@type") == target_type: interface_elements.append(content) return interface_elements except errors.CloudError as e: raise CLIError(unpack_msrest_error(e)) except Exception: # returning an empty collection to continue return []
def delete(self, twin_id, etag=None): try: options = TwinOptions(if_match=(etag if etag else "*")) self.twins_sdk.delete(id=twin_id, digital_twins_delete_options=options, raw=True) except ErrorResponseException as e: raise CLIError(unpack_msrest_error(e))
def get_role_assignments_for_resource(self, resource_id, resource_type): try: return self.mgmt_sdk.get_subjects_for_resources_async( resource_id=resource_id, resource_type=resource_type, ) except CloudError as e: raise CLIError(unpack_msrest_error(e))
def validate_models(self, models=None, validate_dependencies=None): try: return self.mgmt_sdk.are_valid_models( json_ld_models=models, validate_dependencies=validate_dependencies, ) except CloudError as e: raise CLIError(unpack_msrest_error(e))
def _iot_digitaltwin_interface_list(cmd, device_id, hub_name=None, resource_group_name=None, login=None): target = get_iot_hub_connection_string(cmd, hub_name, resource_group_name, login=login) service_sdk, errors = _bind_sdk(target, SdkType.service_sdk) try: device_interfaces = service_sdk.get_interfaces(device_id) return device_interfaces except errors.CloudError as e: raise CLIError(unpack_msrest_error(e))
def _cancel(self, job_id, job_version=JobVersionType.v2): service_sdk = self.get_sdk(SdkType.service_sdk) try: if job_version == JobVersionType.v2: return service_sdk.jobs.cancel_scheduled_job(id=job_id, raw=True).response.json() return service_sdk.jobs.cancel_import_export_job(id=job_id) except CloudError as e: raise CLIError(unpack_msrest_error(e))
def list(self, top=None): # top is guarded for int() in arg def from azext_iot.sdk.digitaltwins.dataplane.models import EventRoutesListOptions list_options = EventRoutesListOptions(max_item_count=top) try: return self.sdk.list(event_routes_list_options=list_options, ) except ErrorResponseException as e: raise CLIError(unpack_msrest_error(e))
def get(self, name, resource_group_name, wait=False): try: return self.mgmt_sdk.digital_twins.get( resource_name=name, resource_group_name=resource_group_name) except ErrorResponseException as e: if wait: e.status_code = e.response.status_code raise e raise CLIError(unpack_msrest_error(e))
def iot_central_device_show(cmd, device_id, app_id): sasToken = get_iot_hub_token_from_central_app_id(cmd, app_id) endpoint = find_between(sasToken, 'SharedAccessSignature sr=', '&sig=') target = {'entity': endpoint} auth = BasicSasTokenAuthentication(sas_token=sasToken) service_sdk, errors = _bind_sdk(target, SdkType.service_sdk, auth=auth) try: return service_sdk.get_twin(device_id) except errors.CloudError as e: raise CLIError(unpack_msrest_error(e))
def _get(self, job_id, job_version=JobVersionType.v2): service_sdk = self.get_sdk(SdkType.service_sdk) try: if job_version == JobVersionType.v2: return service_sdk.job_client.get_job( id=job_id, raw=True).response.json() return self._convert_v1_to_v2( service_sdk.job_client.get_import_export_job(id=job_id)) except CloudError as e: raise CLIError(unpack_msrest_error(e))
def remove_role_assignment(self, resource_id, resource_type, role_id, subject_id): try: return self.mgmt_sdk.remove_roles_async( resource_id=resource_id, resource_type=resource_type, subject_id=subject_id, role_id=role_id, ) except CloudError as e: raise CLIError(unpack_msrest_error(e))