Skip to content

Commit

Permalink
Support IotHub in the profile of 2019-03-01-hybrid
Browse files Browse the repository at this point in the history
  • Loading branch information
zhoxing-ms committed Mar 28, 2020
1 parent 957ef3d commit e71e9de
Show file tree
Hide file tree
Showing 19 changed files with 12,886 additions and 7,203 deletions.
8 changes: 5 additions & 3 deletions src/azure-cli-core/azure/cli/core/profiles/_shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class ResourceType(Enum): # pylint: disable=too-few-public-methods
DATA_KEYVAULT = ('azure.keyvault', 'KeyVaultClient')
MGMT_EVENTHUB = ('azure.mgmt.eventhub', 'EventHubManagementClient')
MGMT_APPSERVICE = ('azure.mgmt.web', 'WebSiteManagementClient')
MGMT_IOTHUB = ('azure.mgmt.iothub', 'IotHubClient')
# the "None" below will stay till a command module fills in the type so "get_mgmt_service_client"
# can be provided with "ResourceType.XXX" to initialize the client object. This usually happens
# when related commands start to support Multi-API
Expand All @@ -74,7 +75,6 @@ class ResourceType(Enum): # pylint: disable=too-few-public-methods
MGMT_DATALAKE_STORE = ('azure.mgmt.datalake.store', None)
MGMT_DATAMIGRATION = ('azure.mgmt.datamigration', None)
MGMT_EVENTGRID = ('azure.mgmt.eventgrid', None)
MGMT_IOT = ('azure.mgmt.iothub', None)
MGMT_IOTCENTRAL = ('azure.mgmt.iotcentral', None)
MGMT_DEVTESTLABS = ('azure.mgmt.devtestlabs', None)
MGMT_MAPS = ('azure.mgmt.maps', None)
Expand Down Expand Up @@ -176,7 +176,8 @@ def default_api_version(self):
'tenant_activity_logs': '2015-04-01',
'vm_insights': '2018-11-27-preview'
}),
ResourceType.MGMT_APPSERVICE: '2019-08-01'
ResourceType.MGMT_APPSERVICE: '2019-08-01',
ResourceType.MGMT_IOTHUB: '2019-07-01-preview'
},
'2019-03-01-hybrid': {
ResourceType.MGMT_STORAGE: '2017-10-01',
Expand Down Expand Up @@ -205,7 +206,8 @@ def default_api_version(self):
# to have commands show up in the hybrid profile which happens to have the latest
# API versions
ResourceType.MGMT_APPSERVICE: '2018-02-01',
ResourceType.MGMT_EVENTHUB: '2017-04-01'
ResourceType.MGMT_EVENTHUB: '2017-04-01',
ResourceType.MGMT_IOTHUB: '2019-03-22'
},
'2018-03-01-hybrid': {
ResourceType.MGMT_STORAGE: '2016-01-01',
Expand Down
2 changes: 1 addition & 1 deletion src/azure-cli/azure/cli/command_modules/iot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def __init__(self, cli_ctx=None):
cli_ctx.register_event(EVENT_INVOKER_POST_PARSE_ARGS, handler)
super(IoTCommandsLoader, self).__init__(cli_ctx=cli_ctx,
custom_command_type=iot_custom,
resource_type=ResourceType.MGMT_IOT)
resource_type=ResourceType.MGMT_IOTHUB)

def load_command_table(self, args):
from azure.cli.command_modules.iot.commands import load_command_table
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

def iot_hub_service_factory(cli_ctx, *_):
from azure.cli.core.commands.client_factory import get_mgmt_service_client
from azure.mgmt.iothub.iot_hub_client import IotHubClient
return get_mgmt_service_client(cli_ctx, IotHubClient)
from azure.cli.core.profiles import ResourceType
return get_mgmt_service_client(cli_ctx, ResourceType.MGMT_IOTHUB)


def resource_service_factory(cli_ctx, **_):
Expand Down
7 changes: 4 additions & 3 deletions src/azure-cli/azure/cli/command_modules/iot/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from ._client_factory import iot_service_provisioning_factory
from ._client_factory import iot_pnp_service_factory


JOB_DEPRECATION_INFO = 'IoT Extension (azure-cli-iot-ext) Job commands'


Expand Down Expand Up @@ -138,7 +137,8 @@ def load_command_table(self, _): # pylint: disable=too-many-statements
transform=EndpointUpdateResultTransform(self.cli_ctx))

# iot hub message enrichment commands
with self.command_group('iot hub message-enrichment', client_factory=iot_hub_service_factory) as g:
with self.command_group('iot hub message-enrichment', client_factory=iot_hub_service_factory,
min_api="2019-07-01-preview") as g:
g.custom_command('create', 'iot_message_enrichment_create')
g.custom_command('list', 'iot_message_enrichment_list')
g.custom_command('delete', 'iot_message_enrichment_delete')
Expand All @@ -154,7 +154,8 @@ def load_command_table(self, _): # pylint: disable=too-many-statements
g.custom_command('test', 'iot_hub_route_test')

# iot hub device stream commands
with self.command_group('iot hub devicestream', client_factory=iot_hub_service_factory) as g:
with self.command_group('iot hub devicestream', client_factory=iot_hub_service_factory,
min_api="2019-07-01-preview") as g:
g.custom_command('show', 'iot_hub_devicestream_show')

# iot pnp commands
Expand Down
3 changes: 1 addition & 2 deletions src/azure-cli/azure/cli/command_modules/iot/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -891,8 +891,7 @@ def iot_hub_devicestream_show(cmd, client, hub_name, resource_group_name=None):
def iot_hub_manual_failover(cmd, client, hub_name, resource_group_name=None, no_wait=False):
hub = iot_hub_get(cmd, client, hub_name, resource_group_name)
resource_group_name = hub.additional_properties['resourcegroup']
failover_region = next(x['location'] for x in hub.properties.additional_properties['locations']
if x['role'].lower() == 'secondary')
failover_region = next(x.location for x in hub.properties.locations if x.role.lower() == 'secondary')
if no_wait:
return client.iot_hub.manual_failover(hub_name, resource_group_name, failover_region)
LongRunningOperation(cmd.cli_ctx)(client.iot_hub.manual_failover(hub_name, resource_group_name, failover_region))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from os.path import exists
import os
from OpenSSL import crypto


def _create_test_cert(cert_file, key_file, subject, valid_days, serial_number):
# create a key pair
k = crypto.PKey()
k.generate_key(crypto.TYPE_RSA, 2046)

# create a self-signed cert with some basic constraints
cert = crypto.X509()
cert.get_subject().CN = subject
cert.gmtime_adj_notBefore(-1 * 24 * 60 * 60)
cert.gmtime_adj_notAfter(valid_days * 24 * 60 * 60)
cert.set_version(2)
cert.set_serial_number(serial_number)
cert.add_extensions([
crypto.X509Extension(b"basicConstraints", True, b"CA:TRUE, pathlen:1"),
crypto.X509Extension(b"subjectKeyIdentifier", False, b"hash",
subject=cert),
])
cert.add_extensions([
crypto.X509Extension(b"authorityKeyIdentifier", False, b"keyid:always",
issuer=cert)
])
cert.set_issuer(cert.get_subject())
cert.set_pubkey(k)
cert.sign(k, 'sha256')

cert_str = crypto.dump_certificate(crypto.FILETYPE_PEM, cert).decode('ascii')
key_str = crypto.dump_privatekey(crypto.FILETYPE_PEM, k).decode('ascii')

open(cert_file, 'w').write(cert_str)
open(key_file, 'w').write(key_str)


def _delete_test_cert(cert_file, key_file, verification_file):
if exists(cert_file) and exists(key_file):
os.remove(cert_file)
os.remove(key_file)

if exists(verification_file):
os.remove(verification_file)


def _create_verification_cert(cert_file, key_file, verification_file, nonce, valid_days, serial_number):
if exists(cert_file) and exists(key_file):
# create a key pair
public_key = crypto.PKey()
public_key.generate_key(crypto.TYPE_RSA, 2046)

# open the root cert and key
signing_cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(cert_file).read())
k = crypto.load_privatekey(crypto.FILETYPE_PEM, open(key_file).read())

# create a cert signed by the root
verification_cert = crypto.X509()
verification_cert.get_subject().CN = nonce
verification_cert.gmtime_adj_notBefore(-1 * 24 * 60 * 60)
verification_cert.gmtime_adj_notAfter(valid_days * 24 * 60 * 60)
verification_cert.set_version(2)
verification_cert.set_serial_number(serial_number)

verification_cert.set_pubkey(public_key)
verification_cert.set_issuer(signing_cert.get_subject())
verification_cert.add_extensions([
crypto.X509Extension(b"authorityKeyIdentifier", False, b"keyid:always",
issuer=signing_cert)
])
verification_cert.sign(k, 'sha256')

verification_cert_str = crypto.dump_certificate(crypto.FILETYPE_PEM, verification_cert).decode('ascii')

open(verification_file, 'w').write(verification_cert_str)
Loading

0 comments on commit e71e9de

Please sign in to comment.