Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bot Service] BREAKING CHANGE: az bot create change: Remove --kind, --password, --lang arguments. Add --app-type, --tenant-id, --msi-resource-id arguments #22902

Merged
merged 32 commits into from
Jun 28, 2022
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
da53d7a
remove two deprecated kinds 'webapp' 'registration', and add 'azurebo…
jiaxuwu2021 May 7, 2022
560cab2
fix test case
chinazhangchao Jun 10, 2022
f1476e9
Merge branch 'dev' into jiaxuwu/clibotcreateazurebot
chinazhangchao Jun 10, 2022
f4fb67b
Merge branch 'jiaxuwu/clibotcreateazurebot' into chao/clibotcreate
chinazhangchao Jun 10, 2022
34dc78c
add app_type param, upgrade azure-mgmt-botservice
chinazhangchao Jun 14, 2022
7e212fb
Merge branch 'dev' into chao/clibotcreate
chinazhangchao Jun 14, 2022
fafca0d
add param
chinazhangchao Jun 15, 2022
217803e
Merge branch 'dev' into chao/clibotcreate
chinazhangchao Jun 17, 2022
c54a44f
fix test case
chinazhangchao Jun 17, 2022
67091e9
fix test error
chinazhangchao Jun 17, 2022
39798b5
fix test case
chinazhangchao Jun 17, 2022
f4de72b
fix test case
chinazhangchao Jun 20, 2022
6dc39d4
Merge branch 'dev' of https://github.com/Azure/azure-cli into chao/cl…
chinazhangchao Jun 20, 2022
e29ce63
fix test case
chinazhangchao Jun 20, 2022
954afd3
fix test case
chinazhangchao Jun 20, 2022
e05d898
fix test case
chinazhangchao Jun 20, 2022
f971fab
fix test case
chinazhangchao Jun 21, 2022
371c07b
Merge branch 'dev' of https://github.com/Azure/azure-cli into chao/cl…
chinazhangchao Jun 21, 2022
e574433
fix
chinazhangchao Jun 21, 2022
64c1bdc
fix tests. update recoding
fangyangci Jun 22, 2022
ab8e772
update recording
chinazhangchao Jun 24, 2022
0d8bcd0
update recording
chinazhangchao Jun 24, 2022
e0dad96
Merge branch 'dev' of https://github.com/Azure/azure-cli into chao/cl…
chinazhangchao Jun 24, 2022
581c316
fix errorexception
chinazhangchao Jun 24, 2022
7355aee
Merge branch 'dev' of https://github.com/Azure/azure-cli into chao/cl…
chinazhangchao Jun 24, 2022
d3dc2ae
update recording
chinazhangchao Jun 24, 2022
a73ac49
add bot type test
chinazhangchao Jun 27, 2022
8fd5ff6
Merge branch 'dev' of https://github.com/Azure/azure-cli into chao/cl…
chinazhangchao Jun 27, 2022
f00d005
change azure-mgmt-botservice version
chinazhangchao Jun 27, 2022
83f9e15
use new error types
chinazhangchao Jun 27, 2022
637fdd8
change import
chinazhangchao Jun 27, 2022
0117a2c
format
chinazhangchao Jun 27, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@


def bot_exception_handler(ex):
from azure.mgmt.botservice.models import ErrorException
from azure.core.exceptions import HttpResponseError
from msrestazure.azure_exceptions import CloudError
from msrest.exceptions import ClientRequestError # pylint: disable=import-error
if isinstance(ex, ErrorException):
if isinstance(ex, HttpResponseError):
message = 'An error occurred. {0}: {1}'.format(
ex.error.error.code,
ex.error.error.message
ex.error.code,
ex.error.message
)
raise CLIError(message)
chinazhangchao marked this conversation as resolved.
Show resolved Hide resolved
if isinstance(ex, CloudError) and ex.status_code == 404:
Expand Down
8 changes: 3 additions & 5 deletions src/azure-cli/azure/cli/command_modules/botservice/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

