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

[ServiceConnector] az webapp/spring-cloud connection: New command group to support service to service connection #19834

Merged
merged 20 commits into from Oct 19, 2021

Conversation

houk-ms
Copy link
Contributor

@houk-ms houk-ms commented Oct 11, 2021

Description

This PR implements Azure ServiceConnector as command group az {source} connection.

Currently, the supported {source} are

  • webapp
  • spring-cloud

The supported target resources are

  • appconfig
  • cosmos-cassandra
  • cosmos-gremlin
  • cosmos-mongo
  • cosmos-sql
  • cosmos-table
  • eventhub
  • keyvault
  • mysql
  • mysql-flexible
  • postgres
  • postgres-flexibl
  • servicebus
  • sql
  • storage-blob
  • storage-file
  • storage-queue
  • storage-table

In the future, more compute services and target resources may be added.

Note. As az {source} connection is released as CLI core module, so for {source} which are in CLI extension (e.g, spring-cloud), we only load az {source} connection when {source} is installed.

Command Interface

Use az webapp connection as an example, as az spring-cloud connection is similar.

// `webapp connection` command group

Group
    az webapp connection : Manage webapp connections.

Subgroups:
    create             : Create a connection between a webapp and a target resource.
    update             : Update a webapp connection.

Commands:
    delete             : Delete a webapp connection.
    list               : List connections of a webapp.
    list-configuration : List source configurations of a webapp connection.
    list-support-types : List target resource types and auth types supported by webapp connections.
    show               : Get the details of a webapp connection.
    validate           : Validate a webapp connection.
    wait               : Place the CLI in a waiting state until a condition of the connection is
                         met.
// `webapp connection create` command group, `update` is similar

Group
    az webapp connection create : Create a connection between a webapp and a target resource.

Commands:
    appconfig         : Create a webapp connection to appconfig.
    cosmos-cassandra  : Create a webapp connection to cosmos-cassandra.
    cosmos-gremlin    : Create a webapp connection to cosmos-gremlin.
    cosmos-mongo      : Create a webapp connection to cosmos-mongo.
    cosmos-sql        : Create a webapp connection to cosmos-sql.
    cosmos-table      : Create a webapp connection to cosmos-table.
    eventhub          : Create a webapp connection to eventhub.
    keyvault          : Create a webapp connection to keyvault.
    mysql             : Create a webapp connection to mysql.
    mysql-flexible    : Create a webapp connection to mysql-flexible.
    postgres          : Create a webapp connection to postgres.
    postgres-flexible : Create a webapp connection to postgres-flexible.
    servicebus        : Create a webapp connection to servicebus.
    sql               : Create a webapp connection to sql.
    storage-blob      : Create a webapp connection to storage-blob.
    storage-file      : Create a webapp connection to storage-file.
    storage-queue     : Create a webapp connection to storage-queue.
    storage-table     : Create a webapp connection to storage-table.
// command `webapp connection list-support-types`

Command
    az webapp connection list-support-types : List target resource types and auth types supported by
    webapp connections.

Arguments
    --target-type -t   : The target resource type.  Allowed values: appconfig, cosmos-cassandra,
                         cosmos-gremlin, cosmos-mongo, cosmos-sql, cosmos-table, eventhub, keyvault,
                         mysql, mysql-flexible, postgres, postgres-flexible, servicebus, sql,
                         storage-blob, storage-file, storage-queue, storage-table.

Examples
    List all webapp supported target resource types and auth types
        az webapp connection list-support-types -o table

    List webapp supported auth types for a specific target resource type
        az webapp connection list list-support-types --target-type storage-blob -o table
// command `webapp connection list`

Command
    az webapp connection list : List connections of a webapp.

Arguments
    --source-id                     : The resource id of a webapp. Required if ['--source-resource-
                                      group', '--webapp'] are not specified.
    --source-resource-group -sg     : The resource group which contains the webapp. Required if '--
                                      source-id' is not specified.
    --webapp                        : Name of the webapp. Required if '--source-id' is not
                                      specified.

Examples
    List webapp connections interactively
        az webapp connection list

    List webapp connections by source resource id
        az webapp connection list --source-id /subscriptions/{subscription}/resourceGroups/
       {source_resource_group}/providers/Microsoft.Web/sites/{site}
// command `webapp connection validate`, `delete`, `list-configuration`, `show` are similar

Command
    az webapp connection validate : Validate a webapp connection.

Arguments
    --connection-name --name -n : Name of the webapp connection.
    --id                        : The resource id of the connection. ['--source-resource-group', '--
                                  webapp', '--connection-name'] are required if '--id' is not       
                                  specified.
    --source-resource-group -sg : The resource group which contains the webapp. Required if '--     
                                  source-id' is not specified.
    --webapp                    : Name of the webapp. Required if '--source-id' is not specified.

Examples
    Validate a connection interactively
        az webapp connection validate

    Validate a connection by connection id
        az webapp connection validate --id /subscriptions/{subscription}/resourceGroups/{source_reso
        urce_group}/providers/Microsoft.Web/sites/{site}/providers/Microsoft.ServiceLinker/linkers/{
        linker}
// command `webapp connection create {target}` 

Command
    az webapp connection create storage-blob : Create a webapp connection to storage-blob.

Arguments
    --account-name -a           : Name of the storage account. Required if '--target-id' is not
                                  specified.
    --client-type               : The client type used on the webapp.  Allowed values: dotnet, java,
                                  nodejs, python, springBoot.
    --connection-name --name -n : Name of the webapp connection.
    --new                       : Indicates whether to create a new storage-blob when creating the
                                  webapp connection.  Allowed values: false, true.
    --no-wait                   : Do not wait for the long-running operation to finish.
    --source-id                 : The resource id of a webapp. Required if ['--source-resource-
                                  group', '--webapp'] are not specified.
    --source-resource-group -sg : The resource group which contains the webapp. Required if '--
                                  source-id' is not specified.
    --target-id                 : The resource id of target service. Required if ['--target-
                                  resource-group', '--account-name'] are not specified.
    --target-resource-group -tg : The resource group which contains the storage account. Required if
                                  '--target-id' is not specified.
    --webapp                    : Name of the webapp. Required if '--source-id' is not specified.

AuthType Arguments
    --secret                    : The secret auth info, no need to provide additional info.
        Usage: --secret.
    --service-principal         : The service principal auth info.
        Usage: --service-principal client-id=XX object-id=XX secret=XX

        client-id      : Required. Client id of the service principal.
        object-id      : Required. Object id of the service principal.
        secret         : Required. Secret of the service principal.
    --system-identity           : The system assigned identity auth info.
        Usage: --system-identity.
    --user-identity             : The user assigned identity auth info.
        Usage: --user-identity client-id=XX subs-id=XX

        client-id      : Required. Client id of the user assigned identity.
        subs-id        : Required. Subscription id of the user assigned identity.

Examples
    Create a connection between webapp and storage-blob interactively
        az webapp connection create storage-blob

    Create a connection between webapp and storage-blob
        az webapp connection create storage-blob --name MyConn --client-type python --source-id /sub
        scriptions/{subscription}/resourceGroups/{source_resource_group}/providers/Microsoft.Web/sit
        es/{site} --target-id /subscriptions/{subscription}/resourceGroups/{target_resource_group}/p
        roviders/Microsoft.Storage/storageAccounts/{account}/blobServices/default --system-identity

    Create a new storage-blob and connect webapp to it interactively
        az webapp connection create storage-blob --new

    Create a new storage-blob and connect webapp to it
        az webapp connection create storage-blob --source-id /subscriptions/{subscription}/resourceG
        roups/{source_resource_group}/providers/Microsoft.Web/sites/{site} --new

This checklist is used to make sure that common guidelines for a pull request are followed.

@yonzhan
Copy link
Collaborator

yonzhan commented Oct 11, 2021

ServiceConnector

AUTH_TYPE.Secret: '--secret name=XX secret=XX',
AUTH_TYPE.SecretAuto: '--secret',
AUTH_TYPE.SystemIdentity: '--system-identity',
AUTH_TYPE.ServicePrincipalSecret: '--service-principal client-id=XX object-id=XX secret=XX',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we support serviceprincipal certificate in CLI?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why need both client id and object id? I mean can we get one from another?

Copy link
Contributor Author

@houk-ms houk-ms Oct 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why need both client id and object id? I mean can we get one from another?

Yes, tenant_id + client_id could result in a unique object_id. If we provide only client_id, we have to use default tenant, which would sacrifice the cross-tenant ability.

So, i prefer we leave both of them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we support serviceprincipal certificate in CLI?

Not now, we may support this if there's customer ask in the future.

from ._utils import run_cli_cmd

def _infer_webapp(source_id):
value_type_map = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are they case sensitive?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they are converted to lower cases when comparing.


all_auth_info = []
if secret_auth_info is not None:
all_auth_info.append(secret_auth_info)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happens if user input has more than one auth_info

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will check it, and an error will be throwed if there are mutiple auth info provided

'and then create the connection. Error details: {}'.format(str(err)))

target_id = self.get_target_id()
logger.warning('Created, the resource id is: %s', target_id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls help to make the message specific clear, <target_resource_type> is created

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this log, another log called Start creating a <target resource> will be print, so i think it's clear enough here

try:
run_cli_cmd(cmd)
except CLIInternalError:
logger.warning('Rollback failed, please manually check and delete the unintended resources '
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with resource id?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure

def _retrive_source_rg(self):
'''Retrive the resource group name in source resource id
'''
regex = '.*/resourceGroups/([^/]*)'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls use the common lib in msrest.azure to parse resource id

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point

AUTH_TYPE.Secret: '--secret name=XX secret=XX',
AUTH_TYPE.SecretAuto: '--secret',
AUTH_TYPE.SystemIdentity: '--system-identity',
AUTH_TYPE.ServicePrincipalSecret: '--service-principal client-id=XX object-id=XX secret=XX',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why need both client id and object id? I mean can we get one from another?

Go = 'go'
Php = 'php'
Ruby = 'ruby'
SpringBoot = 'springBoot'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what's the convention? all small case or camel?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These values are defined in swagger, i think they are camel

def _infer_springcloud(source_id):
client_type = None
try:
regex = '*/resourceGroups/([^/]*)/providers/Microsoft.AppPlatform/Spring/([^/]*)/apps/([^/]*)/*'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pls use the common lib, avoid regex :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure~

@kairu-ms
Copy link
Contributor

@houk-ms Do you need to update CODEOWNERS file?

@houk-ms
Copy link
Contributor Author

houk-ms commented Oct 15, 2021

@houk-ms Do you need to update CODEOWNERS file?

Thanks for reminding, we will add it

@kairu-ms kairu-ms merged commit b0a11d6 into Azure:dev Oct 19, 2021
@houk-ms houk-ms deleted the service-linker branch October 20, 2021 02:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants