diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/CHANGELOG.md b/sdk/deviceupdate/azure-iot-deviceupdate/CHANGELOG.md new file mode 100644 index 000000000000..ba5076b28684 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/CHANGELOG.md @@ -0,0 +1,4 @@ +# Release History + +## 1.0.0b1 (2021-03-03) +* This is the initial release of Azure Device Update for IoT Hub library. diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/MANIFEST.in b/sdk/deviceupdate/azure-iot-deviceupdate/MANIFEST.in new file mode 100644 index 000000000000..37bb3f57ad82 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/MANIFEST.in @@ -0,0 +1,5 @@ +recursive-include tests *.py +recursive-include samples *.py *.md +include *.md +include azure/__init__.py +include azure/iot/__init__.py \ No newline at end of file diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/README.md b/sdk/deviceupdate/azure-iot-deviceupdate/README.md new file mode 100644 index 000000000000..7b239d722fd6 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/README.md @@ -0,0 +1,51 @@ +# Azure Device Update for IoT Hub client library for Python + +The library provides access to the Device Update for IoT Hub service that enables customers to publish updates for their IoT devices to the cloud, and then deploy these updates to their devices (approve updates to groups of devices managed and provisioned in IoT Hub). + +[Source code](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/deviceupdate/azure-iot-deviceupdate) | [Package (PyPI)](https://aka.ms/azsdk/python/deviceupdate-pypi) | [Product documentation](https://docs.microsoft.com/azure/iot-hub-device-update/understand-device-update) + +## Getting started + +### Prerequisites + +- Microsoft Azure Subscription: To call Microsoft Azure services, you need to create an [Azure subscription](https://azure.microsoft.com/free/) +- Device Update for IoT Hub instance +- Azure IoT Hub instance +- Python 2.7, or 3.6 or later is required to use this package. + +### Install the package + +Install the Device Update for IoT Hub client library for Python with [pip](https://pypi.org/project/pip/): + +```bash +pip install azure-iot-deviceupdate --pre +``` + +## Key concepts + +Device Update for IoT Hub is a managed service that enables you to deploy over-the-air updates for your IoT devices. The client library has one main component named **AzureDeviceUpdateServiceDataPlane**. The component allows you to access all three main client services: + +- **UpdatesOperations**: update management (import, enumerate, delete, etc.) +- **DevicesOperations**: device management (enumerate devices and retrieve device properties) +- **DeploymentsOperations**: deployment management (start and monitor update deployments to a set of devices) + +You can learn more about Device Update for IoT Hub by visiting [Device Update for IoT Hub](https://github.com/azure/iot-hub-device-update). + +## Examples + +You can familiarize yourself with different APIs using [Samples](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/deviceupdate/azure-iot-deviceupdate/samples). + +## Troubleshooting + +The Device Update for IoT Hub client will raise exceptions defined in [Azure Core][https://github.com/azure/azure-sdk-for-python/blob/master/sdk/core/azure-core/readme.md]. + +## Next steps + +Get started with our [Device Update for IoT Hub samples](https://github.com/Azure/azure-sdk-for-python/tree/master/sdk/deviceupdate/azure-iot-deviceupdate/samples) + +## Contributing + +If you encounter any bugs or have suggestions, please file an issue in the [Issues](https://github.com/Azure/azure-sdk-for-python/issues) section of the project. + + +[azure_core]: https://github.com/Azure/azure-sdk-for-python/blob/master/sdk/core/azure-core/README.md diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/__init__.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/__init__.py new file mode 100644 index 000000000000..5960c353a898 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/__init__.py @@ -0,0 +1 @@ +__path__ = __import__('pkgutil').extend_path(__path__, __name__) # type: ignore \ No newline at end of file diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/__init__.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/__init__.py new file mode 100644 index 000000000000..5960c353a898 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/__init__.py @@ -0,0 +1 @@ +__path__ = __import__('pkgutil').extend_path(__path__, __name__) # type: ignore \ No newline at end of file diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/__init__.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/__init__.py new file mode 100644 index 000000000000..7c47c872e729 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/__init__.py @@ -0,0 +1,19 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._device_update_client import DeviceUpdateClient +from ._version import VERSION + +__version__ = VERSION +__all__ = ['DeviceUpdateClient'] + +try: + from ._patch import patch_sdk # type: ignore + patch_sdk() +except ImportError: + pass diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/_configuration.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/_configuration.py new file mode 100644 index 000000000000..89bdf03b2382 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/_configuration.py @@ -0,0 +1,75 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import TYPE_CHECKING + +from azure.core.configuration import Configuration +from azure.core.pipeline import policies + +from ._version import VERSION + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any + + from azure.core.credentials import TokenCredential + + +class DeviceUpdateClientConfiguration(Configuration): + """Configuration for DeviceUpdateClient. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials.TokenCredential + :param account_endpoint: Account endpoint. + :type account_endpoint: str + :param instance_id: Account instance identifier. + :type instance_id: str + """ + + def __init__( + self, + credential, # type: "TokenCredential" + account_endpoint, # type: str + instance_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + if account_endpoint is None: + raise ValueError("Parameter 'account_endpoint' must not be None.") + if instance_id is None: + raise ValueError("Parameter 'instance_id' must not be None.") + super(DeviceUpdateClientConfiguration, self).__init__(**kwargs) + + self.credential = credential + self.account_endpoint = account_endpoint + self.instance_id = instance_id + self.credential_scopes = kwargs.pop('credential_scopes', ['https://api.adu.microsoft.com/.default']) + kwargs.setdefault('sdk_moniker', 'iot-deviceupdate/{}'.format(VERSION)) + self._configure(**kwargs) + + def _configure( + self, + **kwargs # type: Any + ): + # type: (...) -> None + self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) + self.retry_policy = kwargs.get('retry_policy') or policies.RetryPolicy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get('redirect_policy') or policies.RedirectPolicy(**kwargs) + self.authentication_policy = kwargs.get('authentication_policy') + if self.credential and not self.authentication_policy: + self.authentication_policy = policies.BearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/_device_update_client.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/_device_update_client.py new file mode 100644 index 000000000000..bf28a639fe9d --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/_device_update_client.py @@ -0,0 +1,99 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import TYPE_CHECKING + +from azure.core import PipelineClient +from msrest import Deserializer, Serializer + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any + + from azure.core.credentials import TokenCredential + from azure.core.pipeline.transport import HttpRequest, HttpResponse + +from ._configuration import DeviceUpdateClientConfiguration +from .operations import UpdatesOperations +from .operations import DevicesOperations +from .operations import DeploymentsOperations +from . import models + + +class DeviceUpdateClient(object): + """Device Update for IoT Hub is an Azure service that enables customers to publish update for their IoT devices to the cloud, and then deploy that update to their devices (approve updates to groups of devices managed and provisioned in IoT Hub). It leverages the proven security and reliability of the Windows Update platform, optimized for IoT devices. It works globally and knows when and how to update devices, enabling customers to focus on their business goals and let Device Update for IoT Hub handle the updates. + + :ivar updates: UpdatesOperations operations + :vartype updates: azure.iot.deviceupdate.operations.UpdatesOperations + :ivar devices: DevicesOperations operations + :vartype devices: azure.iot.deviceupdate.operations.DevicesOperations + :ivar deployments: DeploymentsOperations operations + :vartype deployments: azure.iot.deviceupdate.operations.DeploymentsOperations + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials.TokenCredential + :param account_endpoint: Account endpoint. + :type account_endpoint: str + :param instance_id: Account instance identifier. + :type instance_id: str + """ + + def __init__( + self, + credential, # type: "TokenCredential" + account_endpoint, # type: str + instance_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + base_url = 'https://{accountEndpoint}' + self._config = DeviceUpdateClientConfiguration(credential, account_endpoint, instance_id, **kwargs) + self._client = PipelineClient(base_url=base_url, config=self._config, **kwargs) + + client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} + self._serialize = Serializer(client_models) + self._serialize.client_side_validation = False + self._deserialize = Deserializer(client_models) + + self.updates = UpdatesOperations( + self._client, self._config, self._serialize, self._deserialize) + self.devices = DevicesOperations( + self._client, self._config, self._serialize, self._deserialize) + self.deployments = DeploymentsOperations( + self._client, self._config, self._serialize, self._deserialize) + + def _send_request(self, http_request, **kwargs): + # type: (HttpRequest, Any) -> HttpResponse + """Runs the network request through the client's chained policies. + + :param http_request: The network request you want to make. Required. + :type http_request: ~azure.core.pipeline.transport.HttpRequest + :keyword bool stream: Whether the response payload will be streamed. Defaults to True. + :return: The response of your network call. Does not do error handling on your response. + :rtype: ~azure.core.pipeline.transport.HttpResponse + """ + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + http_request.url = self._client.format_url(http_request.url, **path_format_arguments) + stream = kwargs.pop("stream", True) + pipeline_response = self._client._pipeline.run(http_request, stream=stream, **kwargs) + return pipeline_response.http_response + + def close(self): + # type: () -> None + self._client.close() + + def __enter__(self): + # type: () -> DeviceUpdateClient + self._client.__enter__() + return self + + def __exit__(self, *exc_details): + # type: (Any) -> None + self._client.__exit__(*exc_details) diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/_version.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/_version.py new file mode 100644 index 000000000000..e5754a47ce68 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/_version.py @@ -0,0 +1,9 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +VERSION = "1.0.0b1" diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/__init__.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/__init__.py new file mode 100644 index 000000000000..545c2b6dad82 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/__init__.py @@ -0,0 +1,10 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._device_update_client import DeviceUpdateClient +__all__ = ['DeviceUpdateClient'] diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/_configuration.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/_configuration.py new file mode 100644 index 000000000000..8849abd2c07c --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/_configuration.py @@ -0,0 +1,71 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import Any, TYPE_CHECKING + +from azure.core.configuration import Configuration +from azure.core.pipeline import policies + +from .._version import VERSION + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core.credentials_async import AsyncTokenCredential + + +class DeviceUpdateClientConfiguration(Configuration): + """Configuration for DeviceUpdateClient. + + Note that all parameters used to create this instance are saved as instance + attributes. + + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials_async.AsyncTokenCredential + :param account_endpoint: Account endpoint. + :type account_endpoint: str + :param instance_id: Account instance identifier. + :type instance_id: str + """ + + def __init__( + self, + credential: "AsyncTokenCredential", + account_endpoint: str, + instance_id: str, + **kwargs: Any + ) -> None: + if credential is None: + raise ValueError("Parameter 'credential' must not be None.") + if account_endpoint is None: + raise ValueError("Parameter 'account_endpoint' must not be None.") + if instance_id is None: + raise ValueError("Parameter 'instance_id' must not be None.") + super(DeviceUpdateClientConfiguration, self).__init__(**kwargs) + + self.credential = credential + self.account_endpoint = account_endpoint + self.instance_id = instance_id + self.credential_scopes = kwargs.pop('credential_scopes', ['https://api.adu.microsoft.com/.default']) + kwargs.setdefault('sdk_moniker', 'iot-deviceupdate/{}'.format(VERSION)) + self._configure(**kwargs) + + def _configure( + self, + **kwargs: Any + ) -> None: + self.user_agent_policy = kwargs.get('user_agent_policy') or policies.UserAgentPolicy(**kwargs) + self.headers_policy = kwargs.get('headers_policy') or policies.HeadersPolicy(**kwargs) + self.proxy_policy = kwargs.get('proxy_policy') or policies.ProxyPolicy(**kwargs) + self.logging_policy = kwargs.get('logging_policy') or policies.NetworkTraceLoggingPolicy(**kwargs) + self.http_logging_policy = kwargs.get('http_logging_policy') or policies.HttpLoggingPolicy(**kwargs) + self.retry_policy = kwargs.get('retry_policy') or policies.AsyncRetryPolicy(**kwargs) + self.custom_hook_policy = kwargs.get('custom_hook_policy') or policies.CustomHookPolicy(**kwargs) + self.redirect_policy = kwargs.get('redirect_policy') or policies.AsyncRedirectPolicy(**kwargs) + self.authentication_policy = kwargs.get('authentication_policy') + if self.credential and not self.authentication_policy: + self.authentication_policy = policies.AsyncBearerTokenCredentialPolicy(self.credential, *self.credential_scopes, **kwargs) diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/_device_update_client.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/_device_update_client.py new file mode 100644 index 000000000000..8971936d5700 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/_device_update_client.py @@ -0,0 +1,92 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from typing import Any, TYPE_CHECKING + +from azure.core import AsyncPipelineClient +from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest +from msrest import Deserializer, Serializer + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from azure.core.credentials_async import AsyncTokenCredential + +from ._configuration import DeviceUpdateClientConfiguration +from .operations import UpdatesOperations +from .operations import DevicesOperations +from .operations import DeploymentsOperations +from .. import models + + +class DeviceUpdateClient(object): + """Device Update for IoT Hub is an Azure service that enables customers to publish update for their IoT devices to the cloud, and then deploy that update to their devices (approve updates to groups of devices managed and provisioned in IoT Hub). It leverages the proven security and reliability of the Windows Update platform, optimized for IoT devices. It works globally and knows when and how to update devices, enabling customers to focus on their business goals and let Device Update for IoT Hub handle the updates. + + :ivar updates: UpdatesOperations operations + :vartype updates: azure.iot.deviceupdate.aio.operations.UpdatesOperations + :ivar devices: DevicesOperations operations + :vartype devices: azure.iot.deviceupdate.aio.operations.DevicesOperations + :ivar deployments: DeploymentsOperations operations + :vartype deployments: azure.iot.deviceupdate.aio.operations.DeploymentsOperations + :param credential: Credential needed for the client to connect to Azure. + :type credential: ~azure.core.credentials_async.AsyncTokenCredential + :param account_endpoint: Account endpoint. + :type account_endpoint: str + :param instance_id: Account instance identifier. + :type instance_id: str + """ + + def __init__( + self, + credential: "AsyncTokenCredential", + account_endpoint: str, + instance_id: str, + **kwargs: Any + ) -> None: + base_url = 'https://{accountEndpoint}' + self._config = DeviceUpdateClientConfiguration(credential, account_endpoint, instance_id, **kwargs) + self._client = AsyncPipelineClient(base_url=base_url, config=self._config, **kwargs) + + client_models = {k: v for k, v in models.__dict__.items() if isinstance(v, type)} + self._serialize = Serializer(client_models) + self._serialize.client_side_validation = False + self._deserialize = Deserializer(client_models) + + self.updates = UpdatesOperations( + self._client, self._config, self._serialize, self._deserialize) + self.devices = DevicesOperations( + self._client, self._config, self._serialize, self._deserialize) + self.deployments = DeploymentsOperations( + self._client, self._config, self._serialize, self._deserialize) + + async def _send_request(self, http_request: HttpRequest, **kwargs: Any) -> AsyncHttpResponse: + """Runs the network request through the client's chained policies. + + :param http_request: The network request you want to make. Required. + :type http_request: ~azure.core.pipeline.transport.HttpRequest + :keyword bool stream: Whether the response payload will be streamed. Defaults to True. + :return: The response of your network call. Does not do error handling on your response. + :rtype: ~azure.core.pipeline.transport.AsyncHttpResponse + """ + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + http_request.url = self._client.format_url(http_request.url, **path_format_arguments) + stream = kwargs.pop("stream", True) + pipeline_response = await self._client._pipeline.run(http_request, stream=stream, **kwargs) + return pipeline_response.http_response + + async def close(self) -> None: + await self._client.close() + + async def __aenter__(self) -> "DeviceUpdateClient": + await self._client.__aenter__() + return self + + async def __aexit__(self, *exc_details) -> None: + await self._client.__aexit__(*exc_details) diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/operations/__init__.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/operations/__init__.py new file mode 100644 index 000000000000..0bb67dd3a9fe --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/operations/__init__.py @@ -0,0 +1,17 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._updates_operations import UpdatesOperations +from ._devices_operations import DevicesOperations +from ._deployments_operations import DeploymentsOperations + +__all__ = [ + 'UpdatesOperations', + 'DevicesOperations', + 'DeploymentsOperations', +] diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/operations/_deployments_operations.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/operations/_deployments_operations.py new file mode 100644 index 000000000000..3935c35e398c --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/operations/_deployments_operations.py @@ -0,0 +1,525 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import Any, AsyncIterable, Callable, Dict, Generic, Optional, TypeVar +import warnings + +from azure.core.async_paging import AsyncItemPaged, AsyncList +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest + +from ... import models as _models + +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + +class DeploymentsOperations: + """DeploymentsOperations async operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.iot.deviceupdate.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = _models + + def __init__(self, client, config, serializer, deserializer) -> None: + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def get_all_deployments( + self, + filter: Optional[str] = None, + **kwargs + ) -> AsyncIterable["_models.PageableListOfDeployments"]: + """Gets a list of deployments. + + :param filter: Restricts the set of deployments returned. You can filter on update Provider, + Name and Version property. + :type filter: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfDeployments or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.iot.deviceupdate.models.PageableListOfDeployments] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfDeployments"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_all_deployments.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + if filter is not None: + query_parameters['$filter'] = self._serialize.query("filter", filter, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfDeployments', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + get_all_deployments.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments'} # type: ignore + + async def get_deployment( + self, + deployment_id: str, + **kwargs + ) -> "_models.Deployment": + """Gets the properties of a deployment. + + :param deployment_id: Deployment identifier. + :type deployment_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Deployment, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Deployment + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.Deployment"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_deployment.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('Deployment', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_deployment.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments/{deploymentId}'} # type: ignore + + async def create_or_update_deployment( + self, + deployment_id: str, + deployment: "_models.Deployment", + **kwargs + ) -> "_models.Deployment": + """Creates or updates a deployment. + + :param deployment_id: Deployment identifier. + :type deployment_id: str + :param deployment: The deployment properties. + :type deployment: ~azure.iot.deviceupdate.models.Deployment + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Deployment, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Deployment + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.Deployment"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self.create_or_update_deployment.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(deployment, 'Deployment') + body_content_kwargs['content'] = body_content + request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('Deployment', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + create_or_update_deployment.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments/{deploymentId}'} # type: ignore + + async def delete_deployment( + self, + deployment_id: str, + **kwargs + ) -> None: + """Deletes a deployment. + + :param deployment_id: Deployment identifier. + :type deployment_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: None, or the result of cls(response) + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + # Construct URL + url = self.delete_deployment.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + delete_deployment.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments/{deploymentId}'} # type: ignore + + async def get_deployment_status( + self, + deployment_id: str, + **kwargs + ) -> "_models.DeploymentStatus": + """Gets the status of a deployment including a breakdown of how many devices in the deployment are + in progress, completed, or failed. + + :param deployment_id: Deployment identifier. + :type deployment_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: DeploymentStatus, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.DeploymentStatus + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.DeploymentStatus"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_deployment_status.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('DeploymentStatus', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_deployment_status.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments/{deploymentId}/status'} # type: ignore + + def get_deployment_devices( + self, + deployment_id: str, + filter: Optional[str] = None, + **kwargs + ) -> AsyncIterable["_models.PageableListOfDeploymentDeviceStates"]: + """Gets a list of devices in a deployment along with their state. Useful for getting a list of + failed devices. + + :param deployment_id: Deployment identifier. + :type deployment_id: str + :param filter: Restricts the set of deployment device states returned. You can filter on + deviceId and/or deviceState. + :type filter: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfDeploymentDeviceStates or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.iot.deviceupdate.models.PageableListOfDeploymentDeviceStates] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfDeploymentDeviceStates"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_deployment_devices.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + if filter is not None: + query_parameters['$filter'] = self._serialize.query("filter", filter, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfDeploymentDeviceStates', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + get_deployment_devices.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments/{deploymentId}/devicestates'} # type: ignore + + async def cancel_deployment( + self, + deployment_id: str, + **kwargs + ) -> "_models.Deployment": + """Cancels a deployment. + + :param deployment_id: Deployment identifier. + :type deployment_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Deployment, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Deployment + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.Deployment"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + action = "cancel" + accept = "application/json" + + # Construct URL + url = self.cancel_deployment.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['action'] = self._serialize.query("action", action, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.post(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('Deployment', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + cancel_deployment.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments/{deploymentId}'} # type: ignore + + async def retry_deployment( + self, + deployment_id: str, + **kwargs + ) -> "_models.Deployment": + """Retries a deployment with failed devices. + + :param deployment_id: Deployment identifier. + :type deployment_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Deployment, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Deployment + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.Deployment"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + action = "retry" + accept = "application/json" + + # Construct URL + url = self.retry_deployment.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['action'] = self._serialize.query("action", action, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.post(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('Deployment', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + retry_deployment.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments/{deploymentId}'} # type: ignore diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/operations/_devices_operations.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/operations/_devices_operations.py new file mode 100644 index 000000000000..c218f4f9a0d2 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/operations/_devices_operations.py @@ -0,0 +1,985 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import Any, AsyncIterable, Callable, Dict, Generic, Optional, TypeVar +import warnings + +from azure.core.async_paging import AsyncItemPaged, AsyncList +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest + +from ... import models as _models + +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + +class DevicesOperations: + """DevicesOperations async operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.iot.deviceupdate.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = _models + + def __init__(self, client, config, serializer, deserializer) -> None: + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def get_all_device_classes( + self, + **kwargs + ) -> AsyncIterable["_models.PageableListOfDeviceClasses"]: + """Gets a list of all device classes (unique combinations of device manufacturer and model) for + all devices connected to Device Update for IoT Hub. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfDeviceClasses or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.iot.deviceupdate.models.PageableListOfDeviceClasses] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfDeviceClasses"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_all_device_classes.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfDeviceClasses', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + get_all_device_classes.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deviceclasses'} # type: ignore + + async def get_device_class( + self, + device_class_id: str, + **kwargs + ) -> "_models.DeviceClass": + """Gets the properties of a device class. + + :param device_class_id: Device class identifier. + :type device_class_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: DeviceClass, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.DeviceClass + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.DeviceClass"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_device_class.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deviceClassId': self._serialize.url("device_class_id", device_class_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('DeviceClass', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_device_class.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deviceclasses/{deviceClassId}'} # type: ignore + + def get_device_class_device_ids( + self, + device_class_id: str, + **kwargs + ) -> AsyncIterable["_models.PageableListOfStrings"]: + """Gets a list of device identifiers in a device class. + + :param device_class_id: Device class identifier. + :type device_class_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfStrings or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.iot.deviceupdate.models.PageableListOfStrings] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfStrings"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_device_class_device_ids.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deviceClassId': self._serialize.url("device_class_id", device_class_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deviceClassId': self._serialize.url("device_class_id", device_class_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfStrings', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + get_device_class_device_ids.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deviceclasses/{deviceClassId}/deviceids'} # type: ignore + + def get_device_class_installable_updates( + self, + device_class_id: str, + **kwargs + ) -> AsyncIterable["_models.PageableListOfUpdateIds"]: + """Gets a list of installable updates for a device class. + + :param device_class_id: Device class identifier. + :type device_class_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfUpdateIds or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.iot.deviceupdate.models.PageableListOfUpdateIds] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfUpdateIds"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_device_class_installable_updates.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deviceClassId': self._serialize.url("device_class_id", device_class_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deviceClassId': self._serialize.url("device_class_id", device_class_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfUpdateIds', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + get_device_class_installable_updates.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deviceclasses/{deviceClassId}/installableupdates'} # type: ignore + + def get_all_devices( + self, + filter: Optional[str] = None, + **kwargs + ) -> AsyncIterable["_models.PageableListOfDevices"]: + """Gets a list of devices connected to Device Update for IoT Hub. + + :param filter: Restricts the set of devices returned. You can only filter on device GroupId. + :type filter: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfDevices or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.iot.deviceupdate.models.PageableListOfDevices] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfDevices"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_all_devices.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + if filter is not None: + query_parameters['$filter'] = self._serialize.query("filter", filter, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfDevices', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + get_all_devices.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/devices'} # type: ignore + + async def get_device( + self, + device_id: str, + **kwargs + ) -> "_models.Device": + """Gets the device properties and latest deployment status for a device connected to Device Update + for IoT Hub. + + :param device_id: Device identifier in Azure IOT Hub. + :type device_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Device, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Device + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.Device"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_device.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deviceId': self._serialize.url("device_id", device_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('Device', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_device.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/devices/{deviceId}'} # type: ignore + + async def get_update_compliance( + self, + **kwargs + ) -> "_models.UpdateCompliance": + """Gets the breakdown of how many devices are on their latest update, have new updates available, + or are in progress receiving new updates. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: UpdateCompliance, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.UpdateCompliance + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.UpdateCompliance"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_update_compliance.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('UpdateCompliance', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_update_compliance.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/updatecompliance'} # type: ignore + + def get_all_device_tags( + self, + **kwargs + ) -> AsyncIterable["_models.PageableListOfDeviceTags"]: + """Gets a list of available group device tags for all devices connected to Device Update for IoT + Hub. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfDeviceTags or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.iot.deviceupdate.models.PageableListOfDeviceTags] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfDeviceTags"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_all_device_tags.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfDeviceTags', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + get_all_device_tags.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/devicetags'} # type: ignore + + async def get_device_tag( + self, + tag_name: str, + **kwargs + ) -> "_models.DeviceTag": + """Gets a count of how many devices have a device tag. + + :param tag_name: Tag name. + :type tag_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: DeviceTag, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.DeviceTag + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.DeviceTag"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_device_tag.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'tagName': self._serialize.url("tag_name", tag_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('DeviceTag', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_device_tag.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/devicetags/{tagName}'} # type: ignore + + def get_all_groups( + self, + **kwargs + ) -> AsyncIterable["_models.PageableListOfGroups"]: + """Gets a list of all device groups. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfGroups or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.iot.deviceupdate.models.PageableListOfGroups] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfGroups"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_all_groups.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfGroups', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + get_all_groups.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/groups'} # type: ignore + + async def get_group( + self, + group_id: str, + **kwargs + ) -> "_models.Group": + """Gets the properties of a group. + + :param group_id: Group identifier. + :type group_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Group, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Group + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.Group"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_group.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'groupId': self._serialize.url("group_id", group_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('Group', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_group.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/groups/{groupId}'} # type: ignore + + async def create_or_update_group( + self, + group_id: str, + group: "_models.Group", + **kwargs + ) -> "_models.Group": + """Create or update a device group. + + :param group_id: Group identifier. + :type group_id: str + :param group: The group properties. + :type group: ~azure.iot.deviceupdate.models.Group + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Group, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Group + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.Group"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self.create_or_update_group.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'groupId': self._serialize.url("group_id", group_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(group, 'Group') + body_content_kwargs['content'] = body_content + request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('Group', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + create_or_update_group.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/groups/{groupId}'} # type: ignore + + async def delete_group( + self, + group_id: str, + **kwargs + ) -> None: + """Deletes a device group. + + :param group_id: Group identifier. + :type group_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: None, or the result of cls(response) + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + # Construct URL + url = self.delete_group.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'groupId': self._serialize.url("group_id", group_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + delete_group.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/groups/{groupId}'} # type: ignore + + async def get_group_update_compliance( + self, + group_id: str, + **kwargs + ) -> "_models.UpdateCompliance": + """Get group update compliance information such as how many devices are on their latest update, + how many need new updates, and how many are in progress on receiving a new update. + + :param group_id: Group identifier. + :type group_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: UpdateCompliance, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.UpdateCompliance + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.UpdateCompliance"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_group_update_compliance.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'groupId': self._serialize.url("group_id", group_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('UpdateCompliance', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_group_update_compliance.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/groups/{groupId}/updateCompliance'} # type: ignore + + def get_group_best_updates( + self, + group_id: str, + filter: Optional[str] = None, + **kwargs + ) -> AsyncIterable["_models.PageableListOfUpdatableDevices"]: + """Get the best available updates for a group and a count of how many devices need each update. + + :param group_id: Group identifier. + :type group_id: str + :param filter: Restricts the set of bestUpdates returned. You can filter on update Provider, + Name and Version property. + :type filter: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfUpdatableDevices or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.iot.deviceupdate.models.PageableListOfUpdatableDevices] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfUpdatableDevices"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_group_best_updates.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'groupId': self._serialize.url("group_id", group_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + if filter is not None: + query_parameters['$filter'] = self._serialize.query("filter", filter, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'groupId': self._serialize.url("group_id", group_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfUpdatableDevices', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + get_group_best_updates.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/groups/{groupId}/bestUpdates'} # type: ignore diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/operations/_updates_operations.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/operations/_updates_operations.py new file mode 100644 index 000000000000..1f9d8ce50267 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/aio/operations/_updates_operations.py @@ -0,0 +1,767 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import Any, AsyncIterable, Callable, Dict, Generic, Optional, TypeVar +import warnings + +from azure.core.async_paging import AsyncItemPaged, AsyncList +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import AsyncHttpResponse, HttpRequest + +from ... import models as _models + +T = TypeVar('T') +ClsType = Optional[Callable[[PipelineResponse[HttpRequest, AsyncHttpResponse], T, Dict[str, Any]], Any]] + +class UpdatesOperations: + """UpdatesOperations async operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.iot.deviceupdate.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = _models + + def __init__(self, client, config, serializer, deserializer) -> None: + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + async def import_update( + self, + update_to_import: "_models.ImportUpdateInput", + **kwargs + ) -> None: + """Import new update version. + + :param update_to_import: The update to be imported. + :type update_to_import: ~azure.iot.deviceupdate.models.ImportUpdateInput + :keyword callable cls: A custom type or function that will be passed the direct response + :return: None, or the result of cls(response) + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + action = "import" + content_type = kwargs.pop("content_type", "application/json") + + # Construct URL + url = self.import_update.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['action'] = self._serialize.query("action", action, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(update_to_import, 'ImportUpdateInput') + body_content_kwargs['content'] = body_content + request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + response_headers['Location']=self._deserialize('str', response.headers.get('Location')) + response_headers['Operation-Location']=self._deserialize('str', response.headers.get('Operation-Location')) + + if cls: + return cls(pipeline_response, None, response_headers) + + import_update.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates'} # type: ignore + + async def get_update( + self, + provider: str, + name: str, + version: str, + access_condition: Optional["_models.AccessCondition"] = None, + **kwargs + ) -> Optional["_models.Update"]: + """Get a specific update version. + + :param provider: Update provider. + :type provider: str + :param name: Update name. + :type name: str + :param version: Update version. + :type version: str + :param access_condition: Parameter group. + :type access_condition: ~azure.iot.deviceupdate.models.AccessCondition + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Update, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Update or None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[Optional["_models.Update"]] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + _if_none_match = None + if access_condition is not None: + _if_none_match = access_condition.if_none_match + accept = "application/json" + + # Construct URL + url = self.get_update.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + 'name': self._serialize.url("name", name, 'str'), + 'version': self._serialize.url("version", version, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + if _if_none_match is not None: + header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 304]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = None + if response.status_code == 200: + deserialized = self._deserialize('Update', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_update.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/providers/{provider}/names/{name}/versions/{version}'} # type: ignore + + async def delete_update( + self, + provider: str, + name: str, + version: str, + **kwargs + ) -> None: + """Delete a specific update version. + + :param provider: Update provider. + :type provider: str + :param name: Update name. + :type name: str + :param version: Update version. + :type version: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: None, or the result of cls(response) + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + # Construct URL + url = self.delete_update.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + 'name': self._serialize.url("name", name, 'str'), + 'version': self._serialize.url("version", version, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + response_headers['Location']=self._deserialize('str', response.headers.get('Location')) + response_headers['Operation-Location']=self._deserialize('str', response.headers.get('Operation-Location')) + + if cls: + return cls(pipeline_response, None, response_headers) + + delete_update.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/providers/{provider}/names/{name}/versions/{version}'} # type: ignore + + def get_providers( + self, + **kwargs + ) -> AsyncIterable["_models.PageableListOfStrings"]: + """Get a list of all update providers that have been imported to Device Update for IoT Hub. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfStrings or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.iot.deviceupdate.models.PageableListOfStrings] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfStrings"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_providers.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfStrings', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + get_providers.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/providers'} # type: ignore + + def get_names( + self, + provider: str, + **kwargs + ) -> AsyncIterable["_models.PageableListOfStrings"]: + """Get a list of all update names that match the specified provider. + + :param provider: Update provider. + :type provider: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfStrings or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.iot.deviceupdate.models.PageableListOfStrings] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfStrings"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_names.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfStrings', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + get_names.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/providers/{provider}/names'} # type: ignore + + def get_versions( + self, + provider: str, + name: str, + **kwargs + ) -> AsyncIterable["_models.PageableListOfStrings"]: + """Get a list of all update versions that match the specified provider and name. + + :param provider: Update provider. + :type provider: str + :param name: Update name. + :type name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfStrings or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.iot.deviceupdate.models.PageableListOfStrings] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfStrings"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_versions.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + 'name': self._serialize.url("name", name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + 'name': self._serialize.url("name", name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfStrings', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + get_versions.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/providers/{provider}/names/{name}/versions'} # type: ignore + + def get_files( + self, + provider: str, + name: str, + version: str, + **kwargs + ) -> AsyncIterable["_models.PageableListOfStrings"]: + """Get a list of all update file identifiers for the specified version. + + :param provider: Update provider. + :type provider: str + :param name: Update name. + :type name: str + :param version: Update version. + :type version: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfStrings or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.iot.deviceupdate.models.PageableListOfStrings] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfStrings"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_files.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + 'name': self._serialize.url("name", name, 'str'), + 'version': self._serialize.url("version", version, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + 'name': self._serialize.url("name", name, 'str'), + 'version': self._serialize.url("version", version, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfStrings', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + get_files.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/providers/{provider}/names/{name}/versions/{version}/files'} # type: ignore + + async def get_file( + self, + provider: str, + name: str, + version: str, + file_id: str, + access_condition: Optional["_models.AccessCondition"] = None, + **kwargs + ) -> Optional["_models.File"]: + """Get a specific update file from the version. + + :param provider: Update provider. + :type provider: str + :param name: Update name. + :type name: str + :param version: Update version. + :type version: str + :param file_id: File identifier. + :type file_id: str + :param access_condition: Parameter group. + :type access_condition: ~azure.iot.deviceupdate.models.AccessCondition + :keyword callable cls: A custom type or function that will be passed the direct response + :return: File, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.File or None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[Optional["_models.File"]] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + _if_none_match = None + if access_condition is not None: + _if_none_match = access_condition.if_none_match + accept = "application/json" + + # Construct URL + url = self.get_file.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + 'name': self._serialize.url("name", name, 'str'), + 'version': self._serialize.url("version", version, 'str'), + 'fileId': self._serialize.url("file_id", file_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + if _if_none_match is not None: + header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 304]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = None + if response.status_code == 200: + deserialized = self._deserialize('File', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_file.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/providers/{provider}/names/{name}/versions/{version}/files/{fileId}'} # type: ignore + + def get_operations( + self, + filter: Optional[str] = None, + top: Optional[int] = None, + **kwargs + ) -> AsyncIterable["_models.PageableListOfOperations"]: + """Get a list of all import update operations. Completed operations are kept for 7 days before + auto-deleted. Delete operations are not returned by this API version. + + :param filter: Restricts the set of operations returned. Only one specific filter is supported: + "status eq 'NotStarted' or status eq 'Running'". + :type filter: str + :param top: Specifies a non-negative integer n that limits the number of items returned from a + collection. The service returns the number of available items up to but not greater than the + specified value n. + :type top: int + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfOperations or the result of cls(response) + :rtype: ~azure.core.async_paging.AsyncItemPaged[~azure.iot.deviceupdate.models.PageableListOfOperations] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfOperations"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_operations.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + if filter is not None: + query_parameters['$filter'] = self._serialize.query("filter", filter, 'str') + if top is not None: + query_parameters['$top'] = self._serialize.query("top", top, 'int') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + async def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfOperations', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, AsyncList(list_of_elem) + + async def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return AsyncItemPaged( + get_next, extract_data + ) + get_operations.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/operations'} # type: ignore + + async def get_operation( + self, + operation_id: str, + access_condition: Optional["_models.AccessCondition"] = None, + **kwargs + ) -> Optional["_models.Operation"]: + """Retrieve operation status. + + :param operation_id: Operation identifier. + :type operation_id: str + :param access_condition: Parameter group. + :type access_condition: ~azure.iot.deviceupdate.models.AccessCondition + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Operation, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Operation or None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[Optional["_models.Operation"]] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + _if_none_match = None + if access_condition is not None: + _if_none_match = access_condition.if_none_match + accept = "application/json" + + # Construct URL + url = self.get_operation.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'operationId': self._serialize.url("operation_id", operation_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + if _if_none_match is not None: + header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = await self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 304]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + deserialized = None + if response.status_code == 200: + response_headers['Retry-After']=self._deserialize('str', response.headers.get('Retry-After')) + deserialized = self._deserialize('Operation', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, response_headers) + + return deserialized + get_operation.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/operations/{operationId}'} # type: ignore diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/models/__init__.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/models/__init__.py new file mode 100644 index 000000000000..fbb7ff45a173 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/models/__init__.py @@ -0,0 +1,137 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +try: + from ._models_py3 import AccessCondition + from ._models_py3 import Compatibility + from ._models_py3 import Deployment + from ._models_py3 import DeploymentDeviceState + from ._models_py3 import DeploymentDeviceStatesFilter + from ._models_py3 import DeploymentFilter + from ._models_py3 import DeploymentStatus + from ._models_py3 import Device + from ._models_py3 import DeviceClass + from ._models_py3 import DeviceFilter + from ._models_py3 import DeviceTag + from ._models_py3 import Error + from ._models_py3 import File + from ._models_py3 import FileImportMetadata + from ._models_py3 import Group + from ._models_py3 import GroupBestUpdatesFilter + from ._models_py3 import ImportManifestMetadata + from ._models_py3 import ImportUpdateInput + from ._models_py3 import InnerError + from ._models_py3 import Operation + from ._models_py3 import OperationFilter + from ._models_py3 import PageableListOfDeploymentDeviceStates + from ._models_py3 import PageableListOfDeployments + from ._models_py3 import PageableListOfDeviceClasses + from ._models_py3 import PageableListOfDeviceTags + from ._models_py3 import PageableListOfDevices + from ._models_py3 import PageableListOfGroups + from ._models_py3 import PageableListOfOperations + from ._models_py3 import PageableListOfStrings + from ._models_py3 import PageableListOfUpdatableDevices + from ._models_py3 import PageableListOfUpdateIds + from ._models_py3 import UpdatableDevices + from ._models_py3 import Update + from ._models_py3 import UpdateCompliance + from ._models_py3 import UpdateId +except (SyntaxError, ImportError): + from ._models import AccessCondition # type: ignore + from ._models import Compatibility # type: ignore + from ._models import Deployment # type: ignore + from ._models import DeploymentDeviceState # type: ignore + from ._models import DeploymentDeviceStatesFilter # type: ignore + from ._models import DeploymentFilter # type: ignore + from ._models import DeploymentStatus # type: ignore + from ._models import Device # type: ignore + from ._models import DeviceClass # type: ignore + from ._models import DeviceFilter # type: ignore + from ._models import DeviceTag # type: ignore + from ._models import Error # type: ignore + from ._models import File # type: ignore + from ._models import FileImportMetadata # type: ignore + from ._models import Group # type: ignore + from ._models import GroupBestUpdatesFilter # type: ignore + from ._models import ImportManifestMetadata # type: ignore + from ._models import ImportUpdateInput # type: ignore + from ._models import InnerError # type: ignore + from ._models import Operation # type: ignore + from ._models import OperationFilter # type: ignore + from ._models import PageableListOfDeploymentDeviceStates # type: ignore + from ._models import PageableListOfDeployments # type: ignore + from ._models import PageableListOfDeviceClasses # type: ignore + from ._models import PageableListOfDeviceTags # type: ignore + from ._models import PageableListOfDevices # type: ignore + from ._models import PageableListOfGroups # type: ignore + from ._models import PageableListOfOperations # type: ignore + from ._models import PageableListOfStrings # type: ignore + from ._models import PageableListOfUpdatableDevices # type: ignore + from ._models import PageableListOfUpdateIds # type: ignore + from ._models import UpdatableDevices # type: ignore + from ._models import Update # type: ignore + from ._models import UpdateCompliance # type: ignore + from ._models import UpdateId # type: ignore + +from ._device_update_client_enums import ( + DeploymentState, + DeploymentType, + DeviceDeploymentState, + DeviceGroupType, + DeviceState, + GroupType, + OperationFilterStatus, + OperationStatus, +) + +__all__ = [ + 'AccessCondition', + 'Compatibility', + 'Deployment', + 'DeploymentDeviceState', + 'DeploymentDeviceStatesFilter', + 'DeploymentFilter', + 'DeploymentStatus', + 'Device', + 'DeviceClass', + 'DeviceFilter', + 'DeviceTag', + 'Error', + 'File', + 'FileImportMetadata', + 'Group', + 'GroupBestUpdatesFilter', + 'ImportManifestMetadata', + 'ImportUpdateInput', + 'InnerError', + 'Operation', + 'OperationFilter', + 'PageableListOfDeploymentDeviceStates', + 'PageableListOfDeployments', + 'PageableListOfDeviceClasses', + 'PageableListOfDeviceTags', + 'PageableListOfDevices', + 'PageableListOfGroups', + 'PageableListOfOperations', + 'PageableListOfStrings', + 'PageableListOfUpdatableDevices', + 'PageableListOfUpdateIds', + 'UpdatableDevices', + 'Update', + 'UpdateCompliance', + 'UpdateId', + 'DeploymentState', + 'DeploymentType', + 'DeviceDeploymentState', + 'DeviceGroupType', + 'DeviceState', + 'GroupType', + 'OperationFilterStatus', + 'OperationStatus', +] diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/models/_device_update_client_enums.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/models/_device_update_client_enums.py new file mode 100644 index 000000000000..58adfb960496 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/models/_device_update_client_enums.py @@ -0,0 +1,126 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from enum import Enum, EnumMeta +from six import with_metaclass + +class _CaseInsensitiveEnumMeta(EnumMeta): + def __getitem__(self, name): + return super().__getitem__(name.upper()) + + def __getattr__(cls, name): + """Return the enum member matching `name` + We use __getattr__ instead of descriptors or inserting into the enum + class' __dict__ in order to support `name` and `value` being both + properties for enum members (which live in the class' __dict__) and + enum members themselves. + """ + try: + return cls._member_map_[name.upper()] + except KeyError: + raise AttributeError(name) + + +class DeploymentState(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """Deployment state. + """ + + #: The deployment can be sent to devices targeted in the deployment. + ACTIVE = "Active" + #: A newer deployment with the same targeting exists and no devices will receive this deployment. + SUPERSEDED = "Superseded" + #: The deployment has been canceled and no devices will receive it. + CANCELED = "Canceled" + +class DeploymentType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """Supported deployment types. + """ + + #: A complete deployment including download, install, and apply actions. + COMPLETE = "Complete" + #: A download-only deployment that does not include any install or apply actions. Not currently + #: supported. + DOWNLOAD = "Download" + #: An install-only rollout that does not include any download actions, only install and complete. + #: Not currently supported. + INSTALL = "Install" + +class DeviceDeploymentState(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """Deployment state. + """ + + #: Deployment has completed with success. + SUCCEEDED = "Succeeded" + #: Deployment is in progress. + IN_PROGRESS = "InProgress" + #: Deployment has completed with failure. + FAILED = "Failed" + #: Deployment was canceled. + CANCELED = "Canceled" + #: Deployment is not compatible with the device. + INCOMPATIBLE = "Incompatible" + +class DeviceGroupType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """Supported deployment group types. + """ + + #: The deployment should be sent to all devices in the device class. + ALL = "All" + #: The deployment should be sent to the list of devices in the device group definition. + DEVICES = "Devices" + #: The deployment should be sent to the list of devices returned by the union of all the device + #: group definition queries. + DEVICE_GROUP_DEFINITIONS = "DeviceGroupDefinitions" + +class DeviceState(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """The deployment device state. + """ + + #: Not started (or uninitialized). + NOT_STARTED = "NotStarted" + #: Deployment incompatible for this device. + INCOMPATIBLE = "Incompatible" + #: Another Deployment is underway for this device. + ALREADY_IN_DEPLOYMENT = "AlreadyInDeployment" + #: Deployment has been canceled for this device. + CANCELED = "Canceled" + #: Deployment underway. + IN_PROGRESS = "InProgress" + #: Deployment failed. + FAILED = "Failed" + #: Deployment completed successfully. + SUCCEEDED = "Succeeded" + +class GroupType(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """Supported group types. + """ + + #: IoT Hub tag based group. + IO_T_HUB_TAG = "IoTHubTag" + +class OperationFilterStatus(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """Operation status filter. + """ + + RUNNING = "Running" + NOT_STARTED = "NotStarted" + +class OperationStatus(with_metaclass(_CaseInsensitiveEnumMeta, str, Enum)): + """Operation status. + """ + + #: Undefined operation status. + UNDEFINED = "Undefined" + #: Background operation created but not started yet. + NOT_STARTED = "NotStarted" + #: Background operation is currently running. + RUNNING = "Running" + #: Background operation finished with success. + SUCCEEDED = "Succeeded" + #: Background operation finished with failure. + FAILED = "Failed" diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/models/_models.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/models/_models.py new file mode 100644 index 000000000000..4af2eed3b525 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/models/_models.py @@ -0,0 +1,1218 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +import msrest.serialization + + +class AccessCondition(msrest.serialization.Model): + """Parameter group. + + :param if_none_match: Defines the If-None-Match condition. The operation will be performed only + if the ETag on the server does not match this value. + :type if_none_match: str + """ + + _attribute_map = { + 'if_none_match': {'key': 'If-None-Match', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(AccessCondition, self).__init__(**kwargs) + self.if_none_match = kwargs.get('if_none_match', None) + + +class Compatibility(msrest.serialization.Model): + """Update compatibility information. + + All required parameters must be populated in order to send to Azure. + + :param device_manufacturer: Required. The manufacturer of device the update is compatible with. + :type device_manufacturer: str + :param device_model: Required. The model of device the update is compatible with. + :type device_model: str + """ + + _validation = { + 'device_manufacturer': {'required': True}, + 'device_model': {'required': True}, + } + + _attribute_map = { + 'device_manufacturer': {'key': 'deviceManufacturer', 'type': 'str'}, + 'device_model': {'key': 'deviceModel', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(Compatibility, self).__init__(**kwargs) + self.device_manufacturer = kwargs['device_manufacturer'] + self.device_model = kwargs['device_model'] + + +class Deployment(msrest.serialization.Model): + """Deployment metadata. + + All required parameters must be populated in order to send to Azure. + + :param deployment_id: Required. Gets or sets the deployment identifier. + :type deployment_id: str + :param deployment_type: Required. Gets or sets the deployment type. Possible values include: + "Complete", "Download", "Install". + :type deployment_type: str or ~azure.iot.deviceupdate.models.DeploymentType + :param device_class_id: Gets or sets the device class identifier. + :type device_class_id: str + :param start_date_time: Required. Gets or sets the Deployment start datetime. + :type start_date_time: ~datetime.datetime + :param device_group_type: Required. Gets or sets the device group type. Possible values + include: "All", "Devices", "DeviceGroupDefinitions". + :type device_group_type: str or ~azure.iot.deviceupdate.models.DeviceGroupType + :param device_group_definition: Required. Gets or sets the device group definition. + :type device_group_definition: list[str] + :param update_id: Required. Update identity. + :type update_id: ~azure.iot.deviceupdate.models.UpdateId + :param is_canceled: Boolean flag indicating whether the deployment was canceled. + :type is_canceled: bool + :param is_retried: Boolean flag indicating whether the deployment has been retried. + :type is_retried: bool + :param is_completed: Boolean flag indicating whether the deployment was completed. + :type is_completed: bool + """ + + _validation = { + 'deployment_id': {'required': True}, + 'deployment_type': {'required': True}, + 'start_date_time': {'required': True}, + 'device_group_type': {'required': True}, + 'device_group_definition': {'required': True}, + 'update_id': {'required': True}, + } + + _attribute_map = { + 'deployment_id': {'key': 'deploymentId', 'type': 'str'}, + 'deployment_type': {'key': 'deploymentType', 'type': 'str'}, + 'device_class_id': {'key': 'deviceClassId', 'type': 'str'}, + 'start_date_time': {'key': 'startDateTime', 'type': 'iso-8601'}, + 'device_group_type': {'key': 'deviceGroupType', 'type': 'str'}, + 'device_group_definition': {'key': 'deviceGroupDefinition', 'type': '[str]'}, + 'update_id': {'key': 'updateId', 'type': 'UpdateId'}, + 'is_canceled': {'key': 'isCanceled', 'type': 'bool'}, + 'is_retried': {'key': 'isRetried', 'type': 'bool'}, + 'is_completed': {'key': 'isCompleted', 'type': 'bool'}, + } + + def __init__( + self, + **kwargs + ): + super(Deployment, self).__init__(**kwargs) + self.deployment_id = kwargs['deployment_id'] + self.deployment_type = kwargs['deployment_type'] + self.device_class_id = kwargs.get('device_class_id', None) + self.start_date_time = kwargs['start_date_time'] + self.device_group_type = kwargs['device_group_type'] + self.device_group_definition = kwargs['device_group_definition'] + self.update_id = kwargs['update_id'] + self.is_canceled = kwargs.get('is_canceled', None) + self.is_retried = kwargs.get('is_retried', None) + self.is_completed = kwargs.get('is_completed', None) + + +class DeploymentDeviceState(msrest.serialization.Model): + """Deployment device status. + + All required parameters must be populated in order to send to Azure. + + :param device_id: Required. Device identity. + :type device_id: str + :param retry_count: Required. The number of times this deployment has been retried on this + device. + :type retry_count: int + :param moved_on_to_new_deployment: Required. Boolean flag indicating whether this device is in + a newer deployment and can no longer retry this deployment. + :type moved_on_to_new_deployment: bool + :param device_state: Required. Deployment device state. Possible values include: "Succeeded", + "InProgress", "Failed", "Canceled", "Incompatible". + :type device_state: str or ~azure.iot.deviceupdate.models.DeviceDeploymentState + """ + + _validation = { + 'device_id': {'required': True}, + 'retry_count': {'required': True}, + 'moved_on_to_new_deployment': {'required': True}, + 'device_state': {'required': True}, + } + + _attribute_map = { + 'device_id': {'key': 'deviceId', 'type': 'str'}, + 'retry_count': {'key': 'retryCount', 'type': 'int'}, + 'moved_on_to_new_deployment': {'key': 'movedOnToNewDeployment', 'type': 'bool'}, + 'device_state': {'key': 'deviceState', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(DeploymentDeviceState, self).__init__(**kwargs) + self.device_id = kwargs['device_id'] + self.retry_count = kwargs['retry_count'] + self.moved_on_to_new_deployment = kwargs['moved_on_to_new_deployment'] + self.device_state = kwargs['device_state'] + + +class DeploymentDeviceStatesFilter(msrest.serialization.Model): + """Deployment device state filter. + + :param device_id: Device Identifier. + :type device_id: str + :param device_state: The deployment device state. Possible values include: "NotStarted", + "Incompatible", "AlreadyInDeployment", "Canceled", "InProgress", "Failed", "Succeeded". + :type device_state: str or ~azure.iot.deviceupdate.models.DeviceState + """ + + _attribute_map = { + 'device_id': {'key': 'deviceId', 'type': 'str'}, + 'device_state': {'key': 'deviceState', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(DeploymentDeviceStatesFilter, self).__init__(**kwargs) + self.device_id = kwargs.get('device_id', None) + self.device_state = kwargs.get('device_state', None) + + +class DeploymentFilter(msrest.serialization.Model): + """Deployment filter. + + :param provider: Update provider. + :type provider: str + :param name: Update name. + :type name: str + :param version: Update version. + :type version: str + """ + + _attribute_map = { + 'provider': {'key': 'provider', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'version': {'key': 'version', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(DeploymentFilter, self).__init__(**kwargs) + self.provider = kwargs.get('provider', None) + self.name = kwargs.get('name', None) + self.version = kwargs.get('version', None) + + +class DeploymentStatus(msrest.serialization.Model): + """Deployment status metadata. + + All required parameters must be populated in order to send to Azure. + + :param deployment_state: Required. Gets or sets the state of the deployment. Possible values + include: "Active", "Superseded", "Canceled". + :type deployment_state: str or ~azure.iot.deviceupdate.models.DeploymentState + :param total_devices: Gets or sets the total number of devices in the deployment. + :type total_devices: int + :param devices_incompatible_count: Gets or sets the number of incompatible devices in the + deployment. + :type devices_incompatible_count: int + :param devices_in_progress_count: Gets or sets the number of devices that are currently in + deployment. + :type devices_in_progress_count: int + :param devices_completed_failed_count: Gets or sets the number of devices that have completed + deployment with a failure. + :type devices_completed_failed_count: int + :param devices_completed_succeeded_count: Gets or sets the number of devices which have + successfully completed deployment. + :type devices_completed_succeeded_count: int + :param devices_canceled_count: Gets or sets the number of devices which have had their + deployment canceled. + :type devices_canceled_count: int + """ + + _validation = { + 'deployment_state': {'required': True}, + } + + _attribute_map = { + 'deployment_state': {'key': 'deploymentState', 'type': 'str'}, + 'total_devices': {'key': 'totalDevices', 'type': 'int'}, + 'devices_incompatible_count': {'key': 'devicesIncompatibleCount', 'type': 'int'}, + 'devices_in_progress_count': {'key': 'devicesInProgressCount', 'type': 'int'}, + 'devices_completed_failed_count': {'key': 'devicesCompletedFailedCount', 'type': 'int'}, + 'devices_completed_succeeded_count': {'key': 'devicesCompletedSucceededCount', 'type': 'int'}, + 'devices_canceled_count': {'key': 'devicesCanceledCount', 'type': 'int'}, + } + + def __init__( + self, + **kwargs + ): + super(DeploymentStatus, self).__init__(**kwargs) + self.deployment_state = kwargs['deployment_state'] + self.total_devices = kwargs.get('total_devices', None) + self.devices_incompatible_count = kwargs.get('devices_incompatible_count', None) + self.devices_in_progress_count = kwargs.get('devices_in_progress_count', None) + self.devices_completed_failed_count = kwargs.get('devices_completed_failed_count', None) + self.devices_completed_succeeded_count = kwargs.get('devices_completed_succeeded_count', None) + self.devices_canceled_count = kwargs.get('devices_canceled_count', None) + + +class Device(msrest.serialization.Model): + """Device metadata. + + All required parameters must be populated in order to send to Azure. + + :param device_id: Required. Device identity. + :type device_id: str + :param device_class_id: Required. Device class identity. + :type device_class_id: str + :param manufacturer: Required. Device manufacturer. + :type manufacturer: str + :param model: Required. Device model. + :type model: str + :param group_id: Device group identity. + :type group_id: str + :param last_attempted_update_id: Update identity. + :type last_attempted_update_id: ~azure.iot.deviceupdate.models.UpdateId + :param deployment_status: State of the device in its last deployment. Possible values include: + "Succeeded", "InProgress", "Failed", "Canceled", "Incompatible". + :type deployment_status: str or ~azure.iot.deviceupdate.models.DeviceDeploymentState + :param installed_update_id: Update identity. + :type installed_update_id: ~azure.iot.deviceupdate.models.UpdateId + :param on_latest_update: Required. Boolean flag indicating whether the latest update is + installed on the device. + :type on_latest_update: bool + :param last_deployment_id: The deployment identifier for the last deployment to the device. + :type last_deployment_id: str + """ + + _validation = { + 'device_id': {'required': True}, + 'device_class_id': {'required': True}, + 'manufacturer': {'required': True}, + 'model': {'required': True}, + 'on_latest_update': {'required': True}, + } + + _attribute_map = { + 'device_id': {'key': 'deviceId', 'type': 'str'}, + 'device_class_id': {'key': 'deviceClassId', 'type': 'str'}, + 'manufacturer': {'key': 'manufacturer', 'type': 'str'}, + 'model': {'key': 'model', 'type': 'str'}, + 'group_id': {'key': 'groupId', 'type': 'str'}, + 'last_attempted_update_id': {'key': 'lastAttemptedUpdateId', 'type': 'UpdateId'}, + 'deployment_status': {'key': 'deploymentStatus', 'type': 'str'}, + 'installed_update_id': {'key': 'installedUpdateId', 'type': 'UpdateId'}, + 'on_latest_update': {'key': 'onLatestUpdate', 'type': 'bool'}, + 'last_deployment_id': {'key': 'lastDeploymentId', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(Device, self).__init__(**kwargs) + self.device_id = kwargs['device_id'] + self.device_class_id = kwargs['device_class_id'] + self.manufacturer = kwargs['manufacturer'] + self.model = kwargs['model'] + self.group_id = kwargs.get('group_id', None) + self.last_attempted_update_id = kwargs.get('last_attempted_update_id', None) + self.deployment_status = kwargs.get('deployment_status', None) + self.installed_update_id = kwargs.get('installed_update_id', None) + self.on_latest_update = kwargs['on_latest_update'] + self.last_deployment_id = kwargs.get('last_deployment_id', None) + + +class DeviceClass(msrest.serialization.Model): + """Device class metadata. + + All required parameters must be populated in order to send to Azure. + + :param device_class_id: Required. The device class identifier. + :type device_class_id: str + :param manufacturer: Required. Device manufacturer. + :type manufacturer: str + :param model: Required. Device model. + :type model: str + :param best_compatible_update_id: Required. Update identity. + :type best_compatible_update_id: ~azure.iot.deviceupdate.models.UpdateId + """ + + _validation = { + 'device_class_id': {'required': True}, + 'manufacturer': {'required': True}, + 'model': {'required': True}, + 'best_compatible_update_id': {'required': True}, + } + + _attribute_map = { + 'device_class_id': {'key': 'deviceClassId', 'type': 'str'}, + 'manufacturer': {'key': 'manufacturer', 'type': 'str'}, + 'model': {'key': 'model', 'type': 'str'}, + 'best_compatible_update_id': {'key': 'bestCompatibleUpdateId', 'type': 'UpdateId'}, + } + + def __init__( + self, + **kwargs + ): + super(DeviceClass, self).__init__(**kwargs) + self.device_class_id = kwargs['device_class_id'] + self.manufacturer = kwargs['manufacturer'] + self.model = kwargs['model'] + self.best_compatible_update_id = kwargs['best_compatible_update_id'] + + +class DeviceFilter(msrest.serialization.Model): + """Operation status filter. + + :param group_id: Device group identifier. + :type group_id: str + """ + + _attribute_map = { + 'group_id': {'key': 'groupId', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(DeviceFilter, self).__init__(**kwargs) + self.group_id = kwargs.get('group_id', None) + + +class DeviceTag(msrest.serialization.Model): + """Device tag properties. + + All required parameters must be populated in order to send to Azure. + + :param tag_name: Required. Tag name. + :type tag_name: str + :param device_count: Required. Number of devices with this tag. + :type device_count: int + """ + + _validation = { + 'tag_name': {'required': True}, + 'device_count': {'required': True}, + } + + _attribute_map = { + 'tag_name': {'key': 'tagName', 'type': 'str'}, + 'device_count': {'key': 'deviceCount', 'type': 'int'}, + } + + def __init__( + self, + **kwargs + ): + super(DeviceTag, self).__init__(**kwargs) + self.tag_name = kwargs['tag_name'] + self.device_count = kwargs['device_count'] + + +class Error(msrest.serialization.Model): + """Error details. + + All required parameters must be populated in order to send to Azure. + + :param code: Required. Server defined error code. + :type code: str + :param message: Required. A human-readable representation of the error. + :type message: str + :param target: The target of the error. + :type target: str + :param details: An array of errors that led to the reported error. + :type details: list[~azure.iot.deviceupdate.models.Error] + :param innererror: An object containing more specific information than the current object about + the error. + :type innererror: ~azure.iot.deviceupdate.models.InnerError + :param occurred_date_time: Date and time in UTC when the error occurred. + :type occurred_date_time: ~datetime.datetime + """ + + _validation = { + 'code': {'required': True}, + 'message': {'required': True}, + } + + _attribute_map = { + 'code': {'key': 'code', 'type': 'str'}, + 'message': {'key': 'message', 'type': 'str'}, + 'target': {'key': 'target', 'type': 'str'}, + 'details': {'key': 'details', 'type': '[Error]'}, + 'innererror': {'key': 'innererror', 'type': 'InnerError'}, + 'occurred_date_time': {'key': 'occurredDateTime', 'type': 'iso-8601'}, + } + + def __init__( + self, + **kwargs + ): + super(Error, self).__init__(**kwargs) + self.code = kwargs['code'] + self.message = kwargs['message'] + self.target = kwargs.get('target', None) + self.details = kwargs.get('details', None) + self.innererror = kwargs.get('innererror', None) + self.occurred_date_time = kwargs.get('occurred_date_time', None) + + +class File(msrest.serialization.Model): + """Update file metadata. + + All required parameters must be populated in order to send to Azure. + + :param file_id: Required. File identity, generated by server at import time. + :type file_id: str + :param file_name: Required. File name. + :type file_name: str + :param size_in_bytes: Required. File size in number of bytes. + :type size_in_bytes: long + :param hashes: Required. Mapping of hashing algorithm to base64 encoded hash values. + :type hashes: dict[str, str] + :param mime_type: File MIME type. + :type mime_type: str + :param etag: File ETag. + :type etag: str + """ + + _validation = { + 'file_id': {'required': True}, + 'file_name': {'required': True}, + 'size_in_bytes': {'required': True}, + 'hashes': {'required': True}, + } + + _attribute_map = { + 'file_id': {'key': 'fileId', 'type': 'str'}, + 'file_name': {'key': 'fileName', 'type': 'str'}, + 'size_in_bytes': {'key': 'sizeInBytes', 'type': 'long'}, + 'hashes': {'key': 'hashes', 'type': '{str}'}, + 'mime_type': {'key': 'mimeType', 'type': 'str'}, + 'etag': {'key': 'etag', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(File, self).__init__(**kwargs) + self.file_id = kwargs['file_id'] + self.file_name = kwargs['file_name'] + self.size_in_bytes = kwargs['size_in_bytes'] + self.hashes = kwargs['hashes'] + self.mime_type = kwargs.get('mime_type', None) + self.etag = kwargs.get('etag', None) + + +class FileImportMetadata(msrest.serialization.Model): + """Metadata describing an update file. + + All required parameters must be populated in order to send to Azure. + + :param filename: Required. Update file name as specified inside import manifest. + :type filename: str + :param url: Required. Azure Blob location from which the update file can be downloaded by + Device Update for IoT Hub. This is typically a read-only SAS-protected blob URL with an + expiration set to at least 4 hours. + :type url: str + """ + + _validation = { + 'filename': {'required': True}, + 'url': {'required': True}, + } + + _attribute_map = { + 'filename': {'key': 'filename', 'type': 'str'}, + 'url': {'key': 'url', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(FileImportMetadata, self).__init__(**kwargs) + self.filename = kwargs['filename'] + self.url = kwargs['url'] + + +class Group(msrest.serialization.Model): + """Group details. + + All required parameters must be populated in order to send to Azure. + + :param group_id: Required. Group identity. + :type group_id: str + :param group_type: Required. Group type. Possible values include: "IoTHubTag". + :type group_type: str or ~azure.iot.deviceupdate.models.GroupType + :param tags: Required. A set of tags. IoT Hub tags. + :type tags: list[str] + :param created_date_time: Required. Date and time when the update was created. + :type created_date_time: str + :param device_count: The number of devices in the group. + :type device_count: int + """ + + _validation = { + 'group_id': {'required': True}, + 'group_type': {'required': True}, + 'tags': {'required': True}, + 'created_date_time': {'required': True}, + } + + _attribute_map = { + 'group_id': {'key': 'groupId', 'type': 'str'}, + 'group_type': {'key': 'groupType', 'type': 'str'}, + 'tags': {'key': 'tags', 'type': '[str]'}, + 'created_date_time': {'key': 'createdDateTime', 'type': 'str'}, + 'device_count': {'key': 'deviceCount', 'type': 'int'}, + } + + def __init__( + self, + **kwargs + ): + super(Group, self).__init__(**kwargs) + self.group_id = kwargs['group_id'] + self.group_type = kwargs['group_type'] + self.tags = kwargs['tags'] + self.created_date_time = kwargs['created_date_time'] + self.device_count = kwargs.get('device_count', None) + + +class GroupBestUpdatesFilter(msrest.serialization.Model): + """Group best updates filter. + + :param provider: Update provider. + :type provider: str + :param name: Update name. + :type name: str + :param version: Update version. + :type version: str + """ + + _attribute_map = { + 'provider': {'key': 'provider', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'version': {'key': 'version', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(GroupBestUpdatesFilter, self).__init__(**kwargs) + self.provider = kwargs.get('provider', None) + self.name = kwargs.get('name', None) + self.version = kwargs.get('version', None) + + +class ImportManifestMetadata(msrest.serialization.Model): + """Metadata describing the import manifest, a document which describes the files and other metadata about an update version. + + All required parameters must be populated in order to send to Azure. + + :param url: Required. Azure Blob location from which the import manifest can be downloaded by + Device Update for IoT Hub. This is typically a read-only SAS-protected blob URL with an + expiration set to at least 4 hours. + :type url: str + :param size_in_bytes: Required. File size in number of bytes. + :type size_in_bytes: long + :param hashes: Required. A JSON object containing the hash(es) of the file. At least SHA256 + hash is required. This object can be thought of as a set of key-value pairs where the key is + the hash algorithm, and the value is the hash of the file calculated using that algorithm. + :type hashes: dict[str, str] + """ + + _validation = { + 'url': {'required': True}, + 'size_in_bytes': {'required': True}, + 'hashes': {'required': True}, + } + + _attribute_map = { + 'url': {'key': 'url', 'type': 'str'}, + 'size_in_bytes': {'key': 'sizeInBytes', 'type': 'long'}, + 'hashes': {'key': 'hashes', 'type': '{str}'}, + } + + def __init__( + self, + **kwargs + ): + super(ImportManifestMetadata, self).__init__(**kwargs) + self.url = kwargs['url'] + self.size_in_bytes = kwargs['size_in_bytes'] + self.hashes = kwargs['hashes'] + + +class ImportUpdateInput(msrest.serialization.Model): + """Import update input metadata. + + All required parameters must be populated in order to send to Azure. + + :param import_manifest: Required. Import manifest metadata like source URL, file size/hashes, + etc. + :type import_manifest: ~azure.iot.deviceupdate.models.ImportManifestMetadata + :param files: Required. One or more update file properties like filename and source URL. + :type files: list[~azure.iot.deviceupdate.models.FileImportMetadata] + """ + + _validation = { + 'import_manifest': {'required': True}, + 'files': {'required': True, 'min_items': 1}, + } + + _attribute_map = { + 'import_manifest': {'key': 'importManifest', 'type': 'ImportManifestMetadata'}, + 'files': {'key': 'files', 'type': '[FileImportMetadata]'}, + } + + def __init__( + self, + **kwargs + ): + super(ImportUpdateInput, self).__init__(**kwargs) + self.import_manifest = kwargs['import_manifest'] + self.files = kwargs['files'] + + +class InnerError(msrest.serialization.Model): + """An object containing more specific information than the current object about the error. + + All required parameters must be populated in order to send to Azure. + + :param code: Required. A more specific error code than what was provided by the containing + error. + :type code: str + :param message: A human-readable representation of the error. + :type message: str + :param error_detail: The internal error or exception message. + :type error_detail: str + :param inner_error: An object containing more specific information than the current object + about the error. + :type inner_error: ~azure.iot.deviceupdate.models.InnerError + """ + + _validation = { + 'code': {'required': True}, + } + + _attribute_map = { + 'code': {'key': 'code', 'type': 'str'}, + 'message': {'key': 'message', 'type': 'str'}, + 'error_detail': {'key': 'errorDetail', 'type': 'str'}, + 'inner_error': {'key': 'innerError', 'type': 'InnerError'}, + } + + def __init__( + self, + **kwargs + ): + super(InnerError, self).__init__(**kwargs) + self.code = kwargs['code'] + self.message = kwargs.get('message', None) + self.error_detail = kwargs.get('error_detail', None) + self.inner_error = kwargs.get('inner_error', None) + + +class Operation(msrest.serialization.Model): + """Operation metadata. + + All required parameters must be populated in order to send to Azure. + + :param operation_id: Required. Operation Id. + :type operation_id: str + :param status: Required. Operation status. Possible values include: "Undefined", "NotStarted", + "Running", "Succeeded", "Failed". + :type status: str or ~azure.iot.deviceupdate.models.OperationStatus + :param update_id: The identity of update being imported or deleted. For import, this property + will only be populated after import manifest is processed successfully. + :type update_id: ~azure.iot.deviceupdate.models.UpdateId + :param resource_location: Location of the imported update when operation is successful. + :type resource_location: str + :param error: Operation error encountered, if any. + :type error: ~azure.iot.deviceupdate.models.Error + :param trace_id: Operation correlation identity that can used by Microsoft Support for + troubleshooting. + :type trace_id: str + :param last_action_date_time: Required. Date and time in UTC when the operation status was last + updated. + :type last_action_date_time: ~datetime.datetime + :param created_date_time: Required. Date and time in UTC when the operation was created. + :type created_date_time: ~datetime.datetime + :param etag: Operation ETag. + :type etag: str + """ + + _validation = { + 'operation_id': {'required': True}, + 'status': {'required': True}, + 'last_action_date_time': {'required': True}, + 'created_date_time': {'required': True}, + } + + _attribute_map = { + 'operation_id': {'key': 'operationId', 'type': 'str'}, + 'status': {'key': 'status', 'type': 'str'}, + 'update_id': {'key': 'updateId', 'type': 'UpdateId'}, + 'resource_location': {'key': 'resourceLocation', 'type': 'str'}, + 'error': {'key': 'error', 'type': 'Error'}, + 'trace_id': {'key': 'traceId', 'type': 'str'}, + 'last_action_date_time': {'key': 'lastActionDateTime', 'type': 'iso-8601'}, + 'created_date_time': {'key': 'createdDateTime', 'type': 'iso-8601'}, + 'etag': {'key': 'etag', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(Operation, self).__init__(**kwargs) + self.operation_id = kwargs['operation_id'] + self.status = kwargs['status'] + self.update_id = kwargs.get('update_id', None) + self.resource_location = kwargs.get('resource_location', None) + self.error = kwargs.get('error', None) + self.trace_id = kwargs.get('trace_id', None) + self.last_action_date_time = kwargs['last_action_date_time'] + self.created_date_time = kwargs['created_date_time'] + self.etag = kwargs.get('etag', None) + + +class OperationFilter(msrest.serialization.Model): + """Operation status filter. + + :param status: Operation status filter. Possible values include: "Running", "NotStarted". + :type status: str or ~azure.iot.deviceupdate.models.OperationFilterStatus + """ + + _attribute_map = { + 'status': {'key': 'status', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(OperationFilter, self).__init__(**kwargs) + self.status = kwargs.get('status', None) + + +class PageableListOfDeploymentDeviceStates(msrest.serialization.Model): + """The list of deployment device states. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.DeploymentDeviceState] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[DeploymentDeviceState]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PageableListOfDeploymentDeviceStates, self).__init__(**kwargs) + self.value = kwargs.get('value', None) + self.next_link = kwargs.get('next_link', None) + + +class PageableListOfDeployments(msrest.serialization.Model): + """The list of deployments. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.Deployment] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[Deployment]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PageableListOfDeployments, self).__init__(**kwargs) + self.value = kwargs.get('value', None) + self.next_link = kwargs.get('next_link', None) + + +class PageableListOfDeviceClasses(msrest.serialization.Model): + """The list of device classes. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.DeviceClass] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[DeviceClass]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PageableListOfDeviceClasses, self).__init__(**kwargs) + self.value = kwargs.get('value', None) + self.next_link = kwargs.get('next_link', None) + + +class PageableListOfDevices(msrest.serialization.Model): + """The list of devices. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.Device] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[Device]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PageableListOfDevices, self).__init__(**kwargs) + self.value = kwargs.get('value', None) + self.next_link = kwargs.get('next_link', None) + + +class PageableListOfDeviceTags(msrest.serialization.Model): + """The list of device tags. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.DeviceTag] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[DeviceTag]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PageableListOfDeviceTags, self).__init__(**kwargs) + self.value = kwargs.get('value', None) + self.next_link = kwargs.get('next_link', None) + + +class PageableListOfGroups(msrest.serialization.Model): + """The list of groups. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.Group] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[Group]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PageableListOfGroups, self).__init__(**kwargs) + self.value = kwargs.get('value', None) + self.next_link = kwargs.get('next_link', None) + + +class PageableListOfOperations(msrest.serialization.Model): + """The list of operations with server paging support. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.Operation] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[Operation]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PageableListOfOperations, self).__init__(**kwargs) + self.value = kwargs.get('value', None) + self.next_link = kwargs.get('next_link', None) + + +class PageableListOfStrings(msrest.serialization.Model): + """The list of strings with server paging support. + + :param value: The collection of pageable items. + :type value: list[str] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[str]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PageableListOfStrings, self).__init__(**kwargs) + self.value = kwargs.get('value', None) + self.next_link = kwargs.get('next_link', None) + + +class PageableListOfUpdatableDevices(msrest.serialization.Model): + """The list of updatable devices. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.UpdatableDevices] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[UpdatableDevices]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PageableListOfUpdatableDevices, self).__init__(**kwargs) + self.value = kwargs.get('value', None) + self.next_link = kwargs.get('next_link', None) + + +class PageableListOfUpdateIds(msrest.serialization.Model): + """The list of update identities. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.UpdateId] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[UpdateId]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(PageableListOfUpdateIds, self).__init__(**kwargs) + self.value = kwargs.get('value', None) + self.next_link = kwargs.get('next_link', None) + + +class UpdatableDevices(msrest.serialization.Model): + """Update identifier and the number of devices for which the update is applicable. + + All required parameters must be populated in order to send to Azure. + + :param update_id: Required. Update identity. + :type update_id: ~azure.iot.deviceupdate.models.UpdateId + :param device_count: Required. Total number of devices for which the update is applicable. + :type device_count: int + """ + + _validation = { + 'update_id': {'required': True}, + 'device_count': {'required': True}, + } + + _attribute_map = { + 'update_id': {'key': 'updateId', 'type': 'UpdateId'}, + 'device_count': {'key': 'deviceCount', 'type': 'int'}, + } + + def __init__( + self, + **kwargs + ): + super(UpdatableDevices, self).__init__(**kwargs) + self.update_id = kwargs['update_id'] + self.device_count = kwargs['device_count'] + + +class Update(msrest.serialization.Model): + """Update metadata. + + All required parameters must be populated in order to send to Azure. + + :param update_id: Required. Update identity. + :type update_id: ~azure.iot.deviceupdate.models.UpdateId + :param update_type: Required. Update type. + :type update_type: str + :param installed_criteria: Required. String interpreted by Device Update client to determine if + the update is installed on the device. + :type installed_criteria: str + :param compatibility: Required. List of update compatibility information. + :type compatibility: list[~azure.iot.deviceupdate.models.Compatibility] + :param manifest_version: Required. Schema version of manifest used to import the update. + :type manifest_version: str + :param imported_date_time: Required. Date and time in UTC when the update was imported. + :type imported_date_time: ~datetime.datetime + :param created_date_time: Required. Date and time in UTC when the update was created. + :type created_date_time: ~datetime.datetime + :param etag: Update ETag. + :type etag: str + """ + + _validation = { + 'update_id': {'required': True}, + 'update_type': {'required': True}, + 'installed_criteria': {'required': True}, + 'compatibility': {'required': True, 'min_items': 1}, + 'manifest_version': {'required': True}, + 'imported_date_time': {'required': True}, + 'created_date_time': {'required': True}, + } + + _attribute_map = { + 'update_id': {'key': 'updateId', 'type': 'UpdateId'}, + 'update_type': {'key': 'updateType', 'type': 'str'}, + 'installed_criteria': {'key': 'installedCriteria', 'type': 'str'}, + 'compatibility': {'key': 'compatibility', 'type': '[Compatibility]'}, + 'manifest_version': {'key': 'manifestVersion', 'type': 'str'}, + 'imported_date_time': {'key': 'importedDateTime', 'type': 'iso-8601'}, + 'created_date_time': {'key': 'createdDateTime', 'type': 'iso-8601'}, + 'etag': {'key': 'etag', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(Update, self).__init__(**kwargs) + self.update_id = kwargs['update_id'] + self.update_type = kwargs['update_type'] + self.installed_criteria = kwargs['installed_criteria'] + self.compatibility = kwargs['compatibility'] + self.manifest_version = kwargs['manifest_version'] + self.imported_date_time = kwargs['imported_date_time'] + self.created_date_time = kwargs['created_date_time'] + self.etag = kwargs.get('etag', None) + + +class UpdateCompliance(msrest.serialization.Model): + """Update compliance information. + + All required parameters must be populated in order to send to Azure. + + :param total_device_count: Required. Total number of devices. + :type total_device_count: int + :param on_latest_update_device_count: Required. Number of devices on the latest update. + :type on_latest_update_device_count: int + :param new_updates_available_device_count: Required. Number of devices with a newer update + available. + :type new_updates_available_device_count: int + :param updates_in_progress_device_count: Required. Number of devices with update in-progress. + :type updates_in_progress_device_count: int + """ + + _validation = { + 'total_device_count': {'required': True}, + 'on_latest_update_device_count': {'required': True}, + 'new_updates_available_device_count': {'required': True}, + 'updates_in_progress_device_count': {'required': True}, + } + + _attribute_map = { + 'total_device_count': {'key': 'totalDeviceCount', 'type': 'int'}, + 'on_latest_update_device_count': {'key': 'onLatestUpdateDeviceCount', 'type': 'int'}, + 'new_updates_available_device_count': {'key': 'newUpdatesAvailableDeviceCount', 'type': 'int'}, + 'updates_in_progress_device_count': {'key': 'updatesInProgressDeviceCount', 'type': 'int'}, + } + + def __init__( + self, + **kwargs + ): + super(UpdateCompliance, self).__init__(**kwargs) + self.total_device_count = kwargs['total_device_count'] + self.on_latest_update_device_count = kwargs['on_latest_update_device_count'] + self.new_updates_available_device_count = kwargs['new_updates_available_device_count'] + self.updates_in_progress_device_count = kwargs['updates_in_progress_device_count'] + + +class UpdateId(msrest.serialization.Model): + """Update identifier. + + All required parameters must be populated in order to send to Azure. + + :param provider: Required. Update provider. + :type provider: str + :param name: Required. Update name. + :type name: str + :param version: Required. Update version. + :type version: str + """ + + _validation = { + 'provider': {'required': True}, + 'name': {'required': True}, + 'version': {'required': True}, + } + + _attribute_map = { + 'provider': {'key': 'provider', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'version': {'key': 'version', 'type': 'str'}, + } + + def __init__( + self, + **kwargs + ): + super(UpdateId, self).__init__(**kwargs) + self.provider = kwargs['provider'] + self.name = kwargs['name'] + self.version = kwargs['version'] diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/models/_models_py3.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/models/_models_py3.py new file mode 100644 index 000000000000..c2f6843f02cf --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/models/_models_py3.py @@ -0,0 +1,1382 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +import datetime +from typing import Dict, List, Optional, Union + +import msrest.serialization + +from ._device_update_client_enums import * + + +class AccessCondition(msrest.serialization.Model): + """Parameter group. + + :param if_none_match: Defines the If-None-Match condition. The operation will be performed only + if the ETag on the server does not match this value. + :type if_none_match: str + """ + + _attribute_map = { + 'if_none_match': {'key': 'If-None-Match', 'type': 'str'}, + } + + def __init__( + self, + *, + if_none_match: Optional[str] = None, + **kwargs + ): + super(AccessCondition, self).__init__(**kwargs) + self.if_none_match = if_none_match + + +class Compatibility(msrest.serialization.Model): + """Update compatibility information. + + All required parameters must be populated in order to send to Azure. + + :param device_manufacturer: Required. The manufacturer of device the update is compatible with. + :type device_manufacturer: str + :param device_model: Required. The model of device the update is compatible with. + :type device_model: str + """ + + _validation = { + 'device_manufacturer': {'required': True}, + 'device_model': {'required': True}, + } + + _attribute_map = { + 'device_manufacturer': {'key': 'deviceManufacturer', 'type': 'str'}, + 'device_model': {'key': 'deviceModel', 'type': 'str'}, + } + + def __init__( + self, + *, + device_manufacturer: str, + device_model: str, + **kwargs + ): + super(Compatibility, self).__init__(**kwargs) + self.device_manufacturer = device_manufacturer + self.device_model = device_model + + +class Deployment(msrest.serialization.Model): + """Deployment metadata. + + All required parameters must be populated in order to send to Azure. + + :param deployment_id: Required. Gets or sets the deployment identifier. + :type deployment_id: str + :param deployment_type: Required. Gets or sets the deployment type. Possible values include: + "Complete", "Download", "Install". + :type deployment_type: str or ~azure.iot.deviceupdate.models.DeploymentType + :param device_class_id: Gets or sets the device class identifier. + :type device_class_id: str + :param start_date_time: Required. Gets or sets the Deployment start datetime. + :type start_date_time: ~datetime.datetime + :param device_group_type: Required. Gets or sets the device group type. Possible values + include: "All", "Devices", "DeviceGroupDefinitions". + :type device_group_type: str or ~azure.iot.deviceupdate.models.DeviceGroupType + :param device_group_definition: Required. Gets or sets the device group definition. + :type device_group_definition: list[str] + :param update_id: Required. Update identity. + :type update_id: ~azure.iot.deviceupdate.models.UpdateId + :param is_canceled: Boolean flag indicating whether the deployment was canceled. + :type is_canceled: bool + :param is_retried: Boolean flag indicating whether the deployment has been retried. + :type is_retried: bool + :param is_completed: Boolean flag indicating whether the deployment was completed. + :type is_completed: bool + """ + + _validation = { + 'deployment_id': {'required': True}, + 'deployment_type': {'required': True}, + 'start_date_time': {'required': True}, + 'device_group_type': {'required': True}, + 'device_group_definition': {'required': True}, + 'update_id': {'required': True}, + } + + _attribute_map = { + 'deployment_id': {'key': 'deploymentId', 'type': 'str'}, + 'deployment_type': {'key': 'deploymentType', 'type': 'str'}, + 'device_class_id': {'key': 'deviceClassId', 'type': 'str'}, + 'start_date_time': {'key': 'startDateTime', 'type': 'iso-8601'}, + 'device_group_type': {'key': 'deviceGroupType', 'type': 'str'}, + 'device_group_definition': {'key': 'deviceGroupDefinition', 'type': '[str]'}, + 'update_id': {'key': 'updateId', 'type': 'UpdateId'}, + 'is_canceled': {'key': 'isCanceled', 'type': 'bool'}, + 'is_retried': {'key': 'isRetried', 'type': 'bool'}, + 'is_completed': {'key': 'isCompleted', 'type': 'bool'}, + } + + def __init__( + self, + *, + deployment_id: str, + deployment_type: Union[str, "DeploymentType"], + start_date_time: datetime.datetime, + device_group_type: Union[str, "DeviceGroupType"], + device_group_definition: List[str], + update_id: "UpdateId", + device_class_id: Optional[str] = None, + is_canceled: Optional[bool] = None, + is_retried: Optional[bool] = None, + is_completed: Optional[bool] = None, + **kwargs + ): + super(Deployment, self).__init__(**kwargs) + self.deployment_id = deployment_id + self.deployment_type = deployment_type + self.device_class_id = device_class_id + self.start_date_time = start_date_time + self.device_group_type = device_group_type + self.device_group_definition = device_group_definition + self.update_id = update_id + self.is_canceled = is_canceled + self.is_retried = is_retried + self.is_completed = is_completed + + +class DeploymentDeviceState(msrest.serialization.Model): + """Deployment device status. + + All required parameters must be populated in order to send to Azure. + + :param device_id: Required. Device identity. + :type device_id: str + :param retry_count: Required. The number of times this deployment has been retried on this + device. + :type retry_count: int + :param moved_on_to_new_deployment: Required. Boolean flag indicating whether this device is in + a newer deployment and can no longer retry this deployment. + :type moved_on_to_new_deployment: bool + :param device_state: Required. Deployment device state. Possible values include: "Succeeded", + "InProgress", "Failed", "Canceled", "Incompatible". + :type device_state: str or ~azure.iot.deviceupdate.models.DeviceDeploymentState + """ + + _validation = { + 'device_id': {'required': True}, + 'retry_count': {'required': True}, + 'moved_on_to_new_deployment': {'required': True}, + 'device_state': {'required': True}, + } + + _attribute_map = { + 'device_id': {'key': 'deviceId', 'type': 'str'}, + 'retry_count': {'key': 'retryCount', 'type': 'int'}, + 'moved_on_to_new_deployment': {'key': 'movedOnToNewDeployment', 'type': 'bool'}, + 'device_state': {'key': 'deviceState', 'type': 'str'}, + } + + def __init__( + self, + *, + device_id: str, + retry_count: int, + moved_on_to_new_deployment: bool, + device_state: Union[str, "DeviceDeploymentState"], + **kwargs + ): + super(DeploymentDeviceState, self).__init__(**kwargs) + self.device_id = device_id + self.retry_count = retry_count + self.moved_on_to_new_deployment = moved_on_to_new_deployment + self.device_state = device_state + + +class DeploymentDeviceStatesFilter(msrest.serialization.Model): + """Deployment device state filter. + + :param device_id: Device Identifier. + :type device_id: str + :param device_state: The deployment device state. Possible values include: "NotStarted", + "Incompatible", "AlreadyInDeployment", "Canceled", "InProgress", "Failed", "Succeeded". + :type device_state: str or ~azure.iot.deviceupdate.models.DeviceState + """ + + _attribute_map = { + 'device_id': {'key': 'deviceId', 'type': 'str'}, + 'device_state': {'key': 'deviceState', 'type': 'str'}, + } + + def __init__( + self, + *, + device_id: Optional[str] = None, + device_state: Optional[Union[str, "DeviceState"]] = None, + **kwargs + ): + super(DeploymentDeviceStatesFilter, self).__init__(**kwargs) + self.device_id = device_id + self.device_state = device_state + + +class DeploymentFilter(msrest.serialization.Model): + """Deployment filter. + + :param provider: Update provider. + :type provider: str + :param name: Update name. + :type name: str + :param version: Update version. + :type version: str + """ + + _attribute_map = { + 'provider': {'key': 'provider', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'version': {'key': 'version', 'type': 'str'}, + } + + def __init__( + self, + *, + provider: Optional[str] = None, + name: Optional[str] = None, + version: Optional[str] = None, + **kwargs + ): + super(DeploymentFilter, self).__init__(**kwargs) + self.provider = provider + self.name = name + self.version = version + + +class DeploymentStatus(msrest.serialization.Model): + """Deployment status metadata. + + All required parameters must be populated in order to send to Azure. + + :param deployment_state: Required. Gets or sets the state of the deployment. Possible values + include: "Active", "Superseded", "Canceled". + :type deployment_state: str or ~azure.iot.deviceupdate.models.DeploymentState + :param total_devices: Gets or sets the total number of devices in the deployment. + :type total_devices: int + :param devices_incompatible_count: Gets or sets the number of incompatible devices in the + deployment. + :type devices_incompatible_count: int + :param devices_in_progress_count: Gets or sets the number of devices that are currently in + deployment. + :type devices_in_progress_count: int + :param devices_completed_failed_count: Gets or sets the number of devices that have completed + deployment with a failure. + :type devices_completed_failed_count: int + :param devices_completed_succeeded_count: Gets or sets the number of devices which have + successfully completed deployment. + :type devices_completed_succeeded_count: int + :param devices_canceled_count: Gets or sets the number of devices which have had their + deployment canceled. + :type devices_canceled_count: int + """ + + _validation = { + 'deployment_state': {'required': True}, + } + + _attribute_map = { + 'deployment_state': {'key': 'deploymentState', 'type': 'str'}, + 'total_devices': {'key': 'totalDevices', 'type': 'int'}, + 'devices_incompatible_count': {'key': 'devicesIncompatibleCount', 'type': 'int'}, + 'devices_in_progress_count': {'key': 'devicesInProgressCount', 'type': 'int'}, + 'devices_completed_failed_count': {'key': 'devicesCompletedFailedCount', 'type': 'int'}, + 'devices_completed_succeeded_count': {'key': 'devicesCompletedSucceededCount', 'type': 'int'}, + 'devices_canceled_count': {'key': 'devicesCanceledCount', 'type': 'int'}, + } + + def __init__( + self, + *, + deployment_state: Union[str, "DeploymentState"], + total_devices: Optional[int] = None, + devices_incompatible_count: Optional[int] = None, + devices_in_progress_count: Optional[int] = None, + devices_completed_failed_count: Optional[int] = None, + devices_completed_succeeded_count: Optional[int] = None, + devices_canceled_count: Optional[int] = None, + **kwargs + ): + super(DeploymentStatus, self).__init__(**kwargs) + self.deployment_state = deployment_state + self.total_devices = total_devices + self.devices_incompatible_count = devices_incompatible_count + self.devices_in_progress_count = devices_in_progress_count + self.devices_completed_failed_count = devices_completed_failed_count + self.devices_completed_succeeded_count = devices_completed_succeeded_count + self.devices_canceled_count = devices_canceled_count + + +class Device(msrest.serialization.Model): + """Device metadata. + + All required parameters must be populated in order to send to Azure. + + :param device_id: Required. Device identity. + :type device_id: str + :param device_class_id: Required. Device class identity. + :type device_class_id: str + :param manufacturer: Required. Device manufacturer. + :type manufacturer: str + :param model: Required. Device model. + :type model: str + :param group_id: Device group identity. + :type group_id: str + :param last_attempted_update_id: Update identity. + :type last_attempted_update_id: ~azure.iot.deviceupdate.models.UpdateId + :param deployment_status: State of the device in its last deployment. Possible values include: + "Succeeded", "InProgress", "Failed", "Canceled", "Incompatible". + :type deployment_status: str or ~azure.iot.deviceupdate.models.DeviceDeploymentState + :param installed_update_id: Update identity. + :type installed_update_id: ~azure.iot.deviceupdate.models.UpdateId + :param on_latest_update: Required. Boolean flag indicating whether the latest update is + installed on the device. + :type on_latest_update: bool + :param last_deployment_id: The deployment identifier for the last deployment to the device. + :type last_deployment_id: str + """ + + _validation = { + 'device_id': {'required': True}, + 'device_class_id': {'required': True}, + 'manufacturer': {'required': True}, + 'model': {'required': True}, + 'on_latest_update': {'required': True}, + } + + _attribute_map = { + 'device_id': {'key': 'deviceId', 'type': 'str'}, + 'device_class_id': {'key': 'deviceClassId', 'type': 'str'}, + 'manufacturer': {'key': 'manufacturer', 'type': 'str'}, + 'model': {'key': 'model', 'type': 'str'}, + 'group_id': {'key': 'groupId', 'type': 'str'}, + 'last_attempted_update_id': {'key': 'lastAttemptedUpdateId', 'type': 'UpdateId'}, + 'deployment_status': {'key': 'deploymentStatus', 'type': 'str'}, + 'installed_update_id': {'key': 'installedUpdateId', 'type': 'UpdateId'}, + 'on_latest_update': {'key': 'onLatestUpdate', 'type': 'bool'}, + 'last_deployment_id': {'key': 'lastDeploymentId', 'type': 'str'}, + } + + def __init__( + self, + *, + device_id: str, + device_class_id: str, + manufacturer: str, + model: str, + on_latest_update: bool, + group_id: Optional[str] = None, + last_attempted_update_id: Optional["UpdateId"] = None, + deployment_status: Optional[Union[str, "DeviceDeploymentState"]] = None, + installed_update_id: Optional["UpdateId"] = None, + last_deployment_id: Optional[str] = None, + **kwargs + ): + super(Device, self).__init__(**kwargs) + self.device_id = device_id + self.device_class_id = device_class_id + self.manufacturer = manufacturer + self.model = model + self.group_id = group_id + self.last_attempted_update_id = last_attempted_update_id + self.deployment_status = deployment_status + self.installed_update_id = installed_update_id + self.on_latest_update = on_latest_update + self.last_deployment_id = last_deployment_id + + +class DeviceClass(msrest.serialization.Model): + """Device class metadata. + + All required parameters must be populated in order to send to Azure. + + :param device_class_id: Required. The device class identifier. + :type device_class_id: str + :param manufacturer: Required. Device manufacturer. + :type manufacturer: str + :param model: Required. Device model. + :type model: str + :param best_compatible_update_id: Required. Update identity. + :type best_compatible_update_id: ~azure.iot.deviceupdate.models.UpdateId + """ + + _validation = { + 'device_class_id': {'required': True}, + 'manufacturer': {'required': True}, + 'model': {'required': True}, + 'best_compatible_update_id': {'required': True}, + } + + _attribute_map = { + 'device_class_id': {'key': 'deviceClassId', 'type': 'str'}, + 'manufacturer': {'key': 'manufacturer', 'type': 'str'}, + 'model': {'key': 'model', 'type': 'str'}, + 'best_compatible_update_id': {'key': 'bestCompatibleUpdateId', 'type': 'UpdateId'}, + } + + def __init__( + self, + *, + device_class_id: str, + manufacturer: str, + model: str, + best_compatible_update_id: "UpdateId", + **kwargs + ): + super(DeviceClass, self).__init__(**kwargs) + self.device_class_id = device_class_id + self.manufacturer = manufacturer + self.model = model + self.best_compatible_update_id = best_compatible_update_id + + +class DeviceFilter(msrest.serialization.Model): + """Operation status filter. + + :param group_id: Device group identifier. + :type group_id: str + """ + + _attribute_map = { + 'group_id': {'key': 'groupId', 'type': 'str'}, + } + + def __init__( + self, + *, + group_id: Optional[str] = None, + **kwargs + ): + super(DeviceFilter, self).__init__(**kwargs) + self.group_id = group_id + + +class DeviceTag(msrest.serialization.Model): + """Device tag properties. + + All required parameters must be populated in order to send to Azure. + + :param tag_name: Required. Tag name. + :type tag_name: str + :param device_count: Required. Number of devices with this tag. + :type device_count: int + """ + + _validation = { + 'tag_name': {'required': True}, + 'device_count': {'required': True}, + } + + _attribute_map = { + 'tag_name': {'key': 'tagName', 'type': 'str'}, + 'device_count': {'key': 'deviceCount', 'type': 'int'}, + } + + def __init__( + self, + *, + tag_name: str, + device_count: int, + **kwargs + ): + super(DeviceTag, self).__init__(**kwargs) + self.tag_name = tag_name + self.device_count = device_count + + +class Error(msrest.serialization.Model): + """Error details. + + All required parameters must be populated in order to send to Azure. + + :param code: Required. Server defined error code. + :type code: str + :param message: Required. A human-readable representation of the error. + :type message: str + :param target: The target of the error. + :type target: str + :param details: An array of errors that led to the reported error. + :type details: list[~azure.iot.deviceupdate.models.Error] + :param innererror: An object containing more specific information than the current object about + the error. + :type innererror: ~azure.iot.deviceupdate.models.InnerError + :param occurred_date_time: Date and time in UTC when the error occurred. + :type occurred_date_time: ~datetime.datetime + """ + + _validation = { + 'code': {'required': True}, + 'message': {'required': True}, + } + + _attribute_map = { + 'code': {'key': 'code', 'type': 'str'}, + 'message': {'key': 'message', 'type': 'str'}, + 'target': {'key': 'target', 'type': 'str'}, + 'details': {'key': 'details', 'type': '[Error]'}, + 'innererror': {'key': 'innererror', 'type': 'InnerError'}, + 'occurred_date_time': {'key': 'occurredDateTime', 'type': 'iso-8601'}, + } + + def __init__( + self, + *, + code: str, + message: str, + target: Optional[str] = None, + details: Optional[List["Error"]] = None, + innererror: Optional["InnerError"] = None, + occurred_date_time: Optional[datetime.datetime] = None, + **kwargs + ): + super(Error, self).__init__(**kwargs) + self.code = code + self.message = message + self.target = target + self.details = details + self.innererror = innererror + self.occurred_date_time = occurred_date_time + + +class File(msrest.serialization.Model): + """Update file metadata. + + All required parameters must be populated in order to send to Azure. + + :param file_id: Required. File identity, generated by server at import time. + :type file_id: str + :param file_name: Required. File name. + :type file_name: str + :param size_in_bytes: Required. File size in number of bytes. + :type size_in_bytes: long + :param hashes: Required. Mapping of hashing algorithm to base64 encoded hash values. + :type hashes: dict[str, str] + :param mime_type: File MIME type. + :type mime_type: str + :param etag: File ETag. + :type etag: str + """ + + _validation = { + 'file_id': {'required': True}, + 'file_name': {'required': True}, + 'size_in_bytes': {'required': True}, + 'hashes': {'required': True}, + } + + _attribute_map = { + 'file_id': {'key': 'fileId', 'type': 'str'}, + 'file_name': {'key': 'fileName', 'type': 'str'}, + 'size_in_bytes': {'key': 'sizeInBytes', 'type': 'long'}, + 'hashes': {'key': 'hashes', 'type': '{str}'}, + 'mime_type': {'key': 'mimeType', 'type': 'str'}, + 'etag': {'key': 'etag', 'type': 'str'}, + } + + def __init__( + self, + *, + file_id: str, + file_name: str, + size_in_bytes: int, + hashes: Dict[str, str], + mime_type: Optional[str] = None, + etag: Optional[str] = None, + **kwargs + ): + super(File, self).__init__(**kwargs) + self.file_id = file_id + self.file_name = file_name + self.size_in_bytes = size_in_bytes + self.hashes = hashes + self.mime_type = mime_type + self.etag = etag + + +class FileImportMetadata(msrest.serialization.Model): + """Metadata describing an update file. + + All required parameters must be populated in order to send to Azure. + + :param filename: Required. Update file name as specified inside import manifest. + :type filename: str + :param url: Required. Azure Blob location from which the update file can be downloaded by + Device Update for IoT Hub. This is typically a read-only SAS-protected blob URL with an + expiration set to at least 4 hours. + :type url: str + """ + + _validation = { + 'filename': {'required': True}, + 'url': {'required': True}, + } + + _attribute_map = { + 'filename': {'key': 'filename', 'type': 'str'}, + 'url': {'key': 'url', 'type': 'str'}, + } + + def __init__( + self, + *, + filename: str, + url: str, + **kwargs + ): + super(FileImportMetadata, self).__init__(**kwargs) + self.filename = filename + self.url = url + + +class Group(msrest.serialization.Model): + """Group details. + + All required parameters must be populated in order to send to Azure. + + :param group_id: Required. Group identity. + :type group_id: str + :param group_type: Required. Group type. Possible values include: "IoTHubTag". + :type group_type: str or ~azure.iot.deviceupdate.models.GroupType + :param tags: Required. A set of tags. IoT Hub tags. + :type tags: list[str] + :param created_date_time: Required. Date and time when the update was created. + :type created_date_time: str + :param device_count: The number of devices in the group. + :type device_count: int + """ + + _validation = { + 'group_id': {'required': True}, + 'group_type': {'required': True}, + 'tags': {'required': True}, + 'created_date_time': {'required': True}, + } + + _attribute_map = { + 'group_id': {'key': 'groupId', 'type': 'str'}, + 'group_type': {'key': 'groupType', 'type': 'str'}, + 'tags': {'key': 'tags', 'type': '[str]'}, + 'created_date_time': {'key': 'createdDateTime', 'type': 'str'}, + 'device_count': {'key': 'deviceCount', 'type': 'int'}, + } + + def __init__( + self, + *, + group_id: str, + group_type: Union[str, "GroupType"], + tags: List[str], + created_date_time: str, + device_count: Optional[int] = None, + **kwargs + ): + super(Group, self).__init__(**kwargs) + self.group_id = group_id + self.group_type = group_type + self.tags = tags + self.created_date_time = created_date_time + self.device_count = device_count + + +class GroupBestUpdatesFilter(msrest.serialization.Model): + """Group best updates filter. + + :param provider: Update provider. + :type provider: str + :param name: Update name. + :type name: str + :param version: Update version. + :type version: str + """ + + _attribute_map = { + 'provider': {'key': 'provider', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'version': {'key': 'version', 'type': 'str'}, + } + + def __init__( + self, + *, + provider: Optional[str] = None, + name: Optional[str] = None, + version: Optional[str] = None, + **kwargs + ): + super(GroupBestUpdatesFilter, self).__init__(**kwargs) + self.provider = provider + self.name = name + self.version = version + + +class ImportManifestMetadata(msrest.serialization.Model): + """Metadata describing the import manifest, a document which describes the files and other metadata about an update version. + + All required parameters must be populated in order to send to Azure. + + :param url: Required. Azure Blob location from which the import manifest can be downloaded by + Device Update for IoT Hub. This is typically a read-only SAS-protected blob URL with an + expiration set to at least 4 hours. + :type url: str + :param size_in_bytes: Required. File size in number of bytes. + :type size_in_bytes: long + :param hashes: Required. A JSON object containing the hash(es) of the file. At least SHA256 + hash is required. This object can be thought of as a set of key-value pairs where the key is + the hash algorithm, and the value is the hash of the file calculated using that algorithm. + :type hashes: dict[str, str] + """ + + _validation = { + 'url': {'required': True}, + 'size_in_bytes': {'required': True}, + 'hashes': {'required': True}, + } + + _attribute_map = { + 'url': {'key': 'url', 'type': 'str'}, + 'size_in_bytes': {'key': 'sizeInBytes', 'type': 'long'}, + 'hashes': {'key': 'hashes', 'type': '{str}'}, + } + + def __init__( + self, + *, + url: str, + size_in_bytes: int, + hashes: Dict[str, str], + **kwargs + ): + super(ImportManifestMetadata, self).__init__(**kwargs) + self.url = url + self.size_in_bytes = size_in_bytes + self.hashes = hashes + + +class ImportUpdateInput(msrest.serialization.Model): + """Import update input metadata. + + All required parameters must be populated in order to send to Azure. + + :param import_manifest: Required. Import manifest metadata like source URL, file size/hashes, + etc. + :type import_manifest: ~azure.iot.deviceupdate.models.ImportManifestMetadata + :param files: Required. One or more update file properties like filename and source URL. + :type files: list[~azure.iot.deviceupdate.models.FileImportMetadata] + """ + + _validation = { + 'import_manifest': {'required': True}, + 'files': {'required': True, 'min_items': 1}, + } + + _attribute_map = { + 'import_manifest': {'key': 'importManifest', 'type': 'ImportManifestMetadata'}, + 'files': {'key': 'files', 'type': '[FileImportMetadata]'}, + } + + def __init__( + self, + *, + import_manifest: "ImportManifestMetadata", + files: List["FileImportMetadata"], + **kwargs + ): + super(ImportUpdateInput, self).__init__(**kwargs) + self.import_manifest = import_manifest + self.files = files + + +class InnerError(msrest.serialization.Model): + """An object containing more specific information than the current object about the error. + + All required parameters must be populated in order to send to Azure. + + :param code: Required. A more specific error code than what was provided by the containing + error. + :type code: str + :param message: A human-readable representation of the error. + :type message: str + :param error_detail: The internal error or exception message. + :type error_detail: str + :param inner_error: An object containing more specific information than the current object + about the error. + :type inner_error: ~azure.iot.deviceupdate.models.InnerError + """ + + _validation = { + 'code': {'required': True}, + } + + _attribute_map = { + 'code': {'key': 'code', 'type': 'str'}, + 'message': {'key': 'message', 'type': 'str'}, + 'error_detail': {'key': 'errorDetail', 'type': 'str'}, + 'inner_error': {'key': 'innerError', 'type': 'InnerError'}, + } + + def __init__( + self, + *, + code: str, + message: Optional[str] = None, + error_detail: Optional[str] = None, + inner_error: Optional["InnerError"] = None, + **kwargs + ): + super(InnerError, self).__init__(**kwargs) + self.code = code + self.message = message + self.error_detail = error_detail + self.inner_error = inner_error + + +class Operation(msrest.serialization.Model): + """Operation metadata. + + All required parameters must be populated in order to send to Azure. + + :param operation_id: Required. Operation Id. + :type operation_id: str + :param status: Required. Operation status. Possible values include: "Undefined", "NotStarted", + "Running", "Succeeded", "Failed". + :type status: str or ~azure.iot.deviceupdate.models.OperationStatus + :param update_id: The identity of update being imported or deleted. For import, this property + will only be populated after import manifest is processed successfully. + :type update_id: ~azure.iot.deviceupdate.models.UpdateId + :param resource_location: Location of the imported update when operation is successful. + :type resource_location: str + :param error: Operation error encountered, if any. + :type error: ~azure.iot.deviceupdate.models.Error + :param trace_id: Operation correlation identity that can used by Microsoft Support for + troubleshooting. + :type trace_id: str + :param last_action_date_time: Required. Date and time in UTC when the operation status was last + updated. + :type last_action_date_time: ~datetime.datetime + :param created_date_time: Required. Date and time in UTC when the operation was created. + :type created_date_time: ~datetime.datetime + :param etag: Operation ETag. + :type etag: str + """ + + _validation = { + 'operation_id': {'required': True}, + 'status': {'required': True}, + 'last_action_date_time': {'required': True}, + 'created_date_time': {'required': True}, + } + + _attribute_map = { + 'operation_id': {'key': 'operationId', 'type': 'str'}, + 'status': {'key': 'status', 'type': 'str'}, + 'update_id': {'key': 'updateId', 'type': 'UpdateId'}, + 'resource_location': {'key': 'resourceLocation', 'type': 'str'}, + 'error': {'key': 'error', 'type': 'Error'}, + 'trace_id': {'key': 'traceId', 'type': 'str'}, + 'last_action_date_time': {'key': 'lastActionDateTime', 'type': 'iso-8601'}, + 'created_date_time': {'key': 'createdDateTime', 'type': 'iso-8601'}, + 'etag': {'key': 'etag', 'type': 'str'}, + } + + def __init__( + self, + *, + operation_id: str, + status: Union[str, "OperationStatus"], + last_action_date_time: datetime.datetime, + created_date_time: datetime.datetime, + update_id: Optional["UpdateId"] = None, + resource_location: Optional[str] = None, + error: Optional["Error"] = None, + trace_id: Optional[str] = None, + etag: Optional[str] = None, + **kwargs + ): + super(Operation, self).__init__(**kwargs) + self.operation_id = operation_id + self.status = status + self.update_id = update_id + self.resource_location = resource_location + self.error = error + self.trace_id = trace_id + self.last_action_date_time = last_action_date_time + self.created_date_time = created_date_time + self.etag = etag + + +class OperationFilter(msrest.serialization.Model): + """Operation status filter. + + :param status: Operation status filter. Possible values include: "Running", "NotStarted". + :type status: str or ~azure.iot.deviceupdate.models.OperationFilterStatus + """ + + _attribute_map = { + 'status': {'key': 'status', 'type': 'str'}, + } + + def __init__( + self, + *, + status: Optional[Union[str, "OperationFilterStatus"]] = None, + **kwargs + ): + super(OperationFilter, self).__init__(**kwargs) + self.status = status + + +class PageableListOfDeploymentDeviceStates(msrest.serialization.Model): + """The list of deployment device states. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.DeploymentDeviceState] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[DeploymentDeviceState]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + *, + value: Optional[List["DeploymentDeviceState"]] = None, + next_link: Optional[str] = None, + **kwargs + ): + super(PageableListOfDeploymentDeviceStates, self).__init__(**kwargs) + self.value = value + self.next_link = next_link + + +class PageableListOfDeployments(msrest.serialization.Model): + """The list of deployments. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.Deployment] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[Deployment]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + *, + value: Optional[List["Deployment"]] = None, + next_link: Optional[str] = None, + **kwargs + ): + super(PageableListOfDeployments, self).__init__(**kwargs) + self.value = value + self.next_link = next_link + + +class PageableListOfDeviceClasses(msrest.serialization.Model): + """The list of device classes. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.DeviceClass] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[DeviceClass]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + *, + value: Optional[List["DeviceClass"]] = None, + next_link: Optional[str] = None, + **kwargs + ): + super(PageableListOfDeviceClasses, self).__init__(**kwargs) + self.value = value + self.next_link = next_link + + +class PageableListOfDevices(msrest.serialization.Model): + """The list of devices. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.Device] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[Device]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + *, + value: Optional[List["Device"]] = None, + next_link: Optional[str] = None, + **kwargs + ): + super(PageableListOfDevices, self).__init__(**kwargs) + self.value = value + self.next_link = next_link + + +class PageableListOfDeviceTags(msrest.serialization.Model): + """The list of device tags. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.DeviceTag] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[DeviceTag]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + *, + value: Optional[List["DeviceTag"]] = None, + next_link: Optional[str] = None, + **kwargs + ): + super(PageableListOfDeviceTags, self).__init__(**kwargs) + self.value = value + self.next_link = next_link + + +class PageableListOfGroups(msrest.serialization.Model): + """The list of groups. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.Group] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[Group]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + *, + value: Optional[List["Group"]] = None, + next_link: Optional[str] = None, + **kwargs + ): + super(PageableListOfGroups, self).__init__(**kwargs) + self.value = value + self.next_link = next_link + + +class PageableListOfOperations(msrest.serialization.Model): + """The list of operations with server paging support. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.Operation] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[Operation]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + *, + value: Optional[List["Operation"]] = None, + next_link: Optional[str] = None, + **kwargs + ): + super(PageableListOfOperations, self).__init__(**kwargs) + self.value = value + self.next_link = next_link + + +class PageableListOfStrings(msrest.serialization.Model): + """The list of strings with server paging support. + + :param value: The collection of pageable items. + :type value: list[str] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[str]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + *, + value: Optional[List[str]] = None, + next_link: Optional[str] = None, + **kwargs + ): + super(PageableListOfStrings, self).__init__(**kwargs) + self.value = value + self.next_link = next_link + + +class PageableListOfUpdatableDevices(msrest.serialization.Model): + """The list of updatable devices. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.UpdatableDevices] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[UpdatableDevices]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + *, + value: Optional[List["UpdatableDevices"]] = None, + next_link: Optional[str] = None, + **kwargs + ): + super(PageableListOfUpdatableDevices, self).__init__(**kwargs) + self.value = value + self.next_link = next_link + + +class PageableListOfUpdateIds(msrest.serialization.Model): + """The list of update identities. + + :param value: The collection of pageable items. + :type value: list[~azure.iot.deviceupdate.models.UpdateId] + :param next_link: The link to the next page of items. + :type next_link: str + """ + + _attribute_map = { + 'value': {'key': 'value', 'type': '[UpdateId]'}, + 'next_link': {'key': 'nextLink', 'type': 'str'}, + } + + def __init__( + self, + *, + value: Optional[List["UpdateId"]] = None, + next_link: Optional[str] = None, + **kwargs + ): + super(PageableListOfUpdateIds, self).__init__(**kwargs) + self.value = value + self.next_link = next_link + + +class UpdatableDevices(msrest.serialization.Model): + """Update identifier and the number of devices for which the update is applicable. + + All required parameters must be populated in order to send to Azure. + + :param update_id: Required. Update identity. + :type update_id: ~azure.iot.deviceupdate.models.UpdateId + :param device_count: Required. Total number of devices for which the update is applicable. + :type device_count: int + """ + + _validation = { + 'update_id': {'required': True}, + 'device_count': {'required': True}, + } + + _attribute_map = { + 'update_id': {'key': 'updateId', 'type': 'UpdateId'}, + 'device_count': {'key': 'deviceCount', 'type': 'int'}, + } + + def __init__( + self, + *, + update_id: "UpdateId", + device_count: int, + **kwargs + ): + super(UpdatableDevices, self).__init__(**kwargs) + self.update_id = update_id + self.device_count = device_count + + +class Update(msrest.serialization.Model): + """Update metadata. + + All required parameters must be populated in order to send to Azure. + + :param update_id: Required. Update identity. + :type update_id: ~azure.iot.deviceupdate.models.UpdateId + :param update_type: Required. Update type. + :type update_type: str + :param installed_criteria: Required. String interpreted by Device Update client to determine if + the update is installed on the device. + :type installed_criteria: str + :param compatibility: Required. List of update compatibility information. + :type compatibility: list[~azure.iot.deviceupdate.models.Compatibility] + :param manifest_version: Required. Schema version of manifest used to import the update. + :type manifest_version: str + :param imported_date_time: Required. Date and time in UTC when the update was imported. + :type imported_date_time: ~datetime.datetime + :param created_date_time: Required. Date and time in UTC when the update was created. + :type created_date_time: ~datetime.datetime + :param etag: Update ETag. + :type etag: str + """ + + _validation = { + 'update_id': {'required': True}, + 'update_type': {'required': True}, + 'installed_criteria': {'required': True}, + 'compatibility': {'required': True, 'min_items': 1}, + 'manifest_version': {'required': True}, + 'imported_date_time': {'required': True}, + 'created_date_time': {'required': True}, + } + + _attribute_map = { + 'update_id': {'key': 'updateId', 'type': 'UpdateId'}, + 'update_type': {'key': 'updateType', 'type': 'str'}, + 'installed_criteria': {'key': 'installedCriteria', 'type': 'str'}, + 'compatibility': {'key': 'compatibility', 'type': '[Compatibility]'}, + 'manifest_version': {'key': 'manifestVersion', 'type': 'str'}, + 'imported_date_time': {'key': 'importedDateTime', 'type': 'iso-8601'}, + 'created_date_time': {'key': 'createdDateTime', 'type': 'iso-8601'}, + 'etag': {'key': 'etag', 'type': 'str'}, + } + + def __init__( + self, + *, + update_id: "UpdateId", + update_type: str, + installed_criteria: str, + compatibility: List["Compatibility"], + manifest_version: str, + imported_date_time: datetime.datetime, + created_date_time: datetime.datetime, + etag: Optional[str] = None, + **kwargs + ): + super(Update, self).__init__(**kwargs) + self.update_id = update_id + self.update_type = update_type + self.installed_criteria = installed_criteria + self.compatibility = compatibility + self.manifest_version = manifest_version + self.imported_date_time = imported_date_time + self.created_date_time = created_date_time + self.etag = etag + + +class UpdateCompliance(msrest.serialization.Model): + """Update compliance information. + + All required parameters must be populated in order to send to Azure. + + :param total_device_count: Required. Total number of devices. + :type total_device_count: int + :param on_latest_update_device_count: Required. Number of devices on the latest update. + :type on_latest_update_device_count: int + :param new_updates_available_device_count: Required. Number of devices with a newer update + available. + :type new_updates_available_device_count: int + :param updates_in_progress_device_count: Required. Number of devices with update in-progress. + :type updates_in_progress_device_count: int + """ + + _validation = { + 'total_device_count': {'required': True}, + 'on_latest_update_device_count': {'required': True}, + 'new_updates_available_device_count': {'required': True}, + 'updates_in_progress_device_count': {'required': True}, + } + + _attribute_map = { + 'total_device_count': {'key': 'totalDeviceCount', 'type': 'int'}, + 'on_latest_update_device_count': {'key': 'onLatestUpdateDeviceCount', 'type': 'int'}, + 'new_updates_available_device_count': {'key': 'newUpdatesAvailableDeviceCount', 'type': 'int'}, + 'updates_in_progress_device_count': {'key': 'updatesInProgressDeviceCount', 'type': 'int'}, + } + + def __init__( + self, + *, + total_device_count: int, + on_latest_update_device_count: int, + new_updates_available_device_count: int, + updates_in_progress_device_count: int, + **kwargs + ): + super(UpdateCompliance, self).__init__(**kwargs) + self.total_device_count = total_device_count + self.on_latest_update_device_count = on_latest_update_device_count + self.new_updates_available_device_count = new_updates_available_device_count + self.updates_in_progress_device_count = updates_in_progress_device_count + + +class UpdateId(msrest.serialization.Model): + """Update identifier. + + All required parameters must be populated in order to send to Azure. + + :param provider: Required. Update provider. + :type provider: str + :param name: Required. Update name. + :type name: str + :param version: Required. Update version. + :type version: str + """ + + _validation = { + 'provider': {'required': True}, + 'name': {'required': True}, + 'version': {'required': True}, + } + + _attribute_map = { + 'provider': {'key': 'provider', 'type': 'str'}, + 'name': {'key': 'name', 'type': 'str'}, + 'version': {'key': 'version', 'type': 'str'}, + } + + def __init__( + self, + *, + provider: str, + name: str, + version: str, + **kwargs + ): + super(UpdateId, self).__init__(**kwargs) + self.provider = provider + self.name = name + self.version = version diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/operations/__init__.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/operations/__init__.py new file mode 100644 index 000000000000..0bb67dd3a9fe --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/operations/__init__.py @@ -0,0 +1,17 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- + +from ._updates_operations import UpdatesOperations +from ._devices_operations import DevicesOperations +from ._deployments_operations import DeploymentsOperations + +__all__ = [ + 'UpdatesOperations', + 'DevicesOperations', + 'DeploymentsOperations', +] diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/operations/_deployments_operations.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/operations/_deployments_operations.py new file mode 100644 index 000000000000..9662c63f679b --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/operations/_deployments_operations.py @@ -0,0 +1,537 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import TYPE_CHECKING +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.paging import ItemPaged +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpRequest, HttpResponse + +from .. import models as _models + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Callable, Dict, Generic, Iterable, Optional, TypeVar + + T = TypeVar('T') + ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +class DeploymentsOperations(object): + """DeploymentsOperations operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.iot.deviceupdate.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = _models + + def __init__(self, client, config, serializer, deserializer): + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def get_all_deployments( + self, + filter=None, # type: Optional[str] + **kwargs # type: Any + ): + # type: (...) -> Iterable["_models.PageableListOfDeployments"] + """Gets a list of deployments. + + :param filter: Restricts the set of deployments returned. You can filter on update Provider, + Name and Version property. + :type filter: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfDeployments or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.iot.deviceupdate.models.PageableListOfDeployments] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfDeployments"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_all_deployments.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + if filter is not None: + query_parameters['$filter'] = self._serialize.query("filter", filter, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfDeployments', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + get_all_deployments.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments'} # type: ignore + + def get_deployment( + self, + deployment_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> "_models.Deployment" + """Gets the properties of a deployment. + + :param deployment_id: Deployment identifier. + :type deployment_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Deployment, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Deployment + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.Deployment"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_deployment.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('Deployment', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_deployment.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments/{deploymentId}'} # type: ignore + + def create_or_update_deployment( + self, + deployment_id, # type: str + deployment, # type: "_models.Deployment" + **kwargs # type: Any + ): + # type: (...) -> "_models.Deployment" + """Creates or updates a deployment. + + :param deployment_id: Deployment identifier. + :type deployment_id: str + :param deployment: The deployment properties. + :type deployment: ~azure.iot.deviceupdate.models.Deployment + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Deployment, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Deployment + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.Deployment"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self.create_or_update_deployment.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(deployment, 'Deployment') + body_content_kwargs['content'] = body_content + request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('Deployment', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + create_or_update_deployment.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments/{deploymentId}'} # type: ignore + + def delete_deployment( + self, + deployment_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Deletes a deployment. + + :param deployment_id: Deployment identifier. + :type deployment_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: None, or the result of cls(response) + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + # Construct URL + url = self.delete_deployment.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + delete_deployment.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments/{deploymentId}'} # type: ignore + + def get_deployment_status( + self, + deployment_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> "_models.DeploymentStatus" + """Gets the status of a deployment including a breakdown of how many devices in the deployment are + in progress, completed, or failed. + + :param deployment_id: Deployment identifier. + :type deployment_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: DeploymentStatus, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.DeploymentStatus + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.DeploymentStatus"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_deployment_status.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('DeploymentStatus', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_deployment_status.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments/{deploymentId}/status'} # type: ignore + + def get_deployment_devices( + self, + deployment_id, # type: str + filter=None, # type: Optional[str] + **kwargs # type: Any + ): + # type: (...) -> Iterable["_models.PageableListOfDeploymentDeviceStates"] + """Gets a list of devices in a deployment along with their state. Useful for getting a list of + failed devices. + + :param deployment_id: Deployment identifier. + :type deployment_id: str + :param filter: Restricts the set of deployment device states returned. You can filter on + deviceId and/or deviceState. + :type filter: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfDeploymentDeviceStates or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.iot.deviceupdate.models.PageableListOfDeploymentDeviceStates] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfDeploymentDeviceStates"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_deployment_devices.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + if filter is not None: + query_parameters['$filter'] = self._serialize.query("filter", filter, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfDeploymentDeviceStates', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + get_deployment_devices.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments/{deploymentId}/devicestates'} # type: ignore + + def cancel_deployment( + self, + deployment_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> "_models.Deployment" + """Cancels a deployment. + + :param deployment_id: Deployment identifier. + :type deployment_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Deployment, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Deployment + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.Deployment"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + action = "cancel" + accept = "application/json" + + # Construct URL + url = self.cancel_deployment.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['action'] = self._serialize.query("action", action, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.post(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('Deployment', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + cancel_deployment.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments/{deploymentId}'} # type: ignore + + def retry_deployment( + self, + deployment_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> "_models.Deployment" + """Retries a deployment with failed devices. + + :param deployment_id: Deployment identifier. + :type deployment_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Deployment, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Deployment + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.Deployment"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + action = "retry" + accept = "application/json" + + # Construct URL + url = self.retry_deployment.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deploymentId': self._serialize.url("deployment_id", deployment_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['action'] = self._serialize.query("action", action, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.post(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('Deployment', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + retry_deployment.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deployments/{deploymentId}'} # type: ignore diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/operations/_devices_operations.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/operations/_devices_operations.py new file mode 100644 index 000000000000..f39128ed524e --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/operations/_devices_operations.py @@ -0,0 +1,1004 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import TYPE_CHECKING +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.paging import ItemPaged +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpRequest, HttpResponse + +from .. import models as _models + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Callable, Dict, Generic, Iterable, Optional, TypeVar + + T = TypeVar('T') + ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +class DevicesOperations(object): + """DevicesOperations operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.iot.deviceupdate.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = _models + + def __init__(self, client, config, serializer, deserializer): + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def get_all_device_classes( + self, + **kwargs # type: Any + ): + # type: (...) -> Iterable["_models.PageableListOfDeviceClasses"] + """Gets a list of all device classes (unique combinations of device manufacturer and model) for + all devices connected to Device Update for IoT Hub. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfDeviceClasses or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.iot.deviceupdate.models.PageableListOfDeviceClasses] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfDeviceClasses"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_all_device_classes.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfDeviceClasses', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + get_all_device_classes.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deviceclasses'} # type: ignore + + def get_device_class( + self, + device_class_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> "_models.DeviceClass" + """Gets the properties of a device class. + + :param device_class_id: Device class identifier. + :type device_class_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: DeviceClass, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.DeviceClass + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.DeviceClass"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_device_class.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deviceClassId': self._serialize.url("device_class_id", device_class_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('DeviceClass', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_device_class.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deviceclasses/{deviceClassId}'} # type: ignore + + def get_device_class_device_ids( + self, + device_class_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> Iterable["_models.PageableListOfStrings"] + """Gets a list of device identifiers in a device class. + + :param device_class_id: Device class identifier. + :type device_class_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfStrings or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.iot.deviceupdate.models.PageableListOfStrings] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfStrings"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_device_class_device_ids.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deviceClassId': self._serialize.url("device_class_id", device_class_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deviceClassId': self._serialize.url("device_class_id", device_class_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfStrings', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + get_device_class_device_ids.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deviceclasses/{deviceClassId}/deviceids'} # type: ignore + + def get_device_class_installable_updates( + self, + device_class_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> Iterable["_models.PageableListOfUpdateIds"] + """Gets a list of installable updates for a device class. + + :param device_class_id: Device class identifier. + :type device_class_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfUpdateIds or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.iot.deviceupdate.models.PageableListOfUpdateIds] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfUpdateIds"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_device_class_installable_updates.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deviceClassId': self._serialize.url("device_class_id", device_class_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deviceClassId': self._serialize.url("device_class_id", device_class_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfUpdateIds', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + get_device_class_installable_updates.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/deviceclasses/{deviceClassId}/installableupdates'} # type: ignore + + def get_all_devices( + self, + filter=None, # type: Optional[str] + **kwargs # type: Any + ): + # type: (...) -> Iterable["_models.PageableListOfDevices"] + """Gets a list of devices connected to Device Update for IoT Hub. + + :param filter: Restricts the set of devices returned. You can only filter on device GroupId. + :type filter: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfDevices or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.iot.deviceupdate.models.PageableListOfDevices] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfDevices"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_all_devices.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + if filter is not None: + query_parameters['$filter'] = self._serialize.query("filter", filter, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfDevices', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + get_all_devices.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/devices'} # type: ignore + + def get_device( + self, + device_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> "_models.Device" + """Gets the device properties and latest deployment status for a device connected to Device Update + for IoT Hub. + + :param device_id: Device identifier in Azure IOT Hub. + :type device_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Device, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Device + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.Device"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_device.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'deviceId': self._serialize.url("device_id", device_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('Device', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_device.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/devices/{deviceId}'} # type: ignore + + def get_update_compliance( + self, + **kwargs # type: Any + ): + # type: (...) -> "_models.UpdateCompliance" + """Gets the breakdown of how many devices are on their latest update, have new updates available, + or are in progress receiving new updates. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: UpdateCompliance, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.UpdateCompliance + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.UpdateCompliance"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_update_compliance.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('UpdateCompliance', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_update_compliance.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/updatecompliance'} # type: ignore + + def get_all_device_tags( + self, + **kwargs # type: Any + ): + # type: (...) -> Iterable["_models.PageableListOfDeviceTags"] + """Gets a list of available group device tags for all devices connected to Device Update for IoT + Hub. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfDeviceTags or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.iot.deviceupdate.models.PageableListOfDeviceTags] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfDeviceTags"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_all_device_tags.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfDeviceTags', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + get_all_device_tags.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/devicetags'} # type: ignore + + def get_device_tag( + self, + tag_name, # type: str + **kwargs # type: Any + ): + # type: (...) -> "_models.DeviceTag" + """Gets a count of how many devices have a device tag. + + :param tag_name: Tag name. + :type tag_name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: DeviceTag, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.DeviceTag + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.DeviceTag"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_device_tag.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'tagName': self._serialize.url("tag_name", tag_name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('DeviceTag', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_device_tag.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/devicetags/{tagName}'} # type: ignore + + def get_all_groups( + self, + **kwargs # type: Any + ): + # type: (...) -> Iterable["_models.PageableListOfGroups"] + """Gets a list of all device groups. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfGroups or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.iot.deviceupdate.models.PageableListOfGroups] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfGroups"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_all_groups.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfGroups', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + get_all_groups.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/groups'} # type: ignore + + def get_group( + self, + group_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> "_models.Group" + """Gets the properties of a group. + + :param group_id: Group identifier. + :type group_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Group, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Group + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.Group"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_group.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'groupId': self._serialize.url("group_id", group_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('Group', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_group.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/groups/{groupId}'} # type: ignore + + def create_or_update_group( + self, + group_id, # type: str + group, # type: "_models.Group" + **kwargs # type: Any + ): + # type: (...) -> "_models.Group" + """Create or update a device group. + + :param group_id: Group identifier. + :type group_id: str + :param group: The group properties. + :type group: ~azure.iot.deviceupdate.models.Group + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Group, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Group + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.Group"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + content_type = kwargs.pop("content_type", "application/json") + accept = "application/json" + + # Construct URL + url = self.create_or_update_group.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'groupId': self._serialize.url("group_id", group_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(group, 'Group') + body_content_kwargs['content'] = body_content + request = self._client.put(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('Group', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + create_or_update_group.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/groups/{groupId}'} # type: ignore + + def delete_group( + self, + group_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Deletes a device group. + + :param group_id: Group identifier. + :type group_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: None, or the result of cls(response) + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + # Construct URL + url = self.delete_group.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'groupId': self._serialize.url("group_id", group_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 204]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + if cls: + return cls(pipeline_response, None, {}) + + delete_group.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/groups/{groupId}'} # type: ignore + + def get_group_update_compliance( + self, + group_id, # type: str + **kwargs # type: Any + ): + # type: (...) -> "_models.UpdateCompliance" + """Get group update compliance information such as how many devices are on their latest update, + how many need new updates, and how many are in progress on receiving a new update. + + :param group_id: Group identifier. + :type group_id: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: UpdateCompliance, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.UpdateCompliance + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.UpdateCompliance"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + # Construct URL + url = self.get_group_update_compliance.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'groupId': self._serialize.url("group_id", group_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = self._deserialize('UpdateCompliance', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_group_update_compliance.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/groups/{groupId}/updateCompliance'} # type: ignore + + def get_group_best_updates( + self, + group_id, # type: str + filter=None, # type: Optional[str] + **kwargs # type: Any + ): + # type: (...) -> Iterable["_models.PageableListOfUpdatableDevices"] + """Get the best available updates for a group and a count of how many devices need each update. + + :param group_id: Group identifier. + :type group_id: str + :param filter: Restricts the set of bestUpdates returned. You can filter on update Provider, + Name and Version property. + :type filter: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfUpdatableDevices or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.iot.deviceupdate.models.PageableListOfUpdatableDevices] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfUpdatableDevices"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_group_best_updates.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'groupId': self._serialize.url("group_id", group_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + if filter is not None: + query_parameters['$filter'] = self._serialize.query("filter", filter, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'groupId': self._serialize.url("group_id", group_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfUpdatableDevices', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + get_group_best_updates.metadata = {'url': '/deviceupdate/{instanceId}/v2/management/groups/{groupId}/bestUpdates'} # type: ignore diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/operations/_updates_operations.py b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/operations/_updates_operations.py new file mode 100644 index 000000000000..a6a6e32dec4a --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/operations/_updates_operations.py @@ -0,0 +1,781 @@ +# coding=utf-8 +# -------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# Code generated by Microsoft (R) AutoRest Code Generator. +# Changes may cause incorrect behavior and will be lost if the code is regenerated. +# -------------------------------------------------------------------------- +from typing import TYPE_CHECKING +import warnings + +from azure.core.exceptions import ClientAuthenticationError, HttpResponseError, ResourceExistsError, ResourceNotFoundError, map_error +from azure.core.paging import ItemPaged +from azure.core.pipeline import PipelineResponse +from azure.core.pipeline.transport import HttpRequest, HttpResponse + +from .. import models as _models + +if TYPE_CHECKING: + # pylint: disable=unused-import,ungrouped-imports + from typing import Any, Callable, Dict, Generic, Iterable, Optional, TypeVar + + T = TypeVar('T') + ClsType = Optional[Callable[[PipelineResponse[HttpRequest, HttpResponse], T, Dict[str, Any]], Any]] + +class UpdatesOperations(object): + """UpdatesOperations operations. + + You should not instantiate this class directly. Instead, you should create a Client instance that + instantiates it for you and attaches it as an attribute. + + :ivar models: Alias to model classes used in this operation group. + :type models: ~azure.iot.deviceupdate.models + :param client: Client for service requests. + :param config: Configuration of service client. + :param serializer: An object model serializer. + :param deserializer: An object model deserializer. + """ + + models = _models + + def __init__(self, client, config, serializer, deserializer): + self._client = client + self._serialize = serializer + self._deserialize = deserializer + self._config = config + + def import_update( + self, + update_to_import, # type: "_models.ImportUpdateInput" + **kwargs # type: Any + ): + # type: (...) -> None + """Import new update version. + + :param update_to_import: The update to be imported. + :type update_to_import: ~azure.iot.deviceupdate.models.ImportUpdateInput + :keyword callable cls: A custom type or function that will be passed the direct response + :return: None, or the result of cls(response) + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + action = "import" + content_type = kwargs.pop("content_type", "application/json") + + # Construct URL + url = self.import_update.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + query_parameters['action'] = self._serialize.query("action", action, 'str') + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Content-Type'] = self._serialize.header("content_type", content_type, 'str') + + body_content_kwargs = {} # type: Dict[str, Any] + body_content = self._serialize.body(update_to_import, 'ImportUpdateInput') + body_content_kwargs['content'] = body_content + request = self._client.post(url, query_parameters, header_parameters, **body_content_kwargs) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + response_headers['Location']=self._deserialize('str', response.headers.get('Location')) + response_headers['Operation-Location']=self._deserialize('str', response.headers.get('Operation-Location')) + + if cls: + return cls(pipeline_response, None, response_headers) + + import_update.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates'} # type: ignore + + def get_update( + self, + provider, # type: str + name, # type: str + version, # type: str + access_condition=None, # type: Optional["_models.AccessCondition"] + **kwargs # type: Any + ): + # type: (...) -> Optional["_models.Update"] + """Get a specific update version. + + :param provider: Update provider. + :type provider: str + :param name: Update name. + :type name: str + :param version: Update version. + :type version: str + :param access_condition: Parameter group. + :type access_condition: ~azure.iot.deviceupdate.models.AccessCondition + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Update, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Update or None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[Optional["_models.Update"]] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + _if_none_match = None + if access_condition is not None: + _if_none_match = access_condition.if_none_match + accept = "application/json" + + # Construct URL + url = self.get_update.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + 'name': self._serialize.url("name", name, 'str'), + 'version': self._serialize.url("version", version, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + if _if_none_match is not None: + header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 304]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = None + if response.status_code == 200: + deserialized = self._deserialize('Update', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_update.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/providers/{provider}/names/{name}/versions/{version}'} # type: ignore + + def delete_update( + self, + provider, # type: str + name, # type: str + version, # type: str + **kwargs # type: Any + ): + # type: (...) -> None + """Delete a specific update version. + + :param provider: Update provider. + :type provider: str + :param name: Update name. + :type name: str + :param version: Update version. + :type version: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: None, or the result of cls(response) + :rtype: None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[None] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + # Construct URL + url = self.delete_update.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + 'name': self._serialize.url("name", name, 'str'), + 'version': self._serialize.url("version", version, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + + request = self._client.delete(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [202]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + response_headers['Location']=self._deserialize('str', response.headers.get('Location')) + response_headers['Operation-Location']=self._deserialize('str', response.headers.get('Operation-Location')) + + if cls: + return cls(pipeline_response, None, response_headers) + + delete_update.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/providers/{provider}/names/{name}/versions/{version}'} # type: ignore + + def get_providers( + self, + **kwargs # type: Any + ): + # type: (...) -> Iterable["_models.PageableListOfStrings"] + """Get a list of all update providers that have been imported to Device Update for IoT Hub. + + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfStrings or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.iot.deviceupdate.models.PageableListOfStrings] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfStrings"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_providers.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfStrings', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + get_providers.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/providers'} # type: ignore + + def get_names( + self, + provider, # type: str + **kwargs # type: Any + ): + # type: (...) -> Iterable["_models.PageableListOfStrings"] + """Get a list of all update names that match the specified provider. + + :param provider: Update provider. + :type provider: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfStrings or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.iot.deviceupdate.models.PageableListOfStrings] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfStrings"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_names.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfStrings', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + get_names.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/providers/{provider}/names'} # type: ignore + + def get_versions( + self, + provider, # type: str + name, # type: str + **kwargs # type: Any + ): + # type: (...) -> Iterable["_models.PageableListOfStrings"] + """Get a list of all update versions that match the specified provider and name. + + :param provider: Update provider. + :type provider: str + :param name: Update name. + :type name: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfStrings or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.iot.deviceupdate.models.PageableListOfStrings] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfStrings"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_versions.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + 'name': self._serialize.url("name", name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + 'name': self._serialize.url("name", name, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfStrings', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + get_versions.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/providers/{provider}/names/{name}/versions'} # type: ignore + + def get_files( + self, + provider, # type: str + name, # type: str + version, # type: str + **kwargs # type: Any + ): + # type: (...) -> Iterable["_models.PageableListOfStrings"] + """Get a list of all update file identifiers for the specified version. + + :param provider: Update provider. + :type provider: str + :param name: Update name. + :type name: str + :param version: Update version. + :type version: str + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfStrings or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.iot.deviceupdate.models.PageableListOfStrings] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfStrings"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_files.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + 'name': self._serialize.url("name", name, 'str'), + 'version': self._serialize.url("version", version, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + 'name': self._serialize.url("name", name, 'str'), + 'version': self._serialize.url("version", version, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfStrings', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + get_files.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/providers/{provider}/names/{name}/versions/{version}/files'} # type: ignore + + def get_file( + self, + provider, # type: str + name, # type: str + version, # type: str + file_id, # type: str + access_condition=None, # type: Optional["_models.AccessCondition"] + **kwargs # type: Any + ): + # type: (...) -> Optional["_models.File"] + """Get a specific update file from the version. + + :param provider: Update provider. + :type provider: str + :param name: Update name. + :type name: str + :param version: Update version. + :type version: str + :param file_id: File identifier. + :type file_id: str + :param access_condition: Parameter group. + :type access_condition: ~azure.iot.deviceupdate.models.AccessCondition + :keyword callable cls: A custom type or function that will be passed the direct response + :return: File, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.File or None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[Optional["_models.File"]] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + _if_none_match = None + if access_condition is not None: + _if_none_match = access_condition.if_none_match + accept = "application/json" + + # Construct URL + url = self.get_file.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'provider': self._serialize.url("provider", provider, 'str'), + 'name': self._serialize.url("name", name, 'str'), + 'version': self._serialize.url("version", version, 'str'), + 'fileId': self._serialize.url("file_id", file_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + if _if_none_match is not None: + header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 304]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + deserialized = None + if response.status_code == 200: + deserialized = self._deserialize('File', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, {}) + + return deserialized + get_file.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/providers/{provider}/names/{name}/versions/{version}/files/{fileId}'} # type: ignore + + def get_operations( + self, + filter=None, # type: Optional[str] + top=None, # type: Optional[int] + **kwargs # type: Any + ): + # type: (...) -> Iterable["_models.PageableListOfOperations"] + """Get a list of all import update operations. Completed operations are kept for 7 days before + auto-deleted. Delete operations are not returned by this API version. + + :param filter: Restricts the set of operations returned. Only one specific filter is supported: + "status eq 'NotStarted' or status eq 'Running'". + :type filter: str + :param top: Specifies a non-negative integer n that limits the number of items returned from a + collection. The service returns the number of available items up to but not greater than the + specified value n. + :type top: int + :keyword callable cls: A custom type or function that will be passed the direct response + :return: An iterator like instance of either PageableListOfOperations or the result of cls(response) + :rtype: ~azure.core.paging.ItemPaged[~azure.iot.deviceupdate.models.PageableListOfOperations] + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType["_models.PageableListOfOperations"] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + accept = "application/json" + + def prepare_request(next_link=None): + # Construct headers + header_parameters = {} # type: Dict[str, Any] + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + if not next_link: + # Construct URL + url = self.get_operations.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + if filter is not None: + query_parameters['$filter'] = self._serialize.query("filter", filter, 'str') + if top is not None: + query_parameters['$top'] = self._serialize.query("top", top, 'int') + + request = self._client.get(url, query_parameters, header_parameters) + else: + url = next_link + query_parameters = {} # type: Dict[str, Any] + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + } + url = self._client.format_url(url, **path_format_arguments) + request = self._client.get(url, query_parameters, header_parameters) + return request + + def extract_data(pipeline_response): + deserialized = self._deserialize('PageableListOfOperations', pipeline_response) + list_of_elem = deserialized.value + if cls: + list_of_elem = cls(list_of_elem) + return deserialized.next_link or None, iter(list_of_elem) + + def get_next(next_link=None): + request = prepare_request(next_link) + + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + return pipeline_response + + return ItemPaged( + get_next, extract_data + ) + get_operations.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/operations'} # type: ignore + + def get_operation( + self, + operation_id, # type: str + access_condition=None, # type: Optional["_models.AccessCondition"] + **kwargs # type: Any + ): + # type: (...) -> Optional["_models.Operation"] + """Retrieve operation status. + + :param operation_id: Operation identifier. + :type operation_id: str + :param access_condition: Parameter group. + :type access_condition: ~azure.iot.deviceupdate.models.AccessCondition + :keyword callable cls: A custom type or function that will be passed the direct response + :return: Operation, or the result of cls(response) + :rtype: ~azure.iot.deviceupdate.models.Operation or None + :raises: ~azure.core.exceptions.HttpResponseError + """ + cls = kwargs.pop('cls', None) # type: ClsType[Optional["_models.Operation"]] + error_map = { + 401: ClientAuthenticationError, 404: ResourceNotFoundError, 409: ResourceExistsError + } + error_map.update(kwargs.pop('error_map', {})) + + _if_none_match = None + if access_condition is not None: + _if_none_match = access_condition.if_none_match + accept = "application/json" + + # Construct URL + url = self.get_operation.metadata['url'] # type: ignore + path_format_arguments = { + 'accountEndpoint': self._serialize.url("self._config.account_endpoint", self._config.account_endpoint, 'str', skip_quote=True), + 'instanceId': self._serialize.url("self._config.instance_id", self._config.instance_id, 'str', skip_quote=True), + 'operationId': self._serialize.url("operation_id", operation_id, 'str'), + } + url = self._client.format_url(url, **path_format_arguments) + + # Construct parameters + query_parameters = {} # type: Dict[str, Any] + + # Construct headers + header_parameters = {} # type: Dict[str, Any] + if _if_none_match is not None: + header_parameters['If-None-Match'] = self._serialize.header("if_none_match", _if_none_match, 'str') + header_parameters['Accept'] = self._serialize.header("accept", accept, 'str') + + request = self._client.get(url, query_parameters, header_parameters) + pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs) + response = pipeline_response.http_response + + if response.status_code not in [200, 304]: + map_error(status_code=response.status_code, response=response, error_map=error_map) + raise HttpResponseError(response=response) + + response_headers = {} + deserialized = None + if response.status_code == 200: + response_headers['Retry-After']=self._deserialize('str', response.headers.get('Retry-After')) + deserialized = self._deserialize('Operation', pipeline_response) + + if cls: + return cls(pipeline_response, deserialized, response_headers) + + return deserialized + get_operation.metadata = {'url': '/deviceupdate/{instanceId}/v2/updates/operations/{operationId}'} # type: ignore diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/py.typed b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/py.typed new file mode 100644 index 000000000000..e5aff4f83af8 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/azure/iot/deviceupdate/py.typed @@ -0,0 +1 @@ +# Marker file for PEP 561. \ No newline at end of file diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/dev_requirements.txt b/sdk/deviceupdate/azure-iot-deviceupdate/dev_requirements.txt new file mode 100644 index 000000000000..900f8ee865b4 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/dev_requirements.txt @@ -0,0 +1,5 @@ +-e ../../../tools/azure-sdk-tools +-e ../../../tools/azure-devtools +../../core/azure-core +-e ../../identity/azure-identity +../../storage/azure-storage-blob diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/samples/consts.py b/sdk/deviceupdate/azure-iot-deviceupdate/samples/consts.py new file mode 100644 index 000000000000..747b6a49ed2f --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/samples/consts.py @@ -0,0 +1,5 @@ +MANUFACTURER = "Contoso" +MODEL = "Virtual-Machine" +FILE_NAME = "setup.exe" +BLOB_CONTAINER = "test" +DEFAULT_RETRY_AFTER = 5 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/samples/contentfactory.py b/sdk/deviceupdate/azure-iot-deviceupdate/samples/contentfactory.py new file mode 100644 index 000000000000..acefe39440c8 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/samples/contentfactory.py @@ -0,0 +1,104 @@ +from azure.iot.deviceupdate.models import ImportUpdateInput, ImportManifestMetadata, FileImportMetadata +from datetime import datetime, timedelta +from azure.storage.blob import BlobServiceClient, generate_blob_sas, PublicAccess, BlobSasPermissions +from samples.consts import FILE_NAME + +import json +import tempfile +import hashlib +import base64 +import os +import uuid + + +class ContentFactory: + def __init__(self, storage_name, storage_key, blob_container): + self._storage_name = storage_name + self._storage_key = storage_key + self._connection_string = \ + f"DefaultEndpointsProtocol=https;AccountName={storage_name};AccountKey={storage_key};EndpointSuffix=core.windows.net" + self._blob_container = blob_container + + def create_import_update(self, manufacturer, name, version): + payload_file_id = self._generate_storage_id() + payload_local_file = self._create_adu_payload_file(FILE_NAME, payload_file_id) + payload_file_size = self._get_file_size(payload_local_file) + payload_file_hash = self._get_file_hash(payload_local_file) + payload_url = self._upload_file(payload_local_file, payload_file_id) + + import_manifest_file_id = self._generate_storage_id() + import_manifest_file = self._create_import_manifest( + manufacturer, name, version, + FILE_NAME, payload_file_size, payload_file_hash, + [{"DeviceManufacturer": manufacturer.lower(), "DeviceModel": name.lower()}], + import_manifest_file_id) + import_manifest_file_size = self._get_file_size(import_manifest_file) + import_manifest_file_hash = self._get_file_hash(import_manifest_file) + import_manifest_url = self._upload_file(import_manifest_file, import_manifest_file_id) + + return self._create_import_body(import_manifest_url, import_manifest_file_size, import_manifest_file_hash, + FILE_NAME, payload_url) + + def _create_adu_payload_file(self, filename, file_id): + content = {"Scenario": "DeviceUpdateClientSample", + "Timestamp": datetime.utcnow().strftime("%m/%d/%Y, %H:%M:%S")} + file_path = f"{tempfile.gettempdir()}\\{file_id}" + file = open(file_path, "w+") + file.write(json.dumps(content)) + file.close() + return file_path + + def _create_import_manifest(self, manufacturer, name, version, file_name, file_size, file_hash, compatibility_ids, + file_id): + content = {"UpdateId": {"Provider": manufacturer, "Name": name, "Version": version}, + "CreatedDateTime": f"{datetime.utcnow().isoformat()}Z", + "Files": [{"FileName": file_name, "SizeInBytes": file_size, "Hashes": {"SHA256": file_hash}}], + "Compatibility": compatibility_ids, "ManifestVersion": "2.0", "InstalledCriteria": "1.2.3.4", + "UpdateType": "microsoft/swupdate:1"} + file_path = f"{tempfile.gettempdir()}\\{file_id}" + file = open(file_path, "w+") + file.write(json.dumps(content)) + file.close() + return file_path + + def _create_import_body(self, import_manifest_url, import_manifest_file_size, import_manifest_file_hash, + file_name, payload_url): + return ImportUpdateInput( + import_manifest=ImportManifestMetadata( + url=import_manifest_url, + size_in_bytes=import_manifest_file_size, + hashes={"SHA256": import_manifest_file_hash}), + files=[FileImportMetadata(filename=file_name, url=payload_url)]) + + + def _get_file_size(self, file_path): + return os.path.getsize(file_path) + + def _get_file_hash(self, file_path): + with open(file_path, "rb") as f: + bytes = f.read() # read entire file as bytes + return base64.b64encode(hashlib.sha256(bytes).digest()).decode("utf-8") + + def _generate_storage_id(self): + return uuid.uuid4().hex + + def _upload_file(self, file_path, storage_id): + blob_service_client = BlobServiceClient.from_connection_string(conn_str=self._connection_string) + try: + blob_service_client.create_container(self._blob_container, public_access=PublicAccess.Container) + except: + pass + blob_client = blob_service_client.get_blob_client(container=self._blob_container, blob=storage_id) + + with open(file_path, "rb") as data: + blob_client.upload_blob(data) + + token = generate_blob_sas( + account_name=self._storage_name, + account_key=self._storage_key, + container_name=self._blob_container, + blob_name=storage_id, + permission=BlobSasPermissions(read=True), + expiry=datetime.utcnow() + timedelta(hours=1)) + return f"{blob_client.url}?{token}" + diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/samples/runner.py b/sdk/deviceupdate/azure-iot-deviceupdate/samples/runner.py new file mode 100644 index 000000000000..7b9ee043970d --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/samples/runner.py @@ -0,0 +1,276 @@ +from azure.core.exceptions import HttpResponseError +from azure.iot.deviceupdate import DeviceUpdateClient +from azure.iot.deviceupdate.models import * +from azure.identity import ClientSecretCredential +from datetime import datetime, timezone +import json +import time +from samples.contentfactory import ContentFactory +from samples.consts import MANUFACTURER, MODEL, BLOB_CONTAINER, DEFAULT_RETRY_AFTER + + +class SampleRunner: + def __init__(self, tenant_id, client_id, client_secret, account_endpoint, instance_id, storage_name, storage_key, + device_id, device_tag, **kwargs): + self._tenant_id = tenant_id + self._client_id = client_id + self._client_secret = client_secret + self._storage_name = storage_name + self._storage_key = storage_key + self._device_id = device_id + self._device_tag = device_tag + self._account_endpoint = account_endpoint + self._instance_id = instance_id + self._delete = kwargs.pop('delete', False) + + credentials = ClientSecretCredential( + tenant_id=tenant_id, + client_id=client_id, + client_secret=client_secret + ) + self._client = DeviceUpdateClient(credentials, account_endpoint, instance_id) + + def run(self): + version = datetime.now().strftime("%Y.%#m%d.%#H%M.%#S") + + # Create new update and import it into ADU + job_id = self._import_update_step(version) + + # Let's retrieve the existing (newly imported) update + self._retrieve_update_step(MANUFACTURER, MODEL, version, 200) + + # Create deployment/device group + group_id = self._create_deployment_group_step() + + # Check that device group contains devices that can be updated with our new update + self._check_group_devices_are_up_to_date_step(group_id, MANUFACTURER, MODEL, version, False) + + # Create deployment for our device group to deploy our new update + deployment_id = self._deploy_update_step(MANUFACTURER, MODEL, version, group_id) + + # Check device and wait until the new update is installed there + self._check_device_updates_step(MANUFACTURER, MODEL, version) + + # Check that device group contains *NO* devices that can be updated with our new update + self._check_group_devices_are_up_to_date_step(group_id, MANUFACTURER, MODEL, version, True) + + if self._delete: + # Delete the update + self._delete_update_step(MANUFACTURER, MODEL, version); + + # Let's retrieve the deleted update (newly imported) update and expect 404 (not found response) + self._retrieve_update_step(MANUFACTURER, MODEL, version, 404) + + # Dump test data to be used for unit-testing + self._output_test_data(version, job_id, deployment_id) + + def _import_update_step(self, version): + content_factory = ContentFactory(self._storage_name, self._storage_key, BLOB_CONTAINER) + update = content_factory.create_import_update(MANUFACTURER, MODEL, version) + + print("Importing updates...") + _, _, headers = self._client.updates.import_update(update, cls=callback) + operation_id = self._get_operation_id(headers["Location"]) + print(f"Import operation id: {operation_id}") + + print("(this may take a minute or two)") + repeat = True + while repeat: + _, operation, headers = self._client.updates.get_operation(operation_id, cls=callback) + if operation.status == "Succeeded": + print(operation.status) + repeat = False + elif operation.status == "Failed": + error = operation.errors[0] + raise ImportError("Import failed with response: \n" + + json.dumps(error.__dict__, default=as_dict, sort_keys=True, indent=2)) + else: + print(".", end="", flush=True) + time.sleep(self._get_retry_after(headers)) + print() + return operation_id + + def _retrieve_update_step(self, provider, name, version, expected_status): + print("Retrieving update...") + value = None + try: + response, value, _ = self._client.updates.get_update(provider, name, version, cls=callback) + status_code = response.http_response.status_code + except HttpResponseError as e: + status_code = e.status_code + if status_code == expected_status: + print(f"Received an expected status code: {expected_status}") + if value is not None: + print(json.dumps(value.__dict__, default=as_dict, sort_keys=True, check_circular=False, indent=2)) + else: + print() + else: + raise Exception(f"Service returned status code: {response.http_response.status_code}") + print() + + def _create_deployment_group_step(self): + group_id = self._device_tag + create_new_group = False + + print("Querying deployment group...") + try: + _ = self._client.devices.get_group(group_id) + print(f"Deployment group {group_id} already exists.") + except HttpResponseError as e: + if e.status_code == 404: + create_new_group = True + + if create_new_group: + print("Creating deployment group...") + group = self._client.devices.create_or_update_group( + group_id, + Group( + group_id=group_id, + group_type=GroupType.IO_T_HUB_TAG, + tags=[group_id], + created_date_time=datetime.utcnow().isoformat() + )) + if group is not None: + print(f"Group {group_id} created.") + print() + + print("Waiting for the group to be populated with devices...") + print("(this may take about five minutes to complete)") + repeat = True + while repeat: + group = self._client.devices.get_group(group_id) + if group.device_count > 0: + print(f"Deployment group {group_id} now has {group.device_count} devices.") + repeat = False + else: + print(".", end="", flush=True) + time.sleep(DEFAULT_RETRY_AFTER) + print() + return group_id + + def _check_group_devices_are_up_to_date_step(self, group_id, provider, name, version, is_compliant): + print(f"Check group {group_id} device compliance with update {provider}/{name}/{version}...") + update_found = False + counter = 0 + + while not update_found and counter <= 6: + response = self._client.devices.get_group_best_updates(group_id) + group_devices = list(response) + for updatableDevices in group_devices: + update = updatableDevices.update_id + if update.provider == provider and update.name == name and update.version == version: + update_found = True + if is_compliant: + if updatableDevices.device_count == 0: + print("All devices within the group have this update installed.") + else: + print(f"There are still {updatableDevices.device_count} devices that can be updated to " + + f"update {provider}/{name}/{version}.") + else: + print(f"There are {updatableDevices.device_count} devices that can be updated to update " + + f"{provider}/{name}/{version}.") + counter = counter + 1 + if not update_found: + print(".", end="", flush=True) + time.sleep(DEFAULT_RETRY_AFTER) + + if not update_found: + print("(Update is still not available for any group device.)") + print() + + def _deploy_update_step(self, provider, name, version, group_id): + print("Deploying the update to a device...") + deployment_id = f"{self._device_id}.{version.replace('.', '-')}" + _ = self._client.deployments.create_or_update_deployment( + deployment_id=deployment_id, + deployment=Deployment( + deployment_id=deployment_id, + deployment_type=DeploymentType.complete, + start_date_time=datetime.now(timezone.utc), + device_group_type=DeviceGroupType.DEVICE_GROUP_DEFINITIONS, + device_group_definition=[group_id], + update_id=UpdateId(provider=provider, name=name, version=version))) + print(f"Deployment '{deployment_id}' created.") + time.sleep(DEFAULT_RETRY_AFTER) + + print("Checking the deployment status...") + status = self._client.deployments.get_deployment_status(deployment_id) + print(f" {status.deployment_state}") + print() + return deployment_id + + def _check_device_updates_step(self, provider, name, version): + print(f"Checking device {self._device_id} status...") + print("Waiting for the update to be installed...") + repeat = True + while repeat: + device = self._client.devices.get_device(self._device_id) + installed_update = device.installed_update_id + if installed_update.provider == provider and installed_update.name == name and installed_update.version == version: + repeat = False + else: + print(".", end="", flush=True) + time.sleep(DEFAULT_RETRY_AFTER) + + print("\n") + + def _delete_update_step(self, provider, name, version): + print("Deleting the update...") + _, _, headers = self._client.updates.delete_update(provider, name, version, cls=callback) + operation_id = self._get_operation_id(headers["Operation-Location"]) + print(f"Delete operation id: {operation_id}") + + print("Waiting for delete to finish...") + print("(this may take a minute or two)") + repeat = True + while repeat: + _, operation, headers = self._client.updates.get_operation(operation_id, cls=callback) + if operation.status == "Succeeded": + print(operation.status) + repeat = False + elif operation.status == "Failed": + error = operation.errors[0] + raise ImportError("Delete failed with response: \n" + + json.dumps(error.__dict__, default=as_dict, sort_keys=True, indent=2)) + else: + print(".", end="", flush=True) + time.sleep(self._get_retry_after(headers)) + print() + + def _get_operation_id(self, operation_location): + return operation_location.split("/")[-1] + + def _get_retry_after(self, headers): + if headers is not None and headers["Retry-After"] is not None: + return int(headers["Retry-After"]) + else: + return DEFAULT_RETRY_AFTER + + def _output_test_data(self, version, job_id, deployment_id): + print("Test data to use when running SDK unit tests:") + print(f'DEVICEUPDATE_TENANT_ID="{self._tenant_id}"') + print(f'DEVICEUPDATE_CLIENT_ID="{self._client_id}"') + print(f'DEVICEUPDATE_CLIENT_SECRET="{self._client_secret}"') + print(f'DEVICEUPDATE_ACCOUNT_ENDPOINT="{self._account_endpoint}"') + print(f'DEVICEUPDATE_INSTANCE_ID="{self._instance_id}"') + print(f'DEVICEUPDATE_VERSION="{version}"') + print(f'DEVICEUPDATE_OPERATION_ID="{job_id}"') + print(f'DEVICEUPDATE_DEVICE_ID="{self._device_id}"') + print(f'DEVICEUPDATE_DEPLOYMENT_ID="{deployment_id}"') + print(f'DEVICEUPDATE_PROVIDER="{MANUFACTURER}"') + print(f'DEVICEUPDATE_MODEL="{MODEL}"') + print(f'DEVICEUPDATE_DEVICE_CLASS_ID="b83e3c87fbf98063c20c3269f1c9e58d255906dd"') + print() + print("Set these environment variables in your '.env' file before opening and running SDK unit tests.") + pass + + +def callback(response, value, headers): + return response, value, headers + + +def as_dict(o): + try: + return o.__dict__ + except: + return "???" diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/samples/sample.py b/sdk/deviceupdate/azure-iot-deviceupdate/samples/sample.py new file mode 100644 index 000000000000..9896052b899b --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/samples/sample.py @@ -0,0 +1,38 @@ +import os +import sys +from samples.runner import SampleRunner + +tenant_id = os.getenv("AZURE_TENANT_ID") +client_id = os.getenv("AZURE_CLIENT_ID") +client_secret = os.getenv("AZURE_CLIENT_SECRET") +storage_name = os.getenv("AZURE_STORAGE_NAME") +storage_key = os.getenv("AZURE_STORAGE_KEY") + +account_endpoint = os.getenv("AZURE_ACCOUNT_ENDPOINT") +instance_id = os.getenv("AZURE_INSTANCE_ID") +device_id = os.getenv("AZURE_DEVICE_ID") +device_tag = device_id + + +def sample_device_update(delete): + print("Device Update for IoT Hub client library for Python sample") + print() + + runner = SampleRunner( + tenant_id, + client_id, + client_secret, + account_endpoint, + instance_id, + storage_name, + storage_key, + device_id, + device_tag, + delete=delete) + runner.run() + + print("Finished.") + + +if __name__ == '__main__': + sample_device_update(sys.argv[1].lower() == "true" if len(sys.argv) > 1 else False) diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/sdk_packaging.toml b/sdk/deviceupdate/azure-iot-deviceupdate/sdk_packaging.toml new file mode 100644 index 000000000000..22f9c52f09e6 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/sdk_packaging.toml @@ -0,0 +1,9 @@ +[packaging] +auto_update = false +package_name = "azure-iot-deviceupdate" +package_pprint_name = "Azure DeviceUpdate" +is_stable = false +is_arm = false + +# Package owners should uncomment and set this doc id. +# package_doc_id = "device-update" diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/setup.cfg b/sdk/deviceupdate/azure-iot-deviceupdate/setup.cfg new file mode 100644 index 000000000000..3c6e79cf31da --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/setup.cfg @@ -0,0 +1,2 @@ +[bdist_wheel] +universal=1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/setup.py b/sdk/deviceupdate/azure-iot-deviceupdate/setup.py new file mode 100644 index 000000000000..3b4d52e9e304 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/setup.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python + +#------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +#-------------------------------------------------------------------------- + +import re +import os.path +from io import open +from setuptools import find_packages, setup + +PACKAGE_NAME = "azure-iot-deviceupdate" +PACKAGE_PPRINT_NAME = "Device Update" + +# a-b-c => a/b/c +package_folder_path = PACKAGE_NAME.replace('-', '/') +# a-b-c => a.b.c +namespace_name = PACKAGE_NAME.replace('-', '.') + +# azure v0.x is not compatible with this package +# azure v0.x used to have a __version__ attribute (newer versions don't) +try: + import azure + try: + ver = azure.__version__ + raise Exception( + 'This package is incompatible with azure=={}. '.format(ver) + + 'Uninstall it with "pip uninstall azure".' + ) + except AttributeError: + pass +except ImportError: + pass + +# Version extraction inspired from 'requests' +with open(os.path.join(package_folder_path, '_version.py'), 'r') as fd: + version = re.search(r'^VERSION\s*=\s*[\'"]([^\'"]*)[\'"]', + fd.read(), re.MULTILINE).group(1) + +if not version: + raise RuntimeError('Cannot find version information') + +with open('README.md', encoding='utf-8') as f: + readme = f.read() +with open('CHANGELOG.md', encoding='utf-8') as f: + changelog = f.read() + +setup( + name=PACKAGE_NAME, + version=version, + description='Microsoft Azure {} Client Library for Python'.format(PACKAGE_PPRINT_NAME), + long_description=readme + "\n\n" + changelog, + long_description_content_type='text/markdown', + url='https://github.com/Azure/azure-sdk-for-python', + author='Microsoft Corporation', + author_email='adupmdevteam@microsoft.com', + license='MIT License', + zip_safe=False, + classifiers=[ + "Development Status :: 4 - Beta", + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'License :: OSI Approved :: MIT License', + ], + packages=find_packages(exclude=[ + 'tests', + # Exclude packages that will be covered by PEP420 or nspkg + 'azure', + 'azure.iot', + ]), + install_requires=[ + 'msrest>=0.5.0', + 'azure-common~=1.1', + 'azure-core>=1.6.0,<2.0.0', + ], + extras_require={ + ":python_version<'3.0'": ['azure-iot-nspkg'], + } +) diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_create_cancel_and_delete_deployment.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_create_cancel_and_delete_deployment.yaml new file mode 100644 index 000000000000..cff80f8f628b --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_create_cancel_and_delete_deployment.yaml @@ -0,0 +1,202 @@ +interactions: +- request: + body: '{"deploymentId": "ec89848596944660a1a5b3ddca55e5bf", "deploymentType": + "Complete", "startDateTime": "2020-01-01T00:00:00.000Z", "deviceGroupType": + "DeviceGroupDefinitions", "deviceGroupDefinition": ["fakeDeviceId"], "updateId": + {"provider": "Contoso", "name": "Virtual-Machine", "version": "fakeVersion"}}' + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '311' + Content-Type: + - application/json + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: PUT + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments/ec89848596944660a1a5b3ddca55e5bf + response: + body: + string: "{\r\n \"deploymentId\": \"ec89848596944660a1a5b3ddca55e5bf\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"startDateTime\": \"2020-01-01T00:00:00+00:00\",\r\n + \ \"deviceGroupType\": \"DeviceGroupDefinitions\",\r\n \"deviceGroupDefinition\": + [\r\n \"fakeDeviceId\"\r\n ],\r\n \"updateId\": {\r\n \"provider\": + \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n \"version\": \"fakeVersion\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n \"isRetry\": + false\r\n}" + headers: + content-length: + - '433' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:58:45 GMT + traceparent: + - 00-7dd45f01bc2ae94c919c0915281522ba-2dc9dc9817afa644-00 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments/ec89848596944660a1a5b3ddca55e5bf + response: + body: + string: "{\r\n \"deploymentId\": \"ec89848596944660a1a5b3ddca55e5bf\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"startDateTime\": \"2020-01-01T00:00:00+00:00\",\r\n + \ \"deviceGroupType\": \"DeviceGroupDefinitions\",\r\n \"deviceGroupDefinition\": + [\r\n \"fakeDeviceId\"\r\n ],\r\n \"updateId\": {\r\n \"provider\": + \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n \"version\": \"fakeVersion\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n \"isRetry\": + false\r\n}" + headers: + content-length: + - '433' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:58:45 GMT + traceparent: + - 00-50489f2cb6425345917c217f956875e6-d69691bc87007749-00 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments/ec89848596944660a1a5b3ddca55e5bf/status + response: + body: + string: "{\r\n \"deploymentState\": \"Active\",\r\n \"totalDevices\": 0,\r\n + \ \"devicesIncompatibleCount\": 0,\r\n \"devicesAlreadyInDeploymentCount\": + 0,\r\n \"devicesInProgressCount\": 0,\r\n \"devicesCompletedFailedCount\": + 0,\r\n \"devicesCompletedSucceededCount\": 0,\r\n \"devicesCanceledCount\": + 0\r\n}" + headers: + content-length: + - '271' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:58:45 GMT + traceparent: + - 00-e9ea6a03343c014898b13fd525c4febe-08a137edf5f41b4b-00 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: POST + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments/ec89848596944660a1a5b3ddca55e5bf?action=cancel + response: + body: + string: "{\r\n \"deploymentId\": \"ec89848596944660a1a5b3ddca55e5bf\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"startDateTime\": \"2020-01-01T00:00:00+00:00\",\r\n + \ \"deviceGroupType\": \"DeviceGroupDefinitions\",\r\n \"deviceGroupDefinition\": + [\r\n \"fakeDeviceId\"\r\n ],\r\n \"updateId\": {\r\n \"provider\": + \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n \"version\": \"fakeVersion\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n \"isRetry\": + false\r\n}" + headers: + content-length: + - '432' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:58:45 GMT + traceparent: + - 00-0f2751d97e7543448bacfd89a3ba89ec-e4fd675ab4de254b-00 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '0' + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: DELETE + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments/ec89848596944660a1a5b3ddca55e5bf + response: + body: + string: '' + headers: + content-length: + - '0' + date: + - Wed, 03 Mar 2021 18:58:46 GMT + traceparent: + - 00-b391929f73b15f4d87f8aba752c28ff4-3b8916bbb745d24e-00 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments/ec89848596944660a1a5b3ddca55e5bf + response: + body: + string: "{\r\n \"type\": \"https://tools.ietf.org/html/rfc7231#section-6.5.4\",\r\n + \ \"title\": \"Not Found\",\r\n \"status\": 404,\r\n \"traceId\": \"00-a3fa8337dd887d45beacf39d463036b2-1b2f65440f390149-00\"\r\n}" + headers: + content-length: + - '183' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:58:46 GMT + traceparent: + - 00-a3fa8337dd887d45beacf39d463036b2-3be08289709c5740-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_all_deployments.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_all_deployments.yaml new file mode 100644 index 000000000000..eea6e607c8ab --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_all_deployments.yaml @@ -0,0 +1,1521 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments + response: + body: + string: "{\r\n \"value\": [\r\n {\r\n \"deploymentId\": \"fakeDeviceId-2021-209-1525-54\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"startDateTime\": \"2021-02-09T23:28:38.8516717+00:00\",\r\n + \ \"deviceGroupType\": \"DeviceGroupDefinitions\",\r\n \"deviceGroupDefinition\": + [\r\n \"fakeDeviceId\"\r\n ],\r\n \"updateId\": {\r\n \"provider\": + \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n \"version\": + \"2021.209.1525.54\"\r\n },\r\n \"isCanceled\": false,\r\n \"isCompleted\": + false,\r\n \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": + \"chejiang-test\",\r\n \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": + \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n \"startDateTime\": + \"2019-09-01T16:29:56.5770502+00:00\",\r\n \"deviceGroupType\": \"Devices\",\r\n + \ \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]6423c0f6-f8c8-4068-8dd4-37b9b310c7f4\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T20:37:18.2609177+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]544c8499-3c34-4989-bf61-2f3972befd51\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T20:38:20.5709775+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]0bee76a1-c076-4c3a-94a4-9411a22b4396\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T20:37:24.1153814+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]3fc90e6c-cfa4-4962-adb5-00aeef5fe68e\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T20:39:37.5481626+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"16002.19052\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]146c7339-5dfa-4d28-8c38-367b7648c30c\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T20:41:30.4768881+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"64378.62049\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]c2a9c9e6-4d42-4c68-8b31-a8a4873c5b0c\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T20:56:37.2998162+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]48b5a4bb-4229-45a8-a4f0-86e8d1cbcd74\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T20:57:39.1019833+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]96afe1aa-a64e-4035-ba75-e261be6755c1\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T20:56:41.1254855+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]86df43fe-c9eb-491d-988b-96462c234c57\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T20:58:53.4913754+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"61320.13334.25405\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]467e6bd0-1de2-4701-91d9-f7d9b6dcf690\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T20:59:07.7707431+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]bad84ab8-b002-4dbe-9706-db92b5347f1f\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:00:09.1437771+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]7ce4881a-de65-41d4-9fd5-4e5b386a9ad4\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T20:59:11.4618396+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]00dc0379-c175-4301-8448-956a08c98e85\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T20:59:57.7338974+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]fe66ecba-a5bc-4e11-9f5f-ffe81256b1b6\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:00:59.6301739+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]1b23f416-30ab-452f-8bcd-c5d7a18478c8\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:00:01.7732765+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]1675bf12-6eda-4b1f-813e-c67fad0b3288\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:01:17.4628021+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"48502.47058.6499\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]d62ed371-3e03-49ab-8d8c-4c73bf7f2e91\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:00:39.1036809+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]8265293c-3d95-40f2-aaae-b9fa45cefb08\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:01:40.1897727+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]60689197-15af-4a15-be24-148b6cb6987e\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:00:41.915384+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]c8d76dbf-1efc-4485-9aa8-19e1276441f6\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:01:23.0687599+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"14184.49846.38219\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]602c37f3-cbc4-4b5f-a551-78f7b70b5cb6\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:02:13.3328086+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"14868.25096.1559\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]b8928036-6451-4e5c-8a66-3db33258e974\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:03:17.6420362+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"2973.53652\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]9ee5d586-f8bb-4930-b2ce-3e7fb30f801a\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:02:53.3526249+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"62839.55095\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]1feac02c-bea7-4c73-9a6c-aebb31b8a496\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:04:07.6963661+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"55660.17297\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]7d9e9cda-9205-4d9e-a17f-6bf33f1cd394\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:04:47.4804059+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"18328.9748\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]1192804e-fd42-4456-88ea-e65cb3e4f1e6\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:04:47.1384575+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]af132b25-897d-4b89-b938-a14b2b4c3cf1\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:05:48.5821959+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]0d8a6d4c-9d93-4dc7-b61f-0bd8e06a1cff\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:04:50.6470031+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]62248076-3eb1-4a9a-81f8-d0613c9d2c73\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:07:01.425036+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"35240.23044.5913\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]344059af-1ba5-46c2-b734-ce27f039752d\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:08:56.6381858+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"51211.2096\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]49d41a17-272f-4628-8abe-8c61331cc83c\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:13:22.5201073+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]2e13d159-1cee-4862-92a3-880383088204\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:14:24.5707977+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]d9856a43-35bf-448b-bd3a-e78c022955cd\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:13:26.4273707+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]2da21a3e-16cd-4f9b-9751-11da93a5e285\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:14:52.0256992+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]84c418c6-89bf-4fc0-ab5c-0bf3d0c2769c\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:15:53.6829765+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]68571953-0b81-423e-aa0a-397cf89d732b\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:14:56.6682684+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]cb03e500-44d4-4b09-8031-88e5eab76ad2\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:15:34.9068529+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"28528.25507\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]89841632-9f6b-4b34-a0d8-9012d17f5e05\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:17:32.7008635+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"44486.48093\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]36cd9fea-4305-40b9-8347-60c582ed6cb5\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:17:04.9801419+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"9448.5551\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]daf54f98-f549-484f-9de1-cb5a2c535950\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:19:02.2956694+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"14856.34633.61171\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]300de3a7-4c3a-4ee4-89b0-a61cec28aa51\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:23:15.8746239+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]b34c9f9f-4038-44b5-84e6-b03f7958a69c\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:24:17.5676129+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]07537a92-2ce9-4a5f-85aa-5d5eed1c9204\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:23:19.3335727+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]7eb4e288-6b5e-4611-8e84-6024f304ea61\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:24:27.3600589+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]f6b94f91-7911-4758-b27d-b142f5619cd1\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:25:29.0500763+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]447ec0eb-ef49-43a5-93d2-d7e3075e6d8c\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:24:29.6131133+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]292c852c-fa30-4138-a87b-e789fd7bad23\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:25:29.7175112+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"38304.28076\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]9040ac92-d480-42da-9449-f87fe3134e0d\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:27:25.1124239+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"40006.5636.14753\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]9d29e5c7-9029-49a3-a4bd-c23380dd8447\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:26:39.8158178+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"3191.34183\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]60b8b56e-b70f-4783-a805-a59447bba66e\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-10T21:28:38.8598423+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"40377.45349.61758\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 77b07fba-7fea-4e90-bade-567f17113749\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-11T01:11:46.1315134+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [],\r\n \"updateId\": + {\r\n \"provider\": \"ADUTeam\",\r\n \"name\": \"RefDevice\",\r\n + \ \"version\": \"1.0.3750.1\"\r\n },\r\n \"isCanceled\": true,\r\n + \ \"isCompleted\": false,\r\n \"isRetry\": false\r\n },\r\n {\r\n + \ \"deploymentId\": \"[ManagementE2ETest] 2ab1336a-7b8b-4b9f-803c-90cc2afe1c3a\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-11T01:37:20.7524364+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [],\r\n \"updateId\": + {\r\n \"provider\": \"ADUTeam\",\r\n \"name\": \"RefDevice\",\r\n + \ \"version\": \"1.0.3779.1\"\r\n },\r\n \"isCanceled\": true,\r\n + \ \"isCompleted\": false,\r\n \"isRetry\": false\r\n },\r\n {\r\n + \ \"deploymentId\": \"[ManagementE2ETest] 79394211-4d45-4a51-82fb-179a84988975\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-11T02:02:20.5902878+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [],\r\n \"updateId\": + {\r\n \"provider\": \"ADUTeam\",\r\n \"name\": \"RefDevice\",\r\n + \ \"version\": \"1.0.3779.1\"\r\n },\r\n \"isCanceled\": true,\r\n + \ \"isCompleted\": false,\r\n \"isRetry\": false\r\n },\r\n {\r\n + \ \"deploymentId\": \"[ManagementE2ETest] 52c1e7d4-c09e-4f17-8ff1-9363dbc1871b\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-11T02:30:30.2612669+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"adu-raspi-e2etest-raps-prod-wus2\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"RefDevice\",\r\n \"version\": \"1.0.3750.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + c0fc4757-761e-440e-8e14-89e7bf820316\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-11T19:17:27.9859392+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"adu-raspi-e2etest-raps-prod-wus2\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"RefDevice\",\r\n \"version\": \"1.0.3779.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"fakeDeviceId-3-2021-214-1709-51\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"startDateTime\": \"2021-02-15T01:11:55.2804612+00:00\",\r\n + \ \"deviceGroupType\": \"DeviceGroupDefinitions\",\r\n \"deviceGroupDefinition\": + [\r\n \"my-test\"\r\n ],\r\n \"updateId\": {\r\n \"provider\": + \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n \"version\": + \"2021.214.1709.51\"\r\n },\r\n \"isCanceled\": false,\r\n \"isCompleted\": + false,\r\n \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": + \"[CreateDeploymentAndWaitAndCheckInfoTest]092151e4-e8f2-4fbf-a402-3a97723c86b5\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:14:15.222053+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]f4dac7ea-5827-499e-a000-b990ed95be4b\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:15:19.2493261+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]c773a5a6-5782-4f33-a713-b892af3bb59e\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:14:20.5236017+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]d5d5fe31-9199-4e0a-a817-8a01ebc27e41\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:15:21.6048437+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]4e5d65fd-5756-4d86-be4c-a637b845bb6d\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:14:22.0945934+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]932651aa-8e5a-4e5e-8827-1082fe1dcf37\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:14:23.9056672+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]a69e2ab1-5af6-4795-af42-3032d4610777\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:15:41.1145206+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]954fccfa-2c5a-4527-8630-985269d7eb83\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:16:42.8652225+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]f5d82d53-fafe-4f07-a9f9-85c7f5301a3f\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:15:44.2792902+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]b3a961e7-53a5-4703-8cfa-8706d47fb770\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:15:43.5958267+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]8cbe4ce1-c3af-44b8-b289-a45c118f14a1\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:16:45.2833101+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]7c79861d-b9ac-4121-bc14-c9f75b9060ea\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:15:47.0348662+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]11a69913-03bd-4a13-941a-4ac29352c944\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:16:33.2010311+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"58619.29858.8352\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]ce960397-18fa-45f4-b34b-b523c80c3535\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:16:33.6672612+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"21497.49416.52515\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]cc27c159-11d5-417b-8a94-f6c12f844087\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:18:28.1276813+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"52318.39562.52572\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]88a72696-54e8-4cff-a49b-8bbc62ee9333\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:18:29.0779299+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"9439.9695\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]d2550a49-3a44-4bc8-b06d-062e4a0da8c3\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:17:52.773332+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"9263.27053.51908\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]a155f315-59ad-4675-9366-29f75ab04fa7\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:17:56.8171819+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"32735.19434\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]843b6584-bf87-4ddf-8666-80615a6396fc\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:19:50.0173453+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"64639.32094.8729\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]fbf26ea5-4642-40af-92f8-8dd3bf538c70\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:19:52.7234079+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"34440.15569.32036\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 60f0168b-af1c-453d-9c12-597966a78255\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-18T04:25:09.4387427+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"adu-raspi-e2etest-raps-prod-wus2\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"RefDevice\",\r\n \"version\": \"1.0.3779.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]9ded2c84-41c4-448d-b22d-8cc9240d799a\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:25:43.3143859+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]044036d9-7647-4217-b7dd-39db8d223f4e\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:26:44.7721183+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]c282eb19-98f6-4e08-8ef7-bf1397671ad1\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:25:46.7151459+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]2ad2b873-80d2-47d5-b8f6-ee6b498b5a78\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:27:57.4243367+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"39612.60528\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]2dee1361-b04a-4e96-bcb1-5908b5f2c95e\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:28:07.6098146+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]665b365e-339d-4696-aada-6eddf56f6e5f\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:29:08.9911925+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]4e74add0-ace3-486f-b52a-e3f912b51802\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:28:12.3329545+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]a461fbfb-b9bf-4068-b4cc-dfdd8db3ff93\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:29:53.2162907+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"4432.16466\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]4fd7c530-3d1a-4c05-a870-0ccb7ae66415\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:29:16.8272005+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]9166950f-d8fc-4853-8c23-f2fede268350\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:30:17.8739557+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]47f57615-92a6-4130-87d0-a4e8c6aad705\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:29:22.4859155+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]94c6f429-b197-42ee-bc8e-579eb6f059ab\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:30:22.9762193+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"18279.54271\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]7e3f1fe8-9565-4a52-aa6b-ea4da28799cb\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:32:18.3591562+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"34558.29386\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]e23dfac2-458d-411d-b984-352c1f2c3fd2\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:31:32.8515396+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"12351.27050\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]99b112fd-7e4a-4bf0-9d49-40a783353737\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T04:33:28.1411908+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"2891.41513\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 01163507-5c0d-45a9-99c0-a8245390e6e4\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-18T04:53:01.7398587+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"adu-raspi-e2etest-raps-prod-wus2\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"RefDevice\",\r\n \"version\": \"1.0.3779.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]c6dbe0e6-6816-447b-a3cf-b6bb8918351b\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T17:55:04.49501+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]2a9f6098-f325-4963-9745-bf4e6446e37c\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T17:56:06.1732755+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]63b38384-eccc-48b9-8f32-56184faa80ba\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T17:55:08.3547885+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]753fe67f-b0b0-4452-a4b2-64b80131c595\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T17:57:18.2654138+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"36581.10619.48107\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]6f019a40-3a6d-4338-899f-9cb52c4dbd5a\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T17:59:14.6899507+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"12508.46001\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n }\r\n ],\r\n \"nextLink\": \"/deviceupdate/blue/v2/management/deployments?$top=100&$skipToken=%5B%7B%22token%22%3A%22%2BRID%3A%7EBYwRANEj9L55AAAAAAAAAA%3D%3D%23RT%3A1%23TRC%3A100%23ISV%3A2%23IEO%3A65567%23QCF%3A3%23FPC%3AAgEAAAAUAHkAAO73fff37v%2F%2Ff3f%2FvXf%2FHwkA%22%2C%22range%22%3A%7B%22min%22%3A%22%22%2C%22max%22%3A%22FF%22%7D%7D%5D\"\r\n}" + headers: + content-length: + - '62575' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:04 GMT + traceparent: + - 00-78a50aceb13ac94db2ced378adb58c73-890b23325503bb41-00 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments?$top=100&$skipToken=%5B%7B%22token%22%3A%22%2BRID%3A~BYwRANEj9L55AAAAAAAAAA%3D%3D%23RT%3A1%23TRC%3A100%23ISV%3A2%23IEO%3A65567%23QCF%3A3%23FPC%3AAgEAAAAUAHkAAO73fff37v%2F%2Ff3f%2FvXf%2FHwkA%22%2C%22range%22%3A%7B%22min%22%3A%22%22%2C%22max%22%3A%22FF%22%7D%7D%5D + response: + body: + string: "{\r\n \"value\": [\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 8468856f-889b-4d6b-83d5-928075e9fedb\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-18T19:01:29.1567236+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"adu-raspi-e2etest-raps-prod-wus2\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"RefDevice\",\r\n \"version\": \"1.0.3750.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]fb6343ca-1d75-490c-ba68-3f04dfa54caa\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T21:00:23.5255493+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]2e824739-12df-436e-851d-ab26c51f9594\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T21:01:25.6926112+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]ea83f2ba-9c3a-4649-9be0-ddfacb9cfc03\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T21:00:29.0453385+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]95172d83-94e0-4ca6-a5f3-39cbe08889d9\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T21:02:37.811033+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"46324.35236\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]5611e532-9e55-40eb-a682-e8aead6753cd\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-18T21:04:34.918156+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"18551.26060\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 49ca3e34-0f18-499a-bbfd-ec978a29b953\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-18T23:31:17.2173117+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"adu-raspi-e2etest-raps-prod-wus2\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"RefDevice\",\r\n \"version\": \"1.0.3750.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]a2998755-d5c3-42df-ade1-a9be1ab3c5b2\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T17:50:18.0774055+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]ad0047df-0d07-444d-8493-ad9d4e2e046d\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T17:51:20.4997412+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]1f6fa4a7-f5a6-470a-9dfd-b5646946f8ca\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T17:50:22.8181423+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]0bf3a640-2e43-4c6e-b6e4-8334e2462914\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T17:52:33.5391649+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"18302.17634\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]d63796b8-ee64-4f1a-825d-34b8976aebdb\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T17:54:29.6773908+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"32892.26839.41198\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]ca1e438e-2c03-4445-a68b-49c242137617\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:14:36.9208839+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]f6ba2c69-f4dc-44c7-8d30-026d19110c0c\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:14:44.177023+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]fc6709fa-a6d5-4571-baa6-94a60313fdad\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:15:42.9317595+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]e6cfe17c-0ac7-4901-ae33-8b683d9f2071\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:16:56.2717868+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"65490.30247.12061\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]69f77faf-81d6-4e0e-bd5b-af7bee1270e1\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:18:58.9221908+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"17134.46108\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]671819a8-df68-4035-816c-26e5e2b7f025\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:41:06.9074026+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]7a381b5d-ba52-49fc-988b-c19960f3f04c\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:42:09.1229613+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]1de3f070-c4f3-487f-842f-dd68ee86346e\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:41:11.6750784+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]c8bfa3b2-9c25-4df7-947d-5ea63f63500e\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:43:17.9386413+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]4dc942ab-b8f8-4ae8-b416-c82b341a19e0\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:44:20.0648374+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]a990019f-aa0e-45ca-a78a-77929b57ab00\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:43:20.917731+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"42495.57085.35297\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]52ba359f-a1fc-49f8-b3b3-4104d0677c86\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:43:21.8413063+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]32e858d4-1171-490f-a660-8245086446c6\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:45:19.8503403+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"41434.28948\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]c19f5180-90d3-45c3-8935-d798366bb0ef\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:45:30.0413929+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"11388.40109\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]ffee8e11-5e0a-441d-b86a-52e21d0e4e32\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:47:30.1358071+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"9614.36373.59831\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]1b53dfba-2d43-4a7c-8ceb-9042e8b3f5ae\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:46:40.7850775+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]2785511c-d0eb-4577-b63e-77dfac7946d2\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:47:42.4019461+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]6ca34cef-610c-40e0-a934-7e87ead73f9f\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:46:45.1967155+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]dd4feee2-1a63-4fa1-9d58-7ef896d49c9d\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:48:55.8289585+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"11998.10735\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]328d2a88-c276-488b-8d40-62cdde5d9419\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:49:47.4782376+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]27d0c8dc-b1e7-4983-a046-e1de19ca55ac\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:50:49.4526546+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]7c8f50ba-b17b-4d78-8eaf-86bc0107da0c\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:49:50.7211169+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]4c7d4916-bdd8-4a4d-ad4a-28579219a26e\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:50:04.9141711+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]b47beeb3-5e39-4f21-987a-ff2ed4b4f7b7\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:51:06.1358621+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]bac00410-2b58-4002-8456-e5dabbe9b266\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:50:08.9898527+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]925afa1c-cd08-4193-9b98-eb41f8cb8adf\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:52:51.4312795+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"48148.9669.8061\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]c512236e-84e1-41fe-992f-0bd765d774c3\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:51:59.3177571+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"51478.2537.20262\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]7bbe161b-3d02-4431-b9c6-b331b8ac1a3b\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:53:58.8080515+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"43894.765\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]84d43f3e-5933-4bf3-bdcb-0f7a16f66f60\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:54:14.6590366+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"31239.28795\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]3d942afe-85a9-49fc-9788-92302a5762cf\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-02-24T18:54:19.137201+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"9519.17419.61336\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 037cbc82-4275-4596-acc1-e7305a326e50\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-24T18:57:43.3765392+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"adu-raspi-e2etest-raps-prod-wus2\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"RefDevice\",\r\n \"version\": \"1.0.3779.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 8bd8e2a6-085e-4e39-8416-d014b219bad6\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-24T19:26:51.2374989+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"adu-raspi-e2etest-raps-prod-wus2\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"RefDevice\",\r\n \"version\": \"1.0.3779.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 53b6fd41-9b22-4cc8-acf2-532c8974b43c\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-24T22:18:41.1552691+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"adu-raspi-e2etest-raps-prod-wus2\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"RefDevice\",\r\n \"version\": \"1.0.3779.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 924eeb30-c2d4-4fff-8747-33e095adbd6a\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"634a0b52a6e1fb54fe6b98e5b55534bb4800b77b\",\r\n + \ \"startDateTime\": \"2021-02-24T23:19:50.3020901+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"Pi13279821\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"E2ETestDevice\",\r\n \"version\": \"1.0.3750.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 550f6729-14a8-4b25-b2ee-ceee2510f411\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"634a0b52a6e1fb54fe6b98e5b55534bb4800b77b\",\r\n + \ \"startDateTime\": \"2021-02-24T23:32:04.7652633+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"Pi13279821\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"E2ETestDevice\",\r\n \"version\": \"1.0.3779.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + d0058055-b4bd-449a-a91d-a03a43bcbba5\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"634a0b52a6e1fb54fe6b98e5b55534bb4800b77b\",\r\n + \ \"startDateTime\": \"2021-02-24T23:56:25.1535896+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"Pi13279821\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"E2ETestDevice\",\r\n \"version\": \"1.0.3750.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 41508c83-021f-403c-b4c9-9a15e9fc3d18\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"634a0b52a6e1fb54fe6b98e5b55534bb4800b77b\",\r\n + \ \"startDateTime\": \"2021-02-25T02:22:04.2233813+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"Pi13279821\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"E2ETestDevice\",\r\n \"version\": \"1.0.3779.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + ae08f8a1-f51a-40b5-8acf-517d8928b21e\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-25T18:22:23.1573696+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"adu-raspi-e2etest-raps-prod-wus2\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"RefDevice\",\r\n \"version\": \"1.0.3750.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + d5741c14-17fa-49dd-9932-6e04a611390d\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-25T18:59:34.1204921+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"adu-raspi-e2etest-raps-prod-wus2\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"RefDevice\",\r\n \"version\": \"1.0.3750.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 757f18e3-dd67-48fa-88fe-e232d2ecea0e\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"634a0b52a6e1fb54fe6b98e5b55534bb4800b77b\",\r\n + \ \"startDateTime\": \"2021-02-25T19:21:33.140483+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"Pi13279821\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"E2ETestDevice\",\r\n \"version\": \"1.0.3750.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 97fe08a2-22fe-4ad5-ab05-3e8e239b2419\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"634a0b52a6e1fb54fe6b98e5b55534bb4800b77b\",\r\n + \ \"startDateTime\": \"2021-02-25T20:28:13.5279766+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"Pi13279821\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"E2ETestDevice\",\r\n \"version\": \"1.0.3779.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 9134a970-df08-4fe7-8cb6-10d32a0a61f7\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"startDateTime\": \"2021-02-25T20:51:27.6928511+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"adu-raspi-e2etest-raps-prod-wus2\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"RefDevice\",\r\n \"version\": \"1.0.3750.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + b052e00f-7087-45b9-9cd9-1d96834b82a3\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"634a0b52a6e1fb54fe6b98e5b55534bb4800b77b\",\r\n + \ \"startDateTime\": \"2021-02-25T21:05:21.6376778+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"Pi13279821\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"E2ETestDevice\",\r\n \"version\": \"1.0.3750.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + ff9e6e43-4838-4a1d-9789-e4b0b13f004a\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"634a0b52a6e1fb54fe6b98e5b55534bb4800b77b\",\r\n + \ \"startDateTime\": \"2021-02-26T21:15:44.7606025+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"Pi13279821 + \"\r\n ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"E2ETestDevice\",\r\n \"version\": \"1.0.3779.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + d10be80f-e032-4661-b170-03f3216e5404\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"634a0b52a6e1fb54fe6b98e5b55534bb4800b77b\",\r\n + \ \"startDateTime\": \"2021-02-26T21:58:23.6772544+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"Pi13279821\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"E2ETestDevice\",\r\n \"version\": \"1.0.3779.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 194fe05d-e08f-4414-8e79-573fccdd2e79\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"634a0b52a6e1fb54fe6b98e5b55534bb4800b77b\",\r\n + \ \"startDateTime\": \"2021-02-26T23:05:17.2618357+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"Pi13279821\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"E2ETestDevice\",\r\n \"version\": \"1.0.3750.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 6fcde10b-154c-42f7-b5f1-12ffa7b743e6\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"634a0b52a6e1fb54fe6b98e5b55534bb4800b77b\",\r\n + \ \"startDateTime\": \"2021-03-01T21:07:00.9418695+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"Pi13279821\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"E2ETestDevice\",\r\n \"version\": \"1.0.3779.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"fakeDeviceId-2021-301-1926-8\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"startDateTime\": \"2021-03-02T03:28:49.3990566+00:00\",\r\n + \ \"deviceGroupType\": \"DeviceGroupDefinitions\",\r\n \"deviceGroupDefinition\": + [\r\n \"fakeDeviceId\"\r\n ],\r\n \"updateId\": {\r\n \"provider\": + \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n \"version\": + \"2021.301.1926.8\"\r\n },\r\n \"isCanceled\": false,\r\n \"isCompleted\": + false,\r\n \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": + \"[CreateDeploymentAndWaitAndCheckInfoTest]e8a1db15-a055-442a-afb1-78d2e4223717\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:48:02.6258156+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]f6df34cc-9b33-4c7f-9695-ead5d1a84b67\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:49:07.5909501+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]3e67f4cd-4d99-497c-a3cd-cb4ecf56f6d3\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:48:11.8092271+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]a0dd8476-2d0c-43ef-8371-7a72b936bade\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:49:03.0910711+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]eb93ebcc-b420-4326-89cc-2b04575ddf26\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:49:09.1502449+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]05f4d055-8fcd-4086-99cb-d878f6b18c09\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:50:07.7352547+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]3141b244-d7fc-4100-bcf8-84ae1b4978fe\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:49:13.6087164+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]657a46d3-0c27-4d9e-9960-ae52ff1c5818\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:50:15.2964796+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]ed6fe353-d461-403b-ad4e-010c7d03e60b\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:49:17.0450498+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]f0e1b288-a9d9-4efe-a5e8-03390e3ce267\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:50:27.1806759+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"40904.57411\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]6a28b50a-e916-4ea1-8808-ce4796e02d3d\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:51:16.469512+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"10998.61769.7472\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]a6512b0e-5a47-4878-a7bf-ce25745b669b\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:52:18.0938849+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"46262.16236\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]87fb21f2-ef78-40de-ad90-22c953728104\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:51:27.8522711+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"5971.10509.15901\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]549d56a8-a718-4d70-a73e-b822c1bc2479\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:53:19.5158671+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"33328.34654.17389\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]5df4bdb3-497a-41c3-9875-112a129a7f3f\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T16:53:24.6854092+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"30723.40594\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]a85e6570-33d0-48ee-917a-df263ea20f58\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:02:36.9280652+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]eeb90d76-ee90-4527-933d-f0eac77ecb65\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:03:39.100941+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]dc0ea097-33cb-4355-982c-b7dc0087fd56\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:02:42.3412279+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]2345bbd4-c288-4f7d-ac93-cf3a72dbccb8\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:04:50.0453459+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"41329.18008\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]3e1653f3-39de-4af9-8a08-50e87625dd7a\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:05:01.3766008+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]5d16fe9e-92e4-48c0-ad04-53055d2739a5\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:06:02.8465317+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]a63f4f18-8ace-4e17-bdf4-405accea06f8\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:05:05.2410054+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]206b7e11-facf-423e-b988-b33b7cb4edca\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:06:49.5404696+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"1561.8510\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]bde9549b-cab6-4473-9dce-2fbbac649b01\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:06:04.2328487+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]4ca85c18-95c8-4b18-bc7c-b302685cfdf5\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:07:05.8264496+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]e2dcba71-8575-4bfb-9399-c4572b822a5a\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:06:08.7995055+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndWaitAndCheckInfoTest]31f565b3-daa4-42e4-99ca-bc57bad4c2b1\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:06:25.8325453+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]ed47c825-5308-4bdf-b483-0637246df136\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:07:26.9151902+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentAndCancelTest]ad07230e-5863-4e37-82ab-63ac11110cde\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:06:28.7572809+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]252b1dad-42da-47de-aa95-f4e4c53291b5\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:07:13.6860295+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"52650.5497\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]b701222b-42a6-4eab-ae7b-7b16109b6de5\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:09:11.2440578+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"16427.1376\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]5d2a3871-af51-4b7e-b3c1-375608d6f4ca\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:08:15.8706014+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"27991.20092\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDevicesDeploymentAndWaitAndCheckInfoTest]7e706f11-3876-4b38-9f1d-15ecd5ae2edb\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:08:36.4496284+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"23025.30280\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]1719c00e-49ff-4a99-820e-01e0185a1533\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:10:14.5636526+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"35247.45001.33097\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[CreateDeploymentInTheFutureAndWaitAndCheckInfoTest]ff858f54-5ede-43a2-89d2-d373e0cc86a1\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"startDateTime\": \"2021-03-02T17:10:34.8316201+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"functionaltests-device1\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"14724.12006\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"[ManagementE2ETest] + 043b16d7-35c4-4556-bdea-766c39686f25\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"deviceClassId\": \"634a0b52a6e1fb54fe6b98e5b55534bb4800b77b\",\r\n + \ \"startDateTime\": \"2021-03-02T17:10:49.7308845+00:00\",\r\n \"deviceGroupType\": + \"Devices\",\r\n \"deviceGroupDefinition\": [\r\n \"Pi13279821\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"ADUTeam\",\r\n + \ \"name\": \"E2ETestDevice\",\r\n \"version\": \"1.0.3750.1\"\r\n + \ },\r\n \"isCanceled\": true,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"fakeDeviceId-2021-302-914-51\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"startDateTime\": \"2021-03-02T17:17:30.1735411+00:00\",\r\n + \ \"deviceGroupType\": \"DeviceGroupDefinitions\",\r\n \"deviceGroupDefinition\": + [\r\n \"my-test\"\r\n ],\r\n \"updateId\": {\r\n \"provider\": + \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n \"version\": + \"2021.302.914.51\"\r\n },\r\n \"isCanceled\": false,\r\n \"isCompleted\": + false,\r\n \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": + \"fakeDeviceId2-2021-302-1045-44\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"startDateTime\": \"2021-03-02T18:48:23.2921109+00:00\",\r\n \"deviceGroupType\": + \"DeviceGroupDefinitions\",\r\n \"deviceGroupDefinition\": [\r\n \"my-test\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Contoso\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"2021.302.1045.44\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": \"fakeDeviceId2-2021-302-1048-57\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"startDateTime\": \"2021-03-02T18:51:35.4129264+00:00\",\r\n + \ \"deviceGroupType\": \"DeviceGroupDefinitions\",\r\n \"deviceGroupDefinition\": + [\r\n \"my-test\"\r\n ],\r\n \"updateId\": {\r\n \"provider\": + \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n \"version\": + \"2021.302.1048.57\"\r\n },\r\n \"isCanceled\": false,\r\n \"isCompleted\": + false,\r\n \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": + \"fakeDeploymentId\",\r\n \"deploymentType\": \"Complete\",\r\n \"startDateTime\": + \"2021-03-02T20:04:52.8525661+00:00\",\r\n \"deviceGroupType\": \"DeviceGroupDefinitions\",\r\n + \ \"deviceGroupDefinition\": [\r\n \"fakeDeviceId\"\r\n ],\r\n + \ \"updateId\": {\r\n \"provider\": \"Contoso\",\r\n \"name\": + \"Virtual-Machine\",\r\n \"version\": \"fakeVersion\"\r\n },\r\n + \ \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n \"isRetry\": + false\r\n }\r\n ],\r\n \"nextLink\": \"/deviceupdate/blue/v2/management/deployments?$top=100&$skipToken=%5B%7B%22token%22%3A%22%2BRID%3A%7EBYwRANEj9L7sAAAAAAAAAA%3D%3D%23RT%3A2%23TRC%3A200%23ISV%3A2%23IEO%3A65567%23QCF%3A3%23FPC%3AAgEAAAAGAOyAAcAJAA%3D%3D%22%2C%22range%22%3A%7B%22min%22%3A%22%22%2C%22max%22%3A%22FF%22%7D%7D%5D\"\r\n}" + headers: + content-length: + - '61735' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:05 GMT + traceparent: + - 00-b6f961bf8f51e94fa7d778f1851d28d3-329afa4cc821f743-00 + status: + code: 200 + message: OK +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments?$top=100&$skipToken=%5B%7B%22token%22%3A%22%2BRID%3A~BYwRANEj9L7sAAAAAAAAAA%3D%3D%23RT%3A2%23TRC%3A200%23ISV%3A2%23IEO%3A65567%23QCF%3A3%23FPC%3AAgEAAAAGAOyAAcAJAA%3D%3D%22%2C%22range%22%3A%7B%22min%22%3A%22%22%2C%22max%22%3A%22FF%22%7D%7D%5D + response: + body: + string: "{\r\n \"value\": [\r\n {\r\n \"deploymentId\": \"fakeDeviceId.2021-302-1304-12\",\r\n + \ \"deploymentType\": \"Complete\",\r\n \"startDateTime\": \"2021-03-02T21:06:15.224255+00:00\",\r\n + \ \"deviceGroupType\": \"DeviceGroupDefinitions\",\r\n \"deviceGroupDefinition\": + [\r\n \"fakeDeviceId\"\r\n ],\r\n \"updateId\": {\r\n \"provider\": + \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n \"version\": + \"2021.302.1304.12\"\r\n },\r\n \"isCanceled\": false,\r\n \"isCompleted\": + false,\r\n \"isRetry\": false\r\n },\r\n {\r\n \"deploymentId\": + \"fakeDeviceId-2021-302-1323-55\",\r\n \"deploymentType\": \"Complete\",\r\n + \ \"startDateTime\": \"2021-03-02T21:25:58.9268903+00:00\",\r\n \"deviceGroupType\": + \"DeviceGroupDefinitions\",\r\n \"deviceGroupDefinition\": [\r\n \"fakeDeviceId\"\r\n + \ ],\r\n \"updateId\": {\r\n \"provider\": \"Contoso\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"2021.302.1323.55\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n + \ \"isRetry\": false\r\n }\r\n ]\r\n}" + headers: + content-length: + - '1041' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:05 GMT + traceparent: + - 00-013216d349700a4daf561681506bcbc4-488d9ce64ca0624e-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment.yaml new file mode 100644 index 000000000000..5e4cac163a5f --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment.yaml @@ -0,0 +1,36 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments/fakeDeploymentId + response: + body: + string: "{\r\n \"deploymentId\": \"fakeDeploymentId\",\r\n \"deploymentType\": + \"Complete\",\r\n \"startDateTime\": \"2021-03-02T20:04:52.8525661+00:00\",\r\n + \ \"deviceGroupType\": \"DeviceGroupDefinitions\",\r\n \"deviceGroupDefinition\": + [\r\n \"fakeDeviceId\"\r\n ],\r\n \"updateId\": {\r\n \"provider\": + \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n \"version\": \"fakeVersion\"\r\n + \ },\r\n \"isCanceled\": false,\r\n \"isCompleted\": false,\r\n \"isRetry\": + false\r\n}" + headers: + content-length: + - '439' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:05 GMT + traceparent: + - 00-052c4983497e5e4daba8cb65f9ef67c1-47c9812ba0bfe749-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_devices.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_devices.yaml new file mode 100644 index 000000000000..bfd4995e05d8 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_devices.yaml @@ -0,0 +1,32 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments/fakeDeploymentId/devicestates + response: + body: + string: "{\r\n \"value\": [\r\n {\r\n \"deviceId\": \"fakeDeviceId\",\r\n + \ \"deviceState\": \"Succeeded\",\r\n \"retryCount\": 0,\r\n \"movedOnToNewDeployment\": + true\r\n }\r\n ]\r\n}" + headers: + content-length: + - '170' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:06 GMT + traceparent: + - 00-20cc211550a0cb4ca90c3b8ab4bf4113-9f6f6592bc624547-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_devices_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_devices_not_found.yaml new file mode 100644 index 000000000000..2b07a93779f2 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_devices_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments/foo/devicestates + response: + body: + string: "{\r\n \"type\": \"https://tools.ietf.org/html/rfc7231#section-6.5.4\",\r\n + \ \"title\": \"Not Found\",\r\n \"status\": 404,\r\n \"traceId\": \"00-dbd7ca769980ff46bb569295bd3ddcb2-7b8b43beef8cd442-00\"\r\n}" + headers: + content-length: + - '183' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:07 GMT + traceparent: + - 00-dbd7ca769980ff46bb569295bd3ddcb2-46e373b58f5e3348-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_not_found.yaml new file mode 100644 index 000000000000..e0dac82fd44a --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments/foo + response: + body: + string: "{\r\n \"type\": \"https://tools.ietf.org/html/rfc7231#section-6.5.4\",\r\n + \ \"title\": \"Not Found\",\r\n \"status\": 404,\r\n \"traceId\": \"00-e62d4dbd4585e54184fdd7373688211c-950fd7f5c76f9c48-00\"\r\n}" + headers: + content-length: + - '183' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:07 GMT + traceparent: + - 00-e62d4dbd4585e54184fdd7373688211c-f9a2c004adcedf47-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_status.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_status.yaml new file mode 100644 index 000000000000..1f5461a295e6 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_status.yaml @@ -0,0 +1,34 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments/fakeDeploymentId/status + response: + body: + string: "{\r\n \"deploymentState\": \"Active\",\r\n \"totalDevices\": 1,\r\n + \ \"devicesIncompatibleCount\": 0,\r\n \"devicesAlreadyInDeploymentCount\": + 0,\r\n \"devicesInProgressCount\": 0,\r\n \"devicesCompletedFailedCount\": + 0,\r\n \"devicesCompletedSucceededCount\": 1,\r\n \"devicesCanceledCount\": + 0\r\n}" + headers: + content-length: + - '271' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:09 GMT + traceparent: + - 00-4e1ed909ec0869449bf76ee4d837ff9e-2fd486f8eadca641-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_status_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_status_not_found.yaml new file mode 100644 index 000000000000..d0040090bf58 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_deployments_service.test_get_deployment_status_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deployments/foo/status + response: + body: + string: "{\r\n \"type\": \"https://tools.ietf.org/html/rfc7231#section-6.5.4\",\r\n + \ \"title\": \"Not Found\",\r\n \"status\": 404,\r\n \"traceId\": \"00-2da1bd26ec910647b1e01a4c37083852-530db8392d09b641-00\"\r\n}" + headers: + content-length: + - '183' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:10 GMT + traceparent: + - 00-2da1bd26ec910647b1e01a4c37083852-a59151fd6fc35046-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_all_device_classes.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_all_device_classes.yaml new file mode 100644 index 000000000000..e5c12e26f111 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_all_device_classes.yaml @@ -0,0 +1,41 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deviceclasses + response: + body: + string: "{\r\n \"value\": [\r\n {\r\n \"deviceClassId\": \"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3\",\r\n + \ \"manufacturer\": \"Microsoft-Corporation\",\r\n \"model\": \"Virtual-Machine\",\r\n + \ \"bestCompatibleUpdateId\": {\r\n \"provider\": \"Microsoft-Corporation\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"111.0\"\r\n + \ }\r\n },\r\n {\r\n \"deviceClassId\": \"86705631a06a6d4745a516778f7e2e261a72c5b8\",\r\n + \ \"manufacturer\": \"ADUTeam\",\r\n \"model\": \"RefDevice\"\r\n + \ },\r\n {\r\n \"deviceClassId\": \"634a0b52a6e1fb54fe6b98e5b55534bb4800b77b\",\r\n + \ \"manufacturer\": \"ADUTeam\",\r\n \"model\": \"E2ETestDevice\"\r\n + \ },\r\n {\r\n \"deviceClassId\": \"fakeDeviceClassId\",\r\n \"manufacturer\": + \"Contoso\",\r\n \"model\": \"Virtual-Machine\",\r\n \"bestCompatibleUpdateId\": + {\r\n \"provider\": \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n + \ \"version\": \"2021.302.1323.55\"\r\n }\r\n }\r\n ]\r\n}" + headers: + content-length: + - '939' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:10 GMT + traceparent: + - 00-77b9af39f4bf7b4dbe98d52464567964-e4aa612be449074b-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_all_device_tags.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_all_device_tags.yaml new file mode 100644 index 000000000000..531674b06642 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_all_device_tags.yaml @@ -0,0 +1,30 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/devicetags + response: + body: + string: '{"value":[{"tagName":"functionaltests-groupname1","deviceCount":1}]}' + headers: + content-length: + - '68' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:12 GMT + traceparent: + - 00-356062ebccdb904e95ce7ab1e2b03c30-341f482efb75b249-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_all_devices.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_all_devices.yaml new file mode 100644 index 000000000000..089415c8471a --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_all_devices.yaml @@ -0,0 +1,32 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/devices + response: + body: + string: '{"value":[{"deviceId":"functionaltests-device1","moduleId":null,"deviceClassId":"c97c9c774a1c541ecc88e8c65b6431fd8b7eafc3","manufacturer":"Microsoft-Corporation","model":"Virtual-Machine","lastAttemptedUpdateId":null,"installedUpdateId":{"provider":"Microsoft-Corporation","name":"Virtual-Machine","version":"111.0"},"onLatestUpdate":true,"deploymentStatus":"InProgress","groupId":"functionaltests-groupname1","lastDeploymentId":"6f11870c-79b4-4d4e-85c4-b60e796ed283"},{"deviceId":"adu-raspi-e2etest-raps-prod-wus2","moduleId":null,"deviceClassId":"86705631a06a6d4745a516778f7e2e261a72c5b8","manufacturer":"ADUTeam","model":"RefDevice","lastAttemptedUpdateId":{"provider":"ADUTeam","name":"RefDevice","version":"1.0.3750.1"},"installedUpdateId":{"provider":"ADUTeam","name":"RefDevice","version":"1.0.3779.1"},"onLatestUpdate":false,"deploymentStatus":"Failed","groupId":null,"lastDeploymentId":"[ManagementE2ETest] + 9134a970-df08-4fe7-8cb6-10d32a0a61f7"},{"deviceId":"Pi13279821","moduleId":null,"deviceClassId":"634a0b52a6e1fb54fe6b98e5b55534bb4800b77b","manufacturer":"ADUTeam","model":"E2ETestDevice","lastAttemptedUpdateId":{"provider":"ADUTeam","name":"E2ETestDevice","version":"1.0.3750.1"},"installedUpdateId":{"provider":"ADUTeam","name":"E2ETestDevice","version":"1.0.3750.1"},"onLatestUpdate":false,"deploymentStatus":"Succeeded","groupId":null,"lastDeploymentId":"[ManagementE2ETest] + 043b16d7-35c4-4556-bdea-766c39686f25"},{"deviceId":"fakeDeviceId","moduleId":null,"deviceClassId":"fakeDeviceClassId","manufacturer":"Contoso","model":"Virtual-Machine","lastAttemptedUpdateId":{"provider":"Contoso","name":"Virtual-Machine","version":"fakeVersion"},"installedUpdateId":{"provider":"Contoso","name":"Virtual-Machine","version":"2021.302.1304.12"},"onLatestUpdate":false,"deploymentStatus":"InProgress","groupId":"fakeDeviceId","lastDeploymentId":"202fb59607c346cdb6bff3143668d86b"}]}' + headers: + content-length: + - '1923' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:12 GMT + traceparent: + - 00-c2a61dc4a01d7a43aabe7006106d5e20-c98c661009205740-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_all_groups.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_all_groups.yaml new file mode 100644 index 000000000000..56f5647b5879 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_all_groups.yaml @@ -0,0 +1,39 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/groups + response: + body: + string: "{\r\n \"value\": [\r\n {\r\n \"groupId\": \"Uncategorized\",\r\n + \ \"tags\": [],\r\n \"createdDateTime\": \"2021-02-04T21:55:58.7115058+00:00\",\r\n + \ \"groupType\": \"IoTHubTag\",\r\n \"deviceCount\": 3\r\n },\r\n + \ {\r\n \"groupId\": \"fakeDeviceId\",\r\n \"tags\": [\r\n \"fakeDeviceId\"\r\n + \ ],\r\n \"createdDateTime\": \"2021-02-09T23:28:03+00:00\",\r\n + \ \"groupType\": \"IoTHubTag\",\r\n \"deviceCount\": 1\r\n },\r\n + \ {\r\n \"groupId\": \"my-test\",\r\n \"tags\": [\r\n \"my-test\"\r\n + \ ],\r\n \"createdDateTime\": \"2021-02-15T01:11:54+00:00\",\r\n + \ \"groupType\": \"IoTHubTag\",\r\n \"deviceCount\": 0\r\n }\r\n + \ ]\r\n}" + headers: + content-length: + - '627' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:13 GMT + traceparent: + - 00-db60e1cf714d7a4e859f027acd7430be-7b7312b7b37dcb45-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device.yaml new file mode 100644 index 000000000000..662c72cb0b60 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device.yaml @@ -0,0 +1,30 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/devices/fakeDeviceId + response: + body: + string: '{"deviceId":"fakeDeviceId","moduleId":null,"deviceClassId":"fakeDeviceClassId","manufacturer":"Contoso","model":"Virtual-Machine","lastAttemptedUpdateId":{"provider":"Contoso","name":"Virtual-Machine","version":"fakeVersion"},"installedUpdateId":{"provider":"Contoso","name":"Virtual-Machine","version":"2021.302.1304.12"},"onLatestUpdate":false,"deploymentStatus":"InProgress","groupId":"fakeDeviceId","lastDeploymentId":"202fb59607c346cdb6bff3143668d86b"}' + headers: + content-length: + - '487' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:14 GMT + traceparent: + - 00-e2a8408a85e3114eb7ecf1fbafcd0bd1-9ee75fe83d443749-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class.yaml new file mode 100644 index 000000000000..d152c167e0f5 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class.yaml @@ -0,0 +1,33 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deviceclasses/fakeDeviceClassId + response: + body: + string: "{\r\n \"deviceClassId\": \"fakeDeviceClassId\",\r\n \"manufacturer\": + \"Contoso\",\r\n \"model\": \"Virtual-Machine\",\r\n \"bestCompatibleUpdateId\": + {\r\n \"provider\": \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n + \ \"version\": \"2021.302.1323.55\"\r\n }\r\n}" + headers: + content-length: + - '260' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:14 GMT + traceparent: + - 00-a79459368aa522469a606e0a1428af84-bcb130b01389334f-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_device_ids.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_device_ids.yaml new file mode 100644 index 000000000000..237d2d92bd75 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_device_ids.yaml @@ -0,0 +1,30 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deviceclasses/fakeDeviceClassId/deviceids + response: + body: + string: "{\r\n \"value\": [\r\n \"fakeDeviceId\"\r\n ]\r\n}" + headers: + content-length: + - '44' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:15 GMT + traceparent: + - 00-886869d63fdc4242a2d37304e2452e37-aeec6f75cc468046-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_device_ids_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_device_ids_not_found.yaml new file mode 100644 index 000000000000..08a9d53f872b --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_device_ids_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deviceclasses/foo/deviceids + response: + body: + string: "{\r\n \"type\": \"https://tools.ietf.org/html/rfc7231#section-6.5.4\",\r\n + \ \"title\": \"Not Found\",\r\n \"status\": 404,\r\n \"traceId\": \"00-181337c6e004de42ba5d5a87336f7b46-d396de9894f99648-00\"\r\n}" + headers: + content-length: + - '183' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:16 GMT + traceparent: + - 00-181337c6e004de42ba5d5a87336f7b46-3273b1ca12ce6a42-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_installable_updates.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_installable_updates.yaml new file mode 100644 index 000000000000..88b42ef7bdc8 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_installable_updates.yaml @@ -0,0 +1,50 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deviceclasses/fakeDeviceClassId/installableupdates + response: + body: + string: "{\r\n \"value\": [\r\n {\r\n \"provider\": \"contoso\",\r\n + \ \"name\": \"virtual-machine\",\r\n \"version\": \"2021.209.1457.25\"\r\n + \ },\r\n {\r\n \"provider\": \"contoso\",\r\n \"name\": \"virtual-machine\",\r\n + \ \"version\": \"2021.209.1525.54\"\r\n },\r\n {\r\n \"provider\": + \"contoso\",\r\n \"name\": \"virtual-machine\",\r\n \"version\": + \"2021.214.1700.20\"\r\n },\r\n {\r\n \"provider\": \"contoso\",\r\n + \ \"name\": \"virtual-machine\",\r\n \"version\": \"2021.214.1709.51\"\r\n + \ },\r\n {\r\n \"provider\": \"contoso\",\r\n \"name\": \"virtual-machine\",\r\n + \ \"version\": \"2021.301.1926.8\"\r\n },\r\n {\r\n \"provider\": + \"contoso\",\r\n \"name\": \"virtual-machine\",\r\n \"version\": + \"2021.302.914.51\"\r\n },\r\n {\r\n \"provider\": \"contoso\",\r\n + \ \"name\": \"virtual-machine\",\r\n \"version\": \"2021.302.1045.44\"\r\n + \ },\r\n {\r\n \"provider\": \"contoso\",\r\n \"name\": \"virtual-machine\",\r\n + \ \"version\": \"2021.302.1048.57\"\r\n },\r\n {\r\n \"provider\": + \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n \"version\": + \"fakeVersion\"\r\n },\r\n {\r\n \"provider\": \"Contoso\",\r\n + \ \"name\": \"Virtual-Machine\",\r\n \"version\": \"2021.302.1304.12\"\r\n + \ },\r\n {\r\n \"provider\": \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n + \ \"version\": \"2021.302.1307.58\"\r\n },\r\n {\r\n \"provider\": + \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n \"version\": + \"2021.302.1323.55\"\r\n }\r\n ]\r\n}" + headers: + content-length: + - '1412' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:17 GMT + traceparent: + - 00-c1a13c69e340914bbb05c22d2fed091f-3e0a64069da5754b-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_installable_updates_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_installable_updates_not_found.yaml new file mode 100644 index 000000000000..8e47944773fe --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_installable_updates_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deviceclasses/foo/installableupdates + response: + body: + string: "{\r\n \"type\": \"https://tools.ietf.org/html/rfc7231#section-6.5.4\",\r\n + \ \"title\": \"Not Found\",\r\n \"status\": 404,\r\n \"traceId\": \"00-964e3f2f8960564b8a79d9e8c75f15ce-deffb692f9d2f24e-00\"\r\n}" + headers: + content-length: + - '183' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:18 GMT + traceparent: + - 00-964e3f2f8960564b8a79d9e8c75f15ce-a571a8bf7c92d242-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_not_found.yaml new file mode 100644 index 000000000000..573714e79129 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_class_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/deviceclasses/foo + response: + body: + string: "{\r\n \"type\": \"https://tools.ietf.org/html/rfc7231#section-6.5.4\",\r\n + \ \"title\": \"Not Found\",\r\n \"status\": 404,\r\n \"traceId\": \"00-2832a070238b064697c9123549708132-06167a5f47314946-00\"\r\n}" + headers: + content-length: + - '183' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:19 GMT + traceparent: + - 00-2832a070238b064697c9123549708132-28c00f3c297d0f4b-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_not_found.yaml new file mode 100644 index 000000000000..8a5d582fe5f0 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/devices/foo + response: + body: + string: '{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.4","title":"Not + Found","status":404,"traceId":"00-b1ea1c0b711c0b49929c690e21b3c1da-f0960fd372e63243-00"}' + headers: + content-length: + - '161' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:20 GMT + traceparent: + - 00-b1ea1c0b711c0b49929c690e21b3c1da-e50af4d51122fc4c-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_tag.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_tag.yaml new file mode 100644 index 000000000000..48ecf8af8621 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_tag.yaml @@ -0,0 +1,30 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/devicetags/fakeDeviceId + response: + body: + string: '{"tagName":"fakeDeviceId","deviceCount":1}' + headers: + content-length: + - '43' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:21 GMT + traceparent: + - 00-fe598c68d53eaf4790ec19c45a3c441d-7e61587f1d103b43-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_tag_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_tag_not_found.yaml new file mode 100644 index 000000000000..8070f3d4a794 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_device_tag_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/devicetags/foo + response: + body: + string: '{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.4","title":"Not + Found","status":404,"traceId":"00-930d63bbd2c48843ba0c8b5b1cff5e69-6d743b257542714b-00"}' + headers: + content-length: + - '161' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:21 GMT + traceparent: + - 00-930d63bbd2c48843ba0c8b5b1cff5e69-65d916444a512443-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group.yaml new file mode 100644 index 000000000000..55bd01b4e7b6 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group.yaml @@ -0,0 +1,32 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/groups/fakeDeviceId + response: + body: + string: "{\r\n \"groupId\": \"fakeDeviceId\",\r\n \"tags\": [\r\n \"fakeDeviceId\"\r\n + \ ],\r\n \"createdDateTime\": \"2021-02-09T23:28:03+00:00\",\r\n \"groupType\": + \"IoTHubTag\",\r\n \"deviceCount\": 1\r\n}" + headers: + content-length: + - '175' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:22 GMT + traceparent: + - 00-678e381993357e4dad257f6ec10a7685-b97a2e33bdeb3442-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_best_updates.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_best_updates.yaml new file mode 100644 index 000000000000..a47ae4c414f3 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_best_updates.yaml @@ -0,0 +1,33 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/groups/fakeDeviceId/bestUpdates + response: + body: + string: "{\r\n \"value\": [\r\n {\r\n \"updateId\": {\r\n \"provider\": + \"Contoso\",\r\n \"name\": \"Virtual-Machine\",\r\n \"version\": + \"2021.302.1323.55\"\r\n },\r\n \"deviceCount\": 1\r\n }\r\n + \ ]\r\n}" + headers: + content-length: + - '199' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:22 GMT + traceparent: + - 00-76d320dfe7d88840a75ec49ff70a85ac-9596d55c6d08f54a-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_best_updates_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_best_updates_not_found.yaml new file mode 100644 index 000000000000..e9ca30e19927 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_best_updates_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/groups/foo/bestUpdates + response: + body: + string: "{\r\n \"type\": \"https://tools.ietf.org/html/rfc7231#section-6.5.4\",\r\n + \ \"title\": \"Not Found\",\r\n \"status\": 404,\r\n \"traceId\": \"00-6181fb2b41cff64484cb308fc45541b5-4fe05f86ed8a0a48-00\"\r\n}" + headers: + content-length: + - '183' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:24 GMT + traceparent: + - 00-6181fb2b41cff64484cb308fc45541b5-4f7ebee99a752849-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_not_found.yaml new file mode 100644 index 000000000000..01cd373c6044 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/groups/foo + response: + body: + string: "{\r\n \"type\": \"https://tools.ietf.org/html/rfc7231#section-6.5.4\",\r\n + \ \"title\": \"Not Found\",\r\n \"status\": 404,\r\n \"traceId\": \"00-383b3da7eb95f849a589a786711a94cf-68d1da681f03c44d-00\"\r\n}" + headers: + content-length: + - '183' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:24 GMT + traceparent: + - 00-383b3da7eb95f849a589a786711a94cf-dae45900e57bcc44-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_update_compliance.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_update_compliance.yaml new file mode 100644 index 000000000000..1f2310947930 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_update_compliance.yaml @@ -0,0 +1,32 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/groups/fakeDeviceId/updateCompliance + response: + body: + string: "{\r\n \"totalDeviceCount\": 1,\r\n \"onLatestUpdateDeviceCount\": + 0,\r\n \"newUpdatesAvailableDeviceCount\": 1,\r\n \"updatesInProgressDeviceCount\": + 0\r\n}" + headers: + content-length: + - '142' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:25 GMT + traceparent: + - 00-df106ff640b0fd47877397812082e927-3ba9bb43a702bc49-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_update_compliance_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_update_compliance_not_found.yaml new file mode 100644 index 000000000000..6fcb4c8bc123 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_group_update_compliance_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/groups/foo/updateCompliance + response: + body: + string: "{\r\n \"type\": \"https://tools.ietf.org/html/rfc7231#section-6.5.4\",\r\n + \ \"title\": \"Not Found\",\r\n \"status\": 404,\r\n \"traceId\": \"00-d7613c46a189854891bcb28880cfa038-c3463e6e4fcf2c49-00\"\r\n}" + headers: + content-length: + - '183' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:25 GMT + traceparent: + - 00-d7613c46a189854891bcb28880cfa038-c23f0238dbf36140-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_update_compliance.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_update_compliance.yaml new file mode 100644 index 000000000000..9c19678d0941 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_devices_service.test_get_update_compliance.yaml @@ -0,0 +1,32 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/management/updatecompliance + response: + body: + string: "{\r\n \"totalDeviceCount\": 4,\r\n \"onLatestUpdateDeviceCount\": + 0,\r\n \"newUpdatesAvailableDeviceCount\": 1,\r\n \"updatesInProgressDeviceCount\": + 0\r\n}" + headers: + content-length: + - '142' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:27 GMT + traceparent: + - 00-efc7fbb73f1aa24fbbb3d460257310d5-fed027b708508541-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_file.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_file.yaml new file mode 100644 index 000000000000..a3d61fc5e176 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_file.yaml @@ -0,0 +1,34 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/updates/providers/Contoso/names/Virtual-Machine/versions/fakeVersion/files/00000 + response: + body: + string: '{"fileId":"00000","fileName":"setup.exe","sizeInBytes":94,"hashes":{"Sha256":"nTsYZEDeW9554a4YGmawsypogbG8zhc1IgvOE2PbSsA="},"etag":"\"490fe67f-4cc1-4b69-8c7e-80e9665060f7\""}' + headers: + cache-control: + - max-age=60, private + content-length: + - '175' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:28 GMT + etag: + - '"490fe67f-4cc1-4b69-8c7e-80e9665060f7"' + traceparent: + - 00-5063095459edbd44a973efd0f689b35b-5ded7f1c14bafd43-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_file_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_file_not_found.yaml new file mode 100644 index 000000000000..bf975ab805dc --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_file_not_found.yaml @@ -0,0 +1,33 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/updates/providers/Contoso/names/Virtual-Machine/versions/fakeVersion/files/foobar + response: + body: + string: '{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.4","title":"Not + Found","status":404,"traceId":"00-2b22c097fb794d4db04f8a945cbf0295-407acfd6cd579c4b-00"}' + headers: + cache-control: + - max-age=60, private + content-length: + - '161' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:29 GMT + traceparent: + - 00-2b22c097fb794d4db04f8a945cbf0295-4edb1503886b1b48-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_files.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_files.yaml new file mode 100644 index 000000000000..546e5091f881 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_files.yaml @@ -0,0 +1,30 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/updates/providers/Contoso/names/Virtual-Machine/versions/fakeVersion/files + response: + body: + string: '{"value":["00000"]}' + headers: + content-length: + - '19' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:30 GMT + traceparent: + - 00-34d379614baba848943d409a43f7e547-dbc7297a17655a46-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_files_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_files_not_found.yaml new file mode 100644 index 000000000000..d82ef32e937d --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_files_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/updates/providers/foo/names/bar/versions/0.0.0.1/files + response: + body: + string: '{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.4","title":"Not + Found","status":404,"traceId":"00-845f520fbd0e3944b68269cf8f03756d-68c40c79a20d964f-00"}' + headers: + content-length: + - '161' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:31 GMT + traceparent: + - 00-845f520fbd0e3944b68269cf8f03756d-db60df95c62fcb4d-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_names.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_names.yaml new file mode 100644 index 000000000000..4630712aa82f --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_names.yaml @@ -0,0 +1,30 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/updates/providers/Contoso/names + response: + body: + string: '{"value":["Virtual-Machine"]}' + headers: + content-length: + - '29' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:32 GMT + traceparent: + - 00-568628a0834a86468f32eb43d3ee0910-c2bfd76c9b6a814d-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_names_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_names_not_found.yaml new file mode 100644 index 000000000000..d3f48616a12d --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_names_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/updates/providers/foo/names + response: + body: + string: '{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.4","title":"Not + Found","status":404,"traceId":"00-e740fa28b2f55b43bd859d377986e4f3-668875e706356241-00"}' + headers: + content-length: + - '161' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:33 GMT + traceparent: + - 00-e740fa28b2f55b43bd859d377986e4f3-ec439dbab8519d4b-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_operation.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_operation.yaml new file mode 100644 index 000000000000..3930eae95bc3 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_operation.yaml @@ -0,0 +1,32 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/updates/operations/e3a75d1b-e359-4bbd-a84c-68fbfa8b7b9f%3Fapi-version%3D2 + response: + body: + string: '{"operationId":"e3a75d1b-e359-4bbd-a84c-68fbfa8b7b9f","status":"Succeeded","updateId":{"provider":"Contoso","name":"Virtual-Machine","version":"fakeVersion"},"resourceLocation":"/deviceupdate/blue/updates/providers/Contoso/names/Virtual-Machine/versions/fakeVersion?api-version=2","traceId":"c72d7514826f124fb37678796aa477ae","lastActionDateTime":"2021-03-02T20:04:47.9517198Z","createdDateTime":"2021-03-02T20:02:50.6192614Z","etag":"\"a1874484-e4be-4643-b992-c5d43ed6947c\""}' + headers: + content-length: + - '487' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:34 GMT + etag: + - '"a1874484-e4be-4643-b992-c5d43ed6947c"' + traceparent: + - 00-39d6d01ffb9889408a479168c2babf44-4ca86c5f90d6af4c-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_operation_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_operation_not_found.yaml new file mode 100644 index 000000000000..fe72a449878f --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_operation_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/updates/operations/foo + response: + body: + string: '{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.4","title":"Not + Found","status":404,"traceId":"00-6d9a08b7cf0f4747b145eb74e0a84210-7f66fd2d6c817a40-00"}' + headers: + content-length: + - '161' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:34 GMT + traceparent: + - 00-6d9a08b7cf0f4747b145eb74e0a84210-f701789508ecb745-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_providers.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_providers.yaml new file mode 100644 index 000000000000..29c8a5892725 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_providers.yaml @@ -0,0 +1,30 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/updates/providers + response: + body: + string: '{"value":["Contoso","Microsoft-Corporation","Test-Content"]}' + headers: + content-length: + - '60' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:35 GMT + traceparent: + - 00-0e7cf552bef5594799f3358c36fe82c6-b6c20cbe9fcbb047-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_update.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_update.yaml new file mode 100644 index 000000000000..61ca4a878a80 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_update.yaml @@ -0,0 +1,34 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/updates/providers/Contoso/names/Virtual-Machine/versions/fakeVersion + response: + body: + string: '{"updateId":{"provider":"Contoso","name":"Virtual-Machine","version":"fakeVersion"},"updateType":"microsoft/swupdate:1","installedCriteria":"1.2.3.4","compatibility":[{"deviceManufacturer":"contoso","deviceModel":"virtual-machine"}],"manifestVersion":"2.0","importedDateTime":"2021-03-02T20:04:47.8946059Z","createdDateTime":"2021-03-02T20:02:49.3084164Z","etag":"\"dffc9614-c1c4-4289-b41f-26ac37101fbe\""}' + headers: + cache-control: + - max-age=60, private + content-length: + - '411' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:35 GMT + etag: + - '"dffc9614-c1c4-4289-b41f-26ac37101fbe"' + traceparent: + - 00-5c98c753ec0d494cba79df3183408daa-c14cfd32e18c3b4d-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_update_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_update_not_found.yaml new file mode 100644 index 000000000000..4996c93b40f6 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_update_not_found.yaml @@ -0,0 +1,33 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/updates/providers/foo/names/bar/versions/0.0.0.1 + response: + body: + string: '{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.4","title":"Not + Found","status":404,"traceId":"00-99534c76c5745947a4c96681bcbc5238-a42189f9841d3547-00"}' + headers: + cache-control: + - max-age=60, private + content-length: + - '161' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:36 GMT + traceparent: + - 00-99534c76c5745947a4c96681bcbc5238-65e515e880649f41-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_versions.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_versions.yaml new file mode 100644 index 000000000000..e0d927de4f52 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_versions.yaml @@ -0,0 +1,30 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/updates/providers/Contoso/names/Virtual-Machine/versions + response: + body: + string: '{"value":["2021.209.1457.25","2021.209.1525.54","2021.214.1700.20","2021.214.1709.51","2021.301.1926.8","2021.302.914.51","2021.302.1045.44","2021.302.1048.57","fakeVersion","2021.302.1304.12","2021.302.1307.58","2021.302.1323.55"]}' + headers: + content-length: + - '237' + content-type: + - application/json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:37 GMT + traceparent: + - 00-13830d03a14e7949a0c9e8925b2dbf30-3c93113c533b7344-00 + status: + code: 200 + message: OK +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_versions_not_found.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_versions_not_found.yaml new file mode 100644 index 000000000000..126a15652b56 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_get_versions_not_found.yaml @@ -0,0 +1,31 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: GET + uri: https://fake_endpoint.com/deviceupdate/blue/v2/updates/providers/foo/names/bar/versions + response: + body: + string: '{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.4","title":"Not + Found","status":404,"traceId":"00-5171eb6835f462488f442a8b9c65e597-dd3d2261c8afc944-00"}' + headers: + content-length: + - '161' + content-type: + - application/problem+json; charset=utf-8 + date: + - Wed, 03 Mar 2021 18:10:38 GMT + traceparent: + - 00-5171eb6835f462488f442a8b9c65e597-95d6072c32eda848-00 + status: + code: 404 + message: Not Found +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_import_update.yaml b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_import_update.yaml new file mode 100644 index 000000000000..b187f7340591 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/recordings/test_updates_service.test_import_update.yaml @@ -0,0 +1,38 @@ +interactions: +- request: + body: '{"importManifest": {"url": "https://adutest.blob.core.windows.net/test/Ak1xigPLmur511bYfCvzeC?sv=2019-02-02&sr=b&sig=L9RZxCUwduStz0m1cj4YnXt6OJCvWSe9SPseum3cclE%3D&se=2020-05-08T20%3A52%3A51Z&sp=r", + "sizeInBytes": 453, "hashes": {"SHA256": "Ak1xigPLmur511bYfCvzeCwF6r/QxiBKeEDHOvHPzr4="}}, + "files": [{"filename": "setup.exe", "url": "https://adutest.blob.core.windows.net/test/zVknnlx1tyYSMHY28LZVzk?sv=2019-02-02&sr=b&sig=QtS6bAOcHon18wLwIt9uvHIM%2B4M27EoVPNP4RWpMjyw%3D&se=2020-05-08T20%3A52%3A51Z&sp=r"}]}' + headers: + Accept: + - '*/*' + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + Content-Length: + - '508' + Content-Type: + - application/json + User-Agent: + - azsdk-python-iot-deviceupdate/1.0.0b1 Python/3.9.1 (macOS-10.13.6-x86_64-i386-64bit) + method: POST + uri: https://fake_endpoint.com/deviceupdate/blue/v2/updates?action=import + response: + body: + string: '' + headers: + content-length: + - '0' + date: + - Wed, 03 Mar 2021 18:10:39 GMT + location: + - /deviceupdate/blue/updates/operations/53cbbb48-9a41-463b-969c-20b19f1e8b26?api-version=2 + operation-location: + - /deviceupdate/blue/updates/operations/53cbbb48-9a41-463b-969c-20b19f1e8b26?api-version=2 + traceparent: + - 00-bdf2ad7a5884f54fb1cfcf42479aadb2-5e9d9e99d7defe45-00 + status: + code: 202 + message: Accepted +version: 1 diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/test_deployments_service.py b/sdk/deviceupdate/azure-iot-deviceupdate/tests/test_deployments_service.py new file mode 100644 index 000000000000..6f63f8357084 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/test_deployments_service.py @@ -0,0 +1,139 @@ +# coding: utf-8 +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import pytest +from azure.core.exceptions import ResourceNotFoundError +from azure.iot.deviceupdate import DeviceUpdateClient +from azure.iot.deviceupdate.models import * +from testcase import DeviceUpdateTest, DeviceUpdatePowerShellPreparer, callback +import uuid +from datetime import datetime + + +class DeploymentsClientTestCase(DeviceUpdateTest): + + @DeviceUpdatePowerShellPreparer() + def test_get_all_deployments(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.deployments.get_all_deployments() + self.assertIsNotNone(response) + providers = list(response) + self.assertTrue(len(providers) > 0) + + @DeviceUpdatePowerShellPreparer() + def test_get_deployment( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + deviceupdate_deployment_id, + deviceupdate_provider, + deviceupdate_model, + deviceupdate_version, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.deployments.get_deployment(deviceupdate_deployment_id) + self.assertIsNotNone(response) + self.assertEqual(deviceupdate_deployment_id, response.deployment_id) + self.assertEqual(DeploymentType.complete, response.deployment_type) + self.assertEqual(DeviceGroupType.DEVICE_GROUP_DEFINITIONS, response.device_group_type) + self.assertEqual(deviceupdate_provider, response.update_id.provider) + self.assertEqual(deviceupdate_model, response.update_id.name) + self.assertEqual(deviceupdate_version, response.update_id.version) + + @DeviceUpdatePowerShellPreparer() + def test_get_deployment_not_found(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + _ = client.deployments.get_deployment("foo") + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @pytest.mark.live_test_only + @DeviceUpdatePowerShellPreparer() + def test_create_cancel_and_delete_deployment( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + deviceupdate_device_id, + deviceupdate_provider, + deviceupdate_model, + deviceupdate_version, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + # The following test works *ONLY* when run LIVE -> not recorded + + deployment_id = uuid.uuid4().hex + response = client.deployments.create_or_update_deployment( + deployment_id=deployment_id, + deployment=Deployment( + deployment_id=deployment_id, + deployment_type=DeploymentType.complete, + start_date_time=datetime(2020, 1, 1, 0, 0, 0, 0), + device_group_type=DeviceGroupType.DEVICE_GROUP_DEFINITIONS, + device_group_definition=[deviceupdate_device_id], + update_id=UpdateId(provider=deviceupdate_provider, name=deviceupdate_model, version=deviceupdate_version))) + self.assertIsNotNone(response) + self.assertEqual(deployment_id, response.deployment_id) + + response = client.deployments.get_deployment(deployment_id) + self.assertIsNotNone(response) + self.assertEqual(deployment_id, response.deployment_id) + + response = client.deployments.get_deployment_status(deployment_id) + self.assertIsNotNone(response) + self.assertEqual(DeploymentState.ACTIVE, response.deployment_state) + + response, value, _ = client.deployments.cancel_deployment(deployment_id, cls=callback) + self.assertIsNotNone(response) + self.assertEqual(200, response.http_response.status_code) + self.assertIsNotNone(value) + self.assertEqual(deployment_id, value.deployment_id) + self.assertTrue(value.is_canceled) + + response, _, _ = client.deployments.delete_deployment(deployment_id, cls=callback) + self.assertIsNotNone(response) + self.assertEqual(200, response.http_response.status_code) + + try: + _ = client.deployments.get_deployment(deployment_id) + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @DeviceUpdatePowerShellPreparer() + def test_get_deployment_status(self, deviceupdate_account_endpoint, deviceupdate_instance_id, deviceupdate_deployment_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.deployments.get_deployment_status(deviceupdate_deployment_id) + self.assertIsNotNone(response) + self.assertEqual(DeploymentState.ACTIVE, response.deployment_state) + + @DeviceUpdatePowerShellPreparer() + def test_get_deployment_status_not_found(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + _ = client.deployments.get_deployment_status("foo") + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @DeviceUpdatePowerShellPreparer() + def test_get_deployment_devices(self, deviceupdate_account_endpoint, deviceupdate_instance_id, deviceupdate_deployment_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.deployments.get_deployment_devices(deviceupdate_deployment_id) + self.assertIsNotNone(response) + providers = list(response) + self.assertTrue(len(providers) > 0) + + @DeviceUpdatePowerShellPreparer() + def test_get_deployment_devices_not_found(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + response = client.deployments.get_deployment_devices("foo") + _ = list(response) + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/test_devices_service.py b/sdk/deviceupdate/azure-iot-deviceupdate/tests/test_devices_service.py new file mode 100644 index 000000000000..e71b54fc7d49 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/test_devices_service.py @@ -0,0 +1,221 @@ +# coding: utf-8 +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- + +from azure.core.exceptions import ResourceNotFoundError +from azure.iot.deviceupdate import DeviceUpdateClient +from azure.iot.deviceupdate.models import * +from testcase import DeviceUpdateTest, DeviceUpdatePowerShellPreparer + + +class DevicesClientTestCase(DeviceUpdateTest): + + @DeviceUpdatePowerShellPreparer() + def test_get_all_device_classes(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.devices.get_all_device_classes() + self.assertIsNotNone(response) + providers = list(response) + self.assertTrue(len(providers) > 0) + + @DeviceUpdatePowerShellPreparer() + def test_get_device_class( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + deviceupdate_device_class_id, + deviceupdate_provider, + deviceupdate_model, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.devices.get_device_class(deviceupdate_device_class_id) + self.assertIsNotNone(response) + self.assertEqual(deviceupdate_provider, response.manufacturer) + self.assertEqual(deviceupdate_model, response.model) + + @DeviceUpdatePowerShellPreparer() + def test_get_device_class_not_found(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + _ = client.devices.get_device_class("foo") + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @DeviceUpdatePowerShellPreparer() + def test_get_device_class_device_ids( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + deviceupdate_device_class_id, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.devices.get_device_class_device_ids(deviceupdate_device_class_id) + self.assertIsNotNone(response) + providers = list(response) + self.assertTrue(len(providers) > 0) + + @DeviceUpdatePowerShellPreparer() + def test_get_device_class_device_ids_not_found(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + response = client.devices.get_device_class_device_ids("foo") + _ = list(response) + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @DeviceUpdatePowerShellPreparer() + def test_get_device_class_installable_updates( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + deviceupdate_device_class_id, + deviceupdate_provider, + deviceupdate_model, + deviceupdate_version, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.devices.get_device_class_installable_updates(deviceupdate_device_class_id) + self.assertIsNotNone(response) + providers = list(response) + self.assertTrue(len(providers) > 0) + self.assertTrue(UpdateId(provider=deviceupdate_provider, name=deviceupdate_model, version=deviceupdate_version) in providers) + + @DeviceUpdatePowerShellPreparer() + def test_get_device_class_installable_updates_not_found(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + response = client.devices.get_device_class_installable_updates("foo") + _ = list(response) + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @DeviceUpdatePowerShellPreparer() + def test_get_all_devices(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.devices.get_all_devices() + self.assertIsNotNone(response) + providers = list(response) + self.assertTrue(len(providers) > 0) + + @DeviceUpdatePowerShellPreparer() + def test_get_device( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + deviceupdate_device_id, + deviceupdate_provider, + deviceupdate_model, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.devices.get_device(deviceupdate_device_id) + self.assertIsNotNone(response) + self.assertEqual(deviceupdate_provider, response.manufacturer) + self.assertEqual(deviceupdate_model, response.model) + + @DeviceUpdatePowerShellPreparer() + def test_get_device_not_found(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + _ = client.devices.get_device("foo") + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @DeviceUpdatePowerShellPreparer() + def test_get_update_compliance(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.devices.get_update_compliance() + self.assertIsNotNone(response) + self.assertTrue(response.total_device_count > 0) + + @DeviceUpdatePowerShellPreparer() + def test_get_all_device_tags(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.devices.get_all_device_tags() + self.assertIsNotNone(response) + providers = list(response) + self.assertTrue(len(providers) > 0) + + @DeviceUpdatePowerShellPreparer() + def test_get_device_tag(self, deviceupdate_account_endpoint, deviceupdate_instance_id, deviceupdate_device_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + tag_name = deviceupdate_device_id + response = client.devices.get_device_tag(tag_name) + self.assertIsNotNone(response) + self.assertEqual(tag_name, response.tag_name) + + @DeviceUpdatePowerShellPreparer() + def test_get_device_tag_not_found(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + _ = client.devices.get_device_tag("foo") + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @DeviceUpdatePowerShellPreparer() + def test_get_all_groups(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.devices.get_all_groups() + self.assertIsNotNone(response) + providers = list(response) + self.assertTrue(len(providers) > 0) + + @DeviceUpdatePowerShellPreparer() + def test_get_group(self, deviceupdate_account_endpoint, deviceupdate_instance_id, deviceupdate_device_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + group_id = deviceupdate_device_id + response = client.devices.get_group(group_id) + self.assertIsNotNone(response) + self.assertEqual(group_id, response.group_id) + + @DeviceUpdatePowerShellPreparer() + def test_get_group_not_found(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + _ = client.devices.get_group("foo") + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @DeviceUpdatePowerShellPreparer() + def test_get_group_update_compliance(self, deviceupdate_account_endpoint, deviceupdate_instance_id, deviceupdate_device_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + group_id = deviceupdate_device_id + response = client.devices.get_group_update_compliance(group_id) + self.assertIsNotNone(response) + self.assertTrue(response.total_device_count > 0) + + @DeviceUpdatePowerShellPreparer() + def test_get_group_update_compliance_not_found(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + _ = client.devices.get_group_update_compliance("foo") + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @DeviceUpdatePowerShellPreparer() + def test_get_group_best_updates(self, deviceupdate_account_endpoint, deviceupdate_instance_id, deviceupdate_device_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + group_id = deviceupdate_device_id + response = client.devices.get_group_best_updates(group_id) + self.assertIsNotNone(response) + updates = list(response) + self.assertTrue(len(updates) > 0) + + @DeviceUpdatePowerShellPreparer() + def test_get_group_best_updates_not_found(self, deviceupdate_account_endpoint, deviceupdate_instance_id): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + response = client.devices.get_group_best_updates("foo") + _ = list(response) + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/test_updates_service.py b/sdk/deviceupdate/azure-iot-deviceupdate/tests/test_updates_service.py new file mode 100644 index 000000000000..8229e82412d2 --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/test_updates_service.py @@ -0,0 +1,231 @@ +# coding: utf-8 +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- + +import pytest +from azure.core.exceptions import ResourceNotFoundError +from azure.iot.deviceupdate import DeviceUpdateClient +from azure.iot.deviceupdate.models import * +from testcase import DeviceUpdateTest, DeviceUpdatePowerShellPreparer, callback + + +class UpdatesClientTestCase(DeviceUpdateTest): + @DeviceUpdatePowerShellPreparer() + def test_import_update( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + manifest = ImportManifestMetadata( + url="https://adutest.blob.core.windows.net/test/Ak1xigPLmur511bYfCvzeC?sv=2019-02-02&sr=b&sig=L9RZxCUwduStz0m1cj4YnXt6OJCvWSe9SPseum3cclE%3D&se=2020-05-08T20%3A52%3A51Z&sp=r", + size_in_bytes=453, + hashes={"SHA256":"Ak1xigPLmur511bYfCvzeCwF6r/QxiBKeEDHOvHPzr4="}) + content = ImportUpdateInput( + import_manifest=manifest, + files=[FileImportMetadata( + filename="setup.exe", + url="https://adutest.blob.core.windows.net/test/zVknnlx1tyYSMHY28LZVzk?sv=2019-02-02&sr=b&sig=QtS6bAOcHon18wLwIt9uvHIM%2B4M27EoVPNP4RWpMjyw%3D&se=2020-05-08T20%3A52%3A51Z&sp=r")] + ) + response, value, headers = client.updates.import_update(content, cls=callback) + self.assertIsNotNone(response) + self.assertEqual(202, response.http_response.status_code) + self.assertIsNone(value) + self.assertIsNotNone(headers) + self.assertIsNotNone(headers['Location']) + self.assertIsNotNone(headers['Operation-Location']) + self.assertEqual(headers['Location'], headers['Operation-Location']) + + @DeviceUpdatePowerShellPreparer() + def test_get_update( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + deviceupdate_provider, + deviceupdate_model, + deviceupdate_version, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.updates.get_update(deviceupdate_provider, deviceupdate_model, deviceupdate_version) + self.assertIsNotNone(response) + self.assertEqual(deviceupdate_provider, response.update_id.provider) + self.assertEqual(deviceupdate_model, response.update_id.name) + self.assertEqual(deviceupdate_version, response.update_id.version) + + @DeviceUpdatePowerShellPreparer() + def test_get_update_not_found( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + _ = client.updates.get_update("foo", "bar", "0.0.0.1") + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @DeviceUpdatePowerShellPreparer() + def test_get_providers( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.updates.get_providers() + self.assertIsNotNone(response) + providers = list(response) + self.assertTrue(len(providers) > 0) + + @DeviceUpdatePowerShellPreparer() + def test_get_names( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + deviceupdate_provider, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.updates.get_names(deviceupdate_provider) + self.assertIsNotNone(response) + names = list(response) + self.assertTrue(len(names) > 0) + + @DeviceUpdatePowerShellPreparer() + def test_get_names_not_found( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + response = client.updates.get_names("foo") + _ = list(response) + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @DeviceUpdatePowerShellPreparer() + def test_get_versions( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + deviceupdate_provider, + deviceupdate_model, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.updates.get_versions(deviceupdate_provider, deviceupdate_model) + self.assertIsNotNone(response) + versions = list(response) + self.assertTrue(len(versions) > 0) + + @DeviceUpdatePowerShellPreparer() + def test_get_versions_not_found( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + response = client.updates.get_versions("foo", "bar") + _ = list(response) + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @DeviceUpdatePowerShellPreparer() + def test_get_files( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + deviceupdate_provider, + deviceupdate_model, + deviceupdate_version, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.updates.get_files(deviceupdate_provider, deviceupdate_model, deviceupdate_version) + self.assertIsNotNone(response) + files = list(response) + self.assertTrue(len(files) > 0) + + @DeviceUpdatePowerShellPreparer() + def test_get_files_not_found( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + response = client.updates.get_files("foo", "bar", "0.0.0.1") + _ = list(response) + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @DeviceUpdatePowerShellPreparer() + def test_get_file( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + deviceupdate_provider, + deviceupdate_model, + deviceupdate_version, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.updates.get_file(deviceupdate_provider, deviceupdate_model, deviceupdate_version, "00000") + self.assertIsNotNone(response) + self.assertEqual("00000", response.file_id) + + @DeviceUpdatePowerShellPreparer() + def test_get_file_not_found( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + deviceupdate_provider, + deviceupdate_model, + deviceupdate_version, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + file = client.updates.get_file(deviceupdate_provider, deviceupdate_model, deviceupdate_version, "foobar") + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @pytest.mark.live_test_only + @DeviceUpdatePowerShellPreparer() + def test_get_operation( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + deviceupdate_operation_id, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.updates.get_operation(deviceupdate_operation_id) + self.assertIsNotNone(response) + self.assertEqual(response.status, OperationStatus.succeeded) + + @DeviceUpdatePowerShellPreparer() + def test_get_operation_not_found( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + try: + _ = client.updates.get_operation("foo") + self.fail("NotFound expected") + except ResourceNotFoundError as e: + self.assertEqual(404, e.status_code) + + @DeviceUpdatePowerShellPreparer() + def test_get_operations( + self, + deviceupdate_account_endpoint, + deviceupdate_instance_id, + ): + client = self.create_client(account_endpoint=deviceupdate_account_endpoint, instance_id=deviceupdate_instance_id) + response = client.updates.get_operations(None, 1) + self.assertIsNotNone(response) diff --git a/sdk/deviceupdate/azure-iot-deviceupdate/tests/testcase.py b/sdk/deviceupdate/azure-iot-deviceupdate/tests/testcase.py new file mode 100644 index 000000000000..268c084f919a --- /dev/null +++ b/sdk/deviceupdate/azure-iot-deviceupdate/tests/testcase.py @@ -0,0 +1,38 @@ +# coding: utf-8 +# ------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# -------------------------------------------------------------------------- +import functools +from devtools_testutils import AzureTestCase, PowerShellPreparer +from azure.iot.deviceupdate import DeviceUpdateClient + + +class DeviceUpdateTest(AzureTestCase): + + def create_client(self, account_endpoint, instance_id): + credential = self.get_credential(DeviceUpdateClient) + return self.create_client_from_credential( + DeviceUpdateClient, + credential=credential, + account_endpoint=account_endpoint, + instance_id=instance_id, + ) + +DeviceUpdatePowerShellPreparer = functools.partial( + PowerShellPreparer, + "deviceupdate", + deviceupdate_account_endpoint="fake_endpoint.com", + deviceupdate_instance_id="blue", + deviceupdate_operation_id="fakeOperationId", + deviceupdate_provider="Contoso", + deviceupdate_model="Virtual-Machine", + deviceupdate_version="fakeVersion", + deviceupdate_deployment_id="fakeDeploymentId", + deviceupdate_device_id="fakeDeviceId", + deviceupdate_device_class_id="fakeDeviceClassId" +) + +def callback(response, value, headers): + return response, value, headers diff --git a/sdk/deviceupdate/ci.yml b/sdk/deviceupdate/ci.yml index 723b97cb3398..cf11a513ebdf 100644 --- a/sdk/deviceupdate/ci.yml +++ b/sdk/deviceupdate/ci.yml @@ -31,5 +31,7 @@ extends: parameters: ServiceDirectory: deviceupdate Artifacts: + - name: azure-iot-deviceupdate + safeName: azureiotdeviceupdate - name: azure_mgmt_deviceupdate safeName: azuremgmtdeviceupdate \ No newline at end of file diff --git a/shared_requirements.txt b/shared_requirements.txt index 4c5403b260e5..6184e0e6d8c0 100644 --- a/shared_requirements.txt +++ b/shared_requirements.txt @@ -1,4 +1,5 @@ azure-ai-nspkg +azure-iot-nspkg azure-applicationinsights~=0.1.0 azure-batch~=4.1 azure-cognitiveservices-nspkg @@ -196,3 +197,4 @@ opentelemetry-sdk==0.17b0 #override azure-core-tracing-opentelemetry opentelemetry-api==0.17b0 #override azure-identity six>=1.12.0 #override azure-mixedreality-authentication azure-core<2.0.0,>=1.4.0 +#override azure-iot-deviceupdate azure-core<2.0.0,>=1.6.0