# supported_languages will be use with get_enum_type after the 'Node' value is completely removed from `az bot`
# In custom.py we're still supporting 'Node' in __language_validator()
SUPPORTED_LANGUAGES = ['Csharp', 'Javascript']
UPCOMING_LANGUAGES = ['Csharp', 'Javascript', 'Typescript']
SUPPORTED_APP_INSIGHTS_REGIONS = [
'Australia East',
Expand Down Expand Up @@ -55,15 +54,14 @@ def load_arguments(self, _):

with self.argument_context('bot create') as c:
c.argument('sku_name', options_list=['--sku'], arg_type=get_enum_type(SUPPORTED_SKUS), help='The Sku of the bot.', arg_group='Registration Bot Specific')
c.argument('kind', options_list=['--kind', '-k'], arg_type=get_enum_type(['registration', 'webapp']), help='The kind of the bot.')
c.argument('display_name', help='The display name of the bot. If not specified, defaults to the name of the bot.', arg_group='Registration Bot Specific')
c.argument('description', options_list=['--description', '-d'], help='The description of the bot.', arg_group='Registration Bot Specific')
c.argument('endpoint', options_list=['-e', '--endpoint'], help='The messaging endpoint of the bot.', arg_group='Registration Bot Specific')
c.argument('msa_app_id', options_list=['--appid'], help='The Microsoft account ID (MSA ID) to be used with the bot.')
c.argument('password', options_list=['-p', '--password'], help='The Microsoft account (MSA) password for the bot. Used to authorize messages being sent from the bot. Required when "--kind" is "webapp".', arg_group='Web App Bot Specific')
c.argument('msa_app_type', options_list=['--app-type'], help='Microsoft App Type for the bot. Possible values include: "UserAssignedMSI", "SingleTenant", "MultiTenant".')
c.argument('msa_app_tenant_id', options_list=['--tenant-id'], help='Microsoft App Tenant Id for the bot.')
c.argument('msa_app_msi_resource_id', options_list=['--msi-resource-id'], help='Microsoft App Managed Identity Resource Id for the bot.')
c.argument('tags', arg_type=tags_type)
c.argument('language', options_list=['--lang'], arg_type=get_enum_type(SUPPORTED_LANGUAGES), help='The language to be used to create the bot.', arg_group='Web App Bot Specific')
c.argument('deploy_echo', options_list=['--echo'], arg_type=get_three_state_flag(), help='Deploy an Echo Bot template to the newly created v4 Web App Bot.', arg_group='V4 Bot Templates')
c.argument('cmek_key_vault_url', options_list=['--cmk-key-vault-key-url', '--cmk'], help='The key vault key url to enable Customer Managed Keys encryption')

with self.argument_context('bot publish') as c:
Expand Down

This file was deleted.

117 changes: 41 additions & 76 deletions src/azure-cli/azure/cli/command_modules/botservice/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from azure.cli.core.azclierror import MutuallyExclusiveArgumentError
from azure.cli.command_modules.botservice.bot_json_formatter import BotJsonFormatter
from azure.cli.command_modules.botservice.bot_publish_prep import BotPublishPrep
from azure.cli.command_modules.botservice.bot_template_deployer import BotTemplateDeployer
from azure.cli.command_modules.botservice.constants import CSHARP, JAVASCRIPT, TYPESCRIPT
from azure.cli.command_modules.botservice.kudu_client import KuduClient
from azure.cli.command_modules.botservice.name_availability import NameAvailability
Expand All @@ -22,21 +21,15 @@
ConnectionSetting,
ConnectionSettingProperties,
ConnectionSettingParameter,
ErrorException,
Sku)
from azure.core.exceptions import HttpResponseError

from knack.util import CLIError
from knack.log import get_logger

logger = get_logger(__name__)


def __bot_template_validator(deploy_echo): # pylint: disable=inconsistent-return-statements
if deploy_echo:
return 'echo'
return None


def __prepare_configuration_file(cmd, resource_group_name, kudu_client, folder_path):
"""For bots without a bot file."""
# If no bot file exists, create the language specific configuration file from the bot's Application Settings
Expand Down Expand Up @@ -86,10 +79,10 @@ def __handle_failed_name_check(name_response, cmd, client, resource_group_name,
existing_bot = get_bot(cmd, client, resource_group_name, resource_name)
logger.warning('Provided bot name already exists in Resource Group. Returning bot information:')
return existing_bot
except ErrorException as e:
if e.error.error.code == 'ResourceNotFound':
code = e.error.error.code
message = e.error.error.message
except HttpResponseError as e:
if e.error.code == 'ResourceNotFound':
code = e.error.code
message = e.error.message

logger.debug('Bot "%s" not found in Resource Group "%s".\n Code: "%s"\n Message: '
'"%s"', resource_name, resource_group_name, code, message)
Expand All @@ -99,18 +92,11 @@ def __handle_failed_name_check(name_response, cmd, client, resource_group_name,
raise e


def create(cmd, client, resource_group_name, resource_name, kind, msa_app_id, password=None, language=None, # pylint: disable=too-many-locals, too-many-statements, inconsistent-return-statements
description=None, display_name=None, endpoint=None, tags=None, location='global',
sku_name='F0', deploy_echo=None, cmek_key_vault_url=None):
# Kind parameter validation
kind = kind.lower()
registration_kind = 'registration'
bot_kind = 'bot'
webapp_kind = 'webapp'

# Mapping: registration is deprecated, we now use 'bot' kind for registration bots
if kind == registration_kind:
kind = bot_kind
def create(cmd, client, resource_group_name, resource_name, msa_app_id, msa_app_type,
msa_app_tenant_id=None, msa_app_msi_resource_id=None, description=None, display_name=None,
endpoint=None, tags=None, location='global', sku_name='F0', cmek_key_vault_url=None):
# Kind only support azure bot for now
kind = "azurebot"

# Check the resource name availability for the bot.
name_response = NameAvailability.check_name_availability(client, resource_name, kind)
Expand Down Expand Up @@ -138,61 +124,40 @@ def create(cmd, client, resource_group_name, resource_name, kind, msa_app_id, pa

logger.info('Creating Azure Bot Service.')

# Registration bots: simply call ARM and create the bot
if kind == bot_kind:

logger.info('Detected kind %s, validating parameters for the specified kind.', kind)

# Registration bot specific validation
if not endpoint:
endpoint = ''

is_cmek_enabled = False
if cmek_key_vault_url is not None:
is_cmek_enabled = True

parameters = Bot(
location=location,
sku=Sku(name=sku_name),
kind=kind,
tags=tags,
properties=BotProperties(
display_name=display_name,
description=description,
endpoint=endpoint,
msa_app_id=msa_app_id,
is_cmek_enabled=is_cmek_enabled,
cmek_key_vault_url=cmek_key_vault_url
)
)
logger.info('Bot parameters client side validation successful.')
logger.info('Creating bot.')

return client.bots.create(
resource_group_name=resource_group_name,
resource_name=resource_name,
parameters=parameters
)

if not password:
raise CLIError("--password cannot have a length of 0 for Web App Bots. This value is used to authorize calls "
"to your bot. See 'az bot create --help'.")
# Registration bot specific validation
if not endpoint:
endpoint = ''

# Web app bots require deploying custom ARM templates, we do that in a separate method
logger.info('Detected kind %s, validating parameters for the specified kind.', kind)

if not language:
raise CLIError("You must pass in a language when creating a {0} bot. See 'az bot create --help'."
.format(webapp_kind))
language = language.lower()

bot_template_type = __bot_template_validator(deploy_echo)
is_cmek_enabled = False
if cmek_key_vault_url is not None:
is_cmek_enabled = True

creation_results = BotTemplateDeployer.create_app(
cmd, logger, client, resource_group_name, resource_name, description, kind, msa_app_id, password,
location, sku_name, language, bot_template_type, cmek_key_vault_url)
# Registration bots: simply call ARM and create the bot
parameters = Bot(
location=location,
sku=Sku(name=sku_name),
kind=kind,
tags=tags,
properties=BotProperties(
display_name=display_name,
description=description,
endpoint=endpoint,
msa_app_id=msa_app_id,
msa_app_type=msa_app_type,
msa_app_tenant_id=msa_app_tenant_id,
msa_app_msi_resource_id=msa_app_msi_resource_id,
is_cmek_enabled=is_cmek_enabled,
cmek_key_vault_url=cmek_key_vault_url
)
)
logger.info('Bot parameters client side validation successful.')
logger.info('Creating bot.')

return creation_results
return client.bots.create(
resource_group_name=resource_group_name,
resource_name=resource_name,
parameters=parameters
)


def get_bot(cmd, client, resource_group_name, resource_name, bot_json=None):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
from azure.mgmt.botservice.models import CheckNameAvailabilityRequestBody


class NameAvailability:
@staticmethod
def check_name_availability(client, resource_name, bot_type):
return client.bots.get_check_name_availability(resource_name, bot_type)
return client.bots.get_check_name_availability(
CheckNameAvailabilityRequestBody(name=resource_name, type=bot_type))

@staticmethod
def check_enterprise_channel_name_availability(client, channel_name):
Expand Down
Loading