From fb01bef10c9eaeb92c4ed2a5ea7939f680608f74 Mon Sep 17 00:00:00 2001 From: Victoria Litvinova <73560279+vilit1@users.noreply.github.com> Date: Tue, 21 Jan 2025 12:10:02 -0800 Subject: [PATCH] chore: remove iot hub root authority commands (#730) --- HISTORY.rst | 6 +- azext_iot/iothub/_help.py | 30 ------ azext_iot/iothub/command_map.py | 6 -- azext_iot/iothub/commands_certificate.py | 42 -------- azext_iot/iothub/common.py | 8 -- azext_iot/iothub/params.py | 9 -- azext_iot/iothub/providers/certificate.py | 102 ------------------ .../tests/iothub/certificate/__init__.py | 5 - ...t_iothub_certificate_root_authority_int.py | 49 --------- 9 files changed, 5 insertions(+), 252 deletions(-) delete mode 100644 azext_iot/iothub/commands_certificate.py delete mode 100644 azext_iot/iothub/providers/certificate.py delete mode 100644 azext_iot/tests/iothub/certificate/__init__.py delete mode 100644 azext_iot/tests/iothub/certificate/test_iothub_certificate_root_authority_int.py diff --git a/HISTORY.rst b/HISTORY.rst index bf9685db8..983afb471 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -9,7 +9,7 @@ Release History **General updates** * We have dropped support for Python 3.8 -* This extension now supports Python 3.12 as the CLI core is packaging newer releases with this python version, +* This extension now supports Python 3.12 as the CLI core is packaging newer releases with this python version, * **[Breaking Change]** Older versions of `uamqp` (below `1.6.6`) are not compatible with Python 3.12 * If you update your packaged AZ CLI version (`2.66.0` or later) or otherwise change your environment's Python version to 3.12, you will need to update your `uamqp` dependency to `1.6.6` or above in order to use commands like `az iot hub monitor-events` * You can repair this dependency at command runtime by utilizing the `--repair` / `-r` argument in `az iot hub monitor-events` @@ -20,6 +20,10 @@ Release History * `ContentEncoding` system property is now `content-encoding` * `ContentType` system property is now `content-type` +**IoT Hub updates** + +* Removal of `az iot hub certificate root-authority`. For any issues, email iot-ca-updates@microsoft.com. + 0.25.0 +++++++++++++++ diff --git a/azext_iot/iothub/_help.py b/azext_iot/iothub/_help.py index b9db5553b..86960c41e 100644 --- a/azext_iot/iothub/_help.py +++ b/azext_iot/iothub/_help.py @@ -955,33 +955,3 @@ def load_iothub_help(): text: > az iot hub message-route fallback set -n {iothub_name} --enabled false """ - - helps["iot hub certificate root-authority"] = """ - type: group - short-summary: Manage the certificate root-authority for an IoT Hub instance. - """ - - helps["iot hub certificate root-authority set"] = """ - type: command - short-summary: Set the certificate root-authority for an IoT Hub instance to a specific version. - long-summary: Transition this resource to a certificate on the DigiCert Global G2 root (v2) or revert to Baltimore root (v1). - Before making this transition, please ensure all devices are updated to contain the public portion of the root - that the IoT Hub will be transitioned to. Devices will disconnect and reconnect using the new root. - We suggest monitoring current connections but an user defined metric may be more appropriate for your situation. - examples: - - name: Transition the target IoT Hub certificate root authority to Digicert. - text: > - az iot hub certificate root-authority set --hub-name {iothub_name} --certificate-authority v2 - - name: Revert the target IoT Hub certificate root authority to Baltimore. - text: > - az iot hub certificate root-authority set --hub-name {iothub_name} --certificate-authority v1 - """ - - helps["iot hub certificate root-authority show"] = """ - type: command - short-summary: Show the current certificate root-authority for an IoT Hub instance. - examples: - - name: Show the target IoT Hub certificate root authority. - text: > - az iot hub certificate root-authority show --hub-name {iothub_name} - """ diff --git a/azext_iot/iothub/command_map.py b/azext_iot/iothub/command_map.py index d81336bb1..caa53a612 100644 --- a/azext_iot/iothub/command_map.py +++ b/azext_iot/iothub/command_map.py @@ -180,9 +180,3 @@ def load_iothub_commands(self, _): "iot edge devices", command_type=device_identity_ops ) as cmd_group: cmd_group.command("create", "iot_edge_devices_create", is_experimental=True) - - with self.command_group( - "iot hub certificate root-authority", command_type=iothub_resource_ops, deprecate_info=self.deprecate() - ) as cmd_group: - cmd_group.show_command("show", "certificate_root_authority_show") - cmd_group.command("set", "certificate_root_authority_set") diff --git a/azext_iot/iothub/commands_certificate.py b/azext_iot/iothub/commands_certificate.py deleted file mode 100644 index 12a0c13fb..000000000 --- a/azext_iot/iothub/commands_certificate.py +++ /dev/null @@ -1,42 +0,0 @@ -# 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 typing import Optional -from azext_iot.iothub.providers.certificate import CertificateProvider -from knack.log import get_logger - -logger = get_logger(__name__) - - -def certificate_root_authority_show( - cmd, - hub_name: str, - resource_group_name: Optional[str] = None, -): - resource = CertificateProvider( - cmd=cmd, - hub_name=hub_name, - rg=resource_group_name, - ) - return resource.iot_hub_certificate_root_authority_show() - - -def certificate_root_authority_set( - cmd, - ca_version: str, - hub_name: str, - resource_group_name: Optional[str] = None, - yes: bool = False -): - resource = CertificateProvider( - cmd=cmd, - hub_name=hub_name, - rg=resource_group_name, - ) - return resource.iot_hub_certificate_root_authority_set( - ca_version=ca_version, - yes=yes - ) diff --git a/azext_iot/iothub/common.py b/azext_iot/iothub/common.py index 9b3aa4dd5..ce46b2d0b 100644 --- a/azext_iot/iothub/common.py +++ b/azext_iot/iothub/common.py @@ -187,14 +187,6 @@ def list_valid_types(cls): return list(filter(lambda d: d != RouteSourceType.Invalid.value, map(lambda c: c.value, cls))) -class CertificateAuthorityVersions(Enum): - """ - Certificate Authority Versions - """ - v2 = "v2" - v1 = "v1" - - class IoTHubSDKVersion(Enum): """ Types to determine which object properties the hub supports for backwards compatibility with the diff --git a/azext_iot/iothub/params.py b/azext_iot/iothub/params.py index 3c000c65f..52abb02bc 100644 --- a/azext_iot/iothub/params.py +++ b/azext_iot/iothub/params.py @@ -5,7 +5,6 @@ # -------------------------------------------------------------------------------------------- from azext_iot.iothub.providers.state import HubAspects -from azext_iot.iothub.common import CertificateAuthorityVersions from azure.cli.core.commands.parameters import get_enum_type, get_three_state_flag from azext_iot.common.shared import DeviceAuthType, SettleType, ProtocolType, AckType from azext_iot.assets.user_messages import info_param_properties_device @@ -658,11 +657,3 @@ def load_iothub_arguments(self, _): options_list=["--system-properties", "--sp"], help="System properties of the route message.", ) - - with self.argument_context("iot hub certificate root-authority set") as context: - context.argument( - "ca_version", - options_list=["--certificate-authority", "--cav"], - help="Certificate Root Authority version. The v1 represents Baltimore CA and v2 represents Digicert CA.", - arg_type=get_enum_type(CertificateAuthorityVersions), - ) diff --git a/azext_iot/iothub/providers/certificate.py b/azext_iot/iothub/providers/certificate.py deleted file mode 100644 index 167b0bc80..000000000 --- a/azext_iot/iothub/providers/certificate.py +++ /dev/null @@ -1,102 +0,0 @@ -# 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 json -from typing import Dict, Optional -from azext_iot.common.embedded_cli import EmbeddedCLI -from azext_iot.digitaltwins.common import ABORT_MSG -from azext_iot.iothub.common import ( - CA_REVERT_WARNING, - CA_TRANSITION_API_VERSION, - CA_TRANSITION_WARNING, - CONT_INPUT_MSG, - DEFAULT_ROOT_AUTHORITY, - HUB_PROVIDER, - NO_CHANGE_MSG, - CertificateAuthorityVersions -) -from azext_iot.iothub.providers.base import IoTHubProvider -from azure.cli.core.azclierror import ManualInterrupt -from knack.log import get_logger -from knack.prompting import prompt_y_n - - -logger = get_logger(__name__) - - -class CertificateProvider(IoTHubProvider): - def __init__( - self, - cmd, - hub_name: str, - rg: Optional[str] = None, - ): - super(CertificateProvider, self).__init__( - cmd=cmd, hub_name=hub_name, rg=rg - ) - self.cli = EmbeddedCLI() - if self.target.get("resourcegroup") is None: - resource = self.discovery.find_resource(hub_name) - self.target["resourcegroup"] = resource.additional_properties.get("resourcegroup") - - def iot_hub_certificate_root_authority_show(self) -> Optional[Dict[str, str]]: - # Since a newly created IoT Hub has empty rootCertificate property - return self._get_target_properties().get("rootCertificate") or DEFAULT_ROOT_AUTHORITY - - def iot_hub_certificate_root_authority_set( - self, - ca_version: str, - yes: bool = False - ) -> Optional[Dict[str, str]]: - properties = self._get_target_properties() - current_target = properties.get("rootCertificate") - root_ca = current_target and current_target.get("enableRootCertificateV2") - - # Check if changes are needed - if ca_version == CertificateAuthorityVersions.v1.value and root_ca: - logger.warning(CA_REVERT_WARNING) - if not yes and not prompt_y_n(msg=CONT_INPUT_MSG, default="n"): - raise ManualInterrupt(ABORT_MSG) - elif ca_version == CertificateAuthorityVersions.v2.value and not root_ca: - logger.warning(CA_TRANSITION_WARNING) - if not yes and not prompt_y_n(msg=CONT_INPUT_MSG, default="n"): - raise ManualInterrupt(ABORT_MSG) - else: - logger.warning(NO_CHANGE_MSG.format(ca_version)) - return - - command = "resource update -n {} -g {} --api-version {} --resource-type {}".format( - self.target["name"], - self.target["resourcegroup"], - CA_TRANSITION_API_VERSION, - HUB_PROVIDER - ) - - if root_ca is None: - properties["rootCertificate"] = {"enableRootCertificateV2": not root_ca} - dumped = json.dumps(properties).replace('"', '\\"') - command += f" --set properties=\"{dumped}\"" - else: - command += f" --set properties.rootCertificate.enableRootCertificateV2={not root_ca}" - - result = self.cli.invoke(command) - if not result.success(): - return - return result.as_json()["properties"].get("rootCertificate") - - def _get_target_properties(self) -> Optional[Dict[str, str]]: - result = self.cli.invoke( - "resource show -n {} -g {} --api-version {} --resource-type {}".format( - self.target["name"], - self.target['resourcegroup'], - CA_TRANSITION_API_VERSION, - HUB_PROVIDER - ) - ) - if not result.success(): - # Error will already be printed out - return - return result.as_json()["properties"] diff --git a/azext_iot/tests/iothub/certificate/__init__.py b/azext_iot/tests/iothub/certificate/__init__.py deleted file mode 100644 index 55614acbf..000000000 --- a/azext_iot/tests/iothub/certificate/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# 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. -# -------------------------------------------------------------------------------------------- diff --git a/azext_iot/tests/iothub/certificate/test_iothub_certificate_root_authority_int.py b/azext_iot/tests/iothub/certificate/test_iothub_certificate_root_authority_int.py deleted file mode 100644 index cf8794d3a..000000000 --- a/azext_iot/tests/iothub/certificate/test_iothub_certificate_root_authority_int.py +++ /dev/null @@ -1,49 +0,0 @@ -# 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 azext_iot.tests.iothub import IoTLiveScenarioTest - - -class TestIotHubCertificateRoot(IoTLiveScenarioTest): - def __init__(self, test_case): - super(TestIotHubCertificateRoot, self).__init__(test_case, add_data_contributor=False) - - def test_certificate_root(self): - initial_state = self.cmd( - f"iot hub certificate root-authority show -n {self.entity_name} -g {self.entity_rg}", - ).get_output_in_json()["enableRootCertificateV2"] - - # transition 1 - self.cmd( - f"iot hub certificate root-authority set -n {self.entity_name} -g {self.entity_rg} --cav " - f"{'v1' if initial_state else 'v2'} --yes", - checks=[ - self.check("enableRootCertificateV2", not initial_state), - ], - ) - - self.cmd( - f"iot hub certificate root-authority show -n {self.entity_name} -g {self.entity_rg}", - checks=[ - self.check("enableRootCertificateV2", not initial_state), - ], - ) - - # transition 2 - self.cmd( - f"iot hub certificate root-authority set -n {self.entity_name} -g {self.entity_rg} --cav " - f"{'v2' if initial_state else 'v1'} --yes", - checks=[ - self.check("enableRootCertificateV2", initial_state), - ], - ) - - self.cmd( - f"iot hub certificate root-authority show -n {self.entity_name} -g {self.entity_rg}", - checks=[ - self.check("enableRootCertificateV2", initial_state), - ], - )