Hello community, here is the log from the commit of package azure-cli-resource for openSUSE:Factory checked in at 2019-10-31 18:17:11 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/azure-cli-resource (Old) and /work/SRC/openSUSE:Factory/.azure-cli-resource.new.2990 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "azure-cli-resource" Thu Oct 31 18:17:11 2019 rev:7 rq:742718 version:2.1.16 Changes: -------- --- /work/SRC/openSUSE:Factory/azure-cli-resource/azure-cli-resource.changes 2019-06-05 11:44:58.887013627 +0200 +++ /work/SRC/openSUSE:Factory/.azure-cli-resource.new.2990/azure-cli-resource.changes 2019-10-31 18:17:11.994131298 +0100 @@ -1,0 +2,8 @@ +Thu Oct 24 12:11:54 UTC 2019 - John Paul Adrian Glaubitz <[email protected]> + +- New upstream release + + Version 2.1.16 + + For detailed information about changes see the + HISTORY.txt file provided with this package + +------------------------------------------------------------------- Old: ---- azure-cli-resource-2.1.10.tar.gz New: ---- azure-cli-resource-2.1.16.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ azure-cli-resource.spec ++++++ --- /var/tmp/diff_new_pack.rITT3t/_old 2019-10-31 18:17:13.206132552 +0100 +++ /var/tmp/diff_new_pack.rITT3t/_new 2019-10-31 18:17:13.222132569 +0100 @@ -17,7 +17,7 @@ Name: azure-cli-resource -Version: 2.1.10 +Version: 2.1.16 Release: 0 Summary: Microsoft Azure CLI 'resource' Command Module License: MIT ++++++ azure-cli-resource-2.1.10.tar.gz -> azure-cli-resource-2.1.16.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-resource-2.1.10/HISTORY.rst new/azure-cli-resource-2.1.16/HISTORY.rst --- old/azure-cli-resource-2.1.10/HISTORY.rst 2019-02-12 03:05:13.000000000 +0100 +++ new/azure-cli-resource-2.1.16/HISTORY.rst 2019-06-13 23:17:47.000000000 +0200 @@ -2,9 +2,43 @@ Release History =============== + +2.1.16 +++++++ +* 'az rest': new command for making REST calls +* `policy assignment list`: Fix error when using a resource group or subscription level `--scope`. + +2.1.15 +++++++ +* `deployment create`: Improve error message when there is no TTY available + +2.1.14 +++++++ +* `resource link`: Deprecate `--link-id`, `--target-id` and `--filter-string` in favor of + `--link`, `--target`, and `--filter` respectively. +* `resource link create/update`: Fix issue where these commands would not work. +* `resource delete`: Fix issue where deleting using a resource ID could crash on error. + +2.1.13 +++++++ +* `deployment create`/`group deployment create`: Fixed issue where parameters file with an empty set of parameters would not work. + +2.1.12 +++++++ +* `deployment create/list/show`: improve table output +* `deployment create/validate`: fix issue where type secureObject was not recognized. + +2.1.11 +++++++ +* `deployment create`: Fix issue where type field was case-sensitive. +* `policy assignment create`: support uri based parameters file +* `policy set-definition update`: support uri based parameters and definitions files +* `policy definition update`: fix handling of parameters and rules files +* `resource show/update/delete/tag/invoke-action`: Fix issue where cross-subscription IDs did not properly honor the subscription ID. + 2.1.10 ++++++ -* Minor fixes +* Minor fixes. 2.1.9 +++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-resource-2.1.10/PKG-INFO new/azure-cli-resource-2.1.16/PKG-INFO --- old/azure-cli-resource-2.1.10/PKG-INFO 2019-02-12 03:05:56.000000000 +0100 +++ new/azure-cli-resource-2.1.16/PKG-INFO 2019-06-13 23:18:10.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: azure-cli-resource -Version: 2.1.10 +Version: 2.1.16 Summary: Microsoft Azure Command-Line Tools Resource Command Module Home-page: https://github.com/Azure/azure-cli Author: Microsoft Corporation @@ -19,9 +19,43 @@ Release History =============== + + 2.1.16 + ++++++ + * 'az rest': new command for making REST calls + * `policy assignment list`: Fix error when using a resource group or subscription level `--scope`. + + 2.1.15 + ++++++ + * `deployment create`: Improve error message when there is no TTY available + + 2.1.14 + ++++++ + * `resource link`: Deprecate `--link-id`, `--target-id` and `--filter-string` in favor of + `--link`, `--target`, and `--filter` respectively. + * `resource link create/update`: Fix issue where these commands would not work. + * `resource delete`: Fix issue where deleting using a resource ID could crash on error. + + 2.1.13 + ++++++ + * `deployment create`/`group deployment create`: Fixed issue where parameters file with an empty set of parameters would not work. + + 2.1.12 + ++++++ + * `deployment create/list/show`: improve table output + * `deployment create/validate`: fix issue where type secureObject was not recognized. + + 2.1.11 + ++++++ + * `deployment create`: Fix issue where type field was case-sensitive. + * `policy assignment create`: support uri based parameters file + * `policy set-definition update`: support uri based parameters and definitions files + * `policy definition update`: fix handling of parameters and rules files + * `resource show/update/delete/tag/invoke-action`: Fix issue where cross-subscription IDs did not properly honor the subscription ID. + 2.1.10 ++++++ - * Minor fixes + * Minor fixes. 2.1.9 +++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-resource-2.1.10/azure/cli/command_modules/resource/_exception_handler.py new/azure-cli-resource-2.1.16/azure/cli/command_modules/resource/_exception_handler.py --- old/azure-cli-resource-2.1.10/azure/cli/command_modules/resource/_exception_handler.py 2019-02-12 03:05:13.000000000 +0100 +++ new/azure-cli-resource-2.1.16/azure/cli/command_modules/resource/_exception_handler.py 2019-06-13 23:17:47.000000000 +0200 @@ -11,9 +11,7 @@ if isinstance(ex, ErrorResponseException): if ex.error.error: raise CLIError(ex.error.error) - else: - raise CLIError(ex.error) - else: - import sys - from six import reraise - reraise(*sys.exc_info()) + raise CLIError(ex.error) + import sys + from six import reraise + reraise(*sys.exc_info()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-resource-2.1.10/azure/cli/command_modules/resource/_help.py new/azure-cli-resource-2.1.16/azure/cli/command_modules/resource/_help.py --- old/azure-cli-resource-2.1.10/azure/cli/command_modules/resource/_help.py 2019-02-12 03:05:13.000000000 +0100 +++ new/azure-cli-resource-2.1.16/azure/cli/command_modules/resource/_help.py 2019-06-13 23:17:47.000000000 +0200 @@ -226,10 +226,10 @@ az deployment create --location WestUS --template-uri https://myresource/azuredeploy.json --parameters @myparameters.json - name: Create a deployment from a local template file, using parameters from a JSON string. text: | - az deployment create --location WestUS --template-file azuredeploy.json --parameters '{ \\ - "policyName": { \\ - "value": "policy2" \\ - } \\ + az deployment create --location WestUS --template-file azuredeploy.json --parameters '{ + "policyName": { + "value": "policy2" + } }' - name: Create a deployment from a local template, using a parameter file, a remote parameter file, and selectively overriding key/value pairs. text: > @@ -275,11 +275,18 @@ helps['feature list'] = """ type: command short-summary: List preview features. +examples: + - name: List preview features + text: az feature list + crafted: true """ helps['feature register'] = """ type: command short-summary: register a preview feature. +examples: + - name: register the "Shared Image Gallery" feature + text: az feature register --namespace Microsoft.Compute --name GalleryPreview """ helps['group'] = """ @@ -325,10 +332,10 @@ az group deployment create -g MyResourceGroup --template-uri https://myresource/azuredeploy.json --parameters @myparameters.json - name: Create a deployment from a local template file, using parameters from a JSON string. text: | - az group deployment create -g MyResourceGroup --template-file azuredeploy.json --parameters '{ \\ - "location": { \\ - "value": "westus" \\ - } \\ + az group deployment create -g MyResourceGroup --template-file azuredeploy.json --parameters '{ + "location": { + "value": "westus" + } }' - name: Create a deployment from a local template, using a local parameter file, a remote parameter file, and selectively overriding key/value pairs. text: > @@ -339,6 +346,10 @@ helps['group deployment export'] = """ type: command short-summary: Export the template used for a deployment. +examples: + - name: Export the template used for a deployment. (autogenerated) + text: az group deployment export --name MyDeployment --resource-group MyResourceGroup + crafted: true """ helps['group deployment operation'] = """ @@ -355,11 +366,24 @@ long-summary: > Parameters may be supplied from a file using the `@{path}` syntax, a JSON string, or as <KEY=VALUE> pairs. Parameters are evaluated in order, so when a value is assigned twice, the latter value will be used. It is recommended that you supply your parameters file first, and then override selectively using KEY=VALUE syntax. +examples: + - name: Validate whether a template is syntactically correct. (autogenerated) + text: |- + az group deployment validate --parameters '{ + "location": { + "value": "westus" + } + }' --resource-group MyResourceGroup --template-file storage.json + crafted: true """ helps['group deployment wait'] = """ type: command short-summary: Place the CLI in a waiting state until a deployment condition is met. +examples: + - name: Place the CLI in a waiting state until a deployment condition is met. (autogenerated) + text: az group deployment wait --name MyDeployment --resource-group MyResourceGroup --updated + crafted: true """ helps['group exists'] = """ @@ -433,6 +457,11 @@ helps['group update'] = """ type: command short-summary: Update a resource group. +examples: + - name: Update a resource group. (autogenerated) + text: |- + az group update --resource-group MyResourceGroup --set tags.CostCenter='{"Dept":"IT","Environment":"Test"}' + crafted: true """ helps['group wait'] = """ @@ -487,6 +516,9 @@ - name: Show a subscription level lock text: > az lock show -n lockname + - name: Show the properties of a lock (autogenerated) + text: az lock show --name lockname --resource-group MyResourceGroup --resource-name MyResource --resource-type Microsoft.Network/virtualNetworks + crafted: true """ helps['lock update'] = """ @@ -543,11 +575,19 @@ helps['managedapp definition delete'] = """ type: command short-summary: Delete a managed application definition. +examples: + - name: Delete a managed application definition. (autogenerated) + text: az managedapp definition delete --name MyManagedApplicationDefinition --resource-group MyResourceGroup + crafted: true """ helps['managedapp definition list'] = """ type: command short-summary: List managed application definitions. +examples: + - name: List managed application definitions. (autogenerated) + text: az managedapp definition list --resource-group MyResourceGroup + crafted: true """ helps['managedapp delete'] = """ @@ -589,25 +629,25 @@ subscription: /subscriptions/0b1f6471-1bf0-4dda-aec3-111122223333 resource group: /subscriptions/0b1f6471-1bf0-4dda-aec3-111122223333/resourceGroups/myGroup resource: /subscriptions/0b1f6471-1bf0-4dda-aec3-111122223333/resourceGroups/myGroup/providers/Microsoft.Compute/virtualMachines/myVM - az policy assignment create --scope '/providers/Microsoft.Management/managementGroups/MyManagementGroup' --policy {PolicyName} -p '{ \\ - "allowedLocations": { \\ - "value": [ \\ - "australiaeast", \\ - "eastus", \\ - "japaneast" \\ - ] \\ - } \\ + az policy assignment create --scope '/providers/Microsoft.Management/managementGroups/MyManagementGroup' --policy {PolicyName} -p '{ + "allowedLocations": { + "value": [ + "australiaeast", + "eastus", + "japaneast" + ] + } }' - name: Create a resource policy assignment and provide rule parameter values. text: | - az policy assignment create --policy {PolicyName} -p '{ \\ - "allowedLocations": { \\ - "value": [ \\ - "australiaeast", \\ - "eastus", \\ - "japaneast" \\ - ] \\ - } \\ + az policy assignment create --policy {PolicyName} -p '{ + "allowedLocations": { + "value": [ + "australiaeast", + "eastus", + "japaneast" + ] + } }' - name: Create a resource policy assignment with a system assigned identity. text: > @@ -620,6 +660,10 @@ helps['policy assignment delete'] = """ type: command short-summary: Delete a resource policy assignment. +examples: + - name: Delete a resource policy assignment. (autogenerated) + text: az policy assignment delete --name MyPolicyAssignment + crafted: true """ helps['policy assignment identity'] = """ @@ -657,6 +701,10 @@ helps['policy assignment show'] = """ type: command short-summary: Show a resource policy assignment. +examples: + - name: Show a resource policy assignment. (autogenerated) + text: az policy assignment show --name MyPolicyAssignment + crafted: true """ helps['policy definition'] = """ @@ -680,68 +728,72 @@ examples: - name: Create a read-only policy. text: | - az policy definition create --name readOnlyStorage --rules '{ \\ - "if": \\ - { \\ - "field": "type", \\ - "equals": "Microsoft.Storage/storageAccounts/write" \\ - }, \\ - "then": \\ - { \\ - "effect": "deny" \\ - } \\ + az policy definition create --name readOnlyStorage --rules '{ + "if": + { + "field": "type", + "equals": "Microsoft.Storage/storageAccounts/write" + }, + "then": + { + "effect": "deny" + } }' - name: Create a policy parameter definition. text: | - az policy definition create --name allowedLocations --rules '{ \\ - "if": { \\ - "allOf": [ \\ - { \\ - "field": "location", \\ - "notIn": "[parameters('listOfAllowedLocations')]" \\ - }, \\ - { \\ - "field": "location", \\ - "notEquals": "global" \\ - }, \\ - { \\ - "field": "type", \\ - "notEquals": "Microsoft.AzureActiveDirectory/b2cDirectories" \\ - } \\ - ] \\ - }, \\ - "then": { \\ - "effect": "deny" \\ - } \\ + az policy definition create --name allowedLocations --rules '{ + "if": { + "allOf": [ + { + "field": "location", + "notIn": "[parameters('listOfAllowedLocations')]" + }, + { + "field": "location", + "notEquals": "global" + }, + { + "field": "type", + "notEquals": "Microsoft.AzureActiveDirectory/b2cDirectories" + } + ] + }, + "then": { + "effect": "deny" + } }' \\ - --params '{ \\ - "allowedLocations": { \\ - "type": "array", \\ - "metadata": { \\ - "description": "The list of locations that can be specified when deploying resources", \\ - "strongType": "location", \\ - "displayName": "Allowed locations" \\ - } \\ - } \\ + --params '{ + "allowedLocations": { + "type": "array", + "metadata": { + "description": "The list of locations that can be specified when deploying resources", + "strongType": "location", + "displayName": "Allowed locations" + } + } }' - name: Create a read-only policy that can be applied within a management group. text: | - az policy definition create -n readOnlyStorage --management-group 'MyManagementGroup' --rules '{ \\ - "if": \\ - { \\ - "field": "type", \\ - "equals": "Microsoft.Storage/storageAccounts/write" \\ - }, \\ - "then": \\ - { \\ - "effect": "deny" \\ - } \\ + az policy definition create -n readOnlyStorage --management-group 'MyManagementGroup' --rules '{ + "if": + { + "field": "type", + "equals": "Microsoft.Storage/storageAccounts/write" + }, + "then": + { + "effect": "deny" + } }' """ helps['policy definition delete'] = """ type: command short-summary: Delete a policy definition. +examples: + - name: Delete a policy definition. (autogenerated) + text: az policy definition delete --name MyPolicyDefinition + crafted: true """ helps['policy definition list'] = """ @@ -752,6 +804,10 @@ helps['policy definition show'] = """ type: command short-summary: Show a policy definition. +examples: + - name: Show a policy definition. (autogenerated) + text: az policy definition show --name MyPolicyDefinition + crafted: true """ helps['policy definition update'] = """ @@ -780,23 +836,27 @@ examples: - name: Create a policy set definition. text: | - az policy set-definition create -n readOnlyStorage --definitions '[ \\ - { \\ - "policyDefinitionId": "/subscriptions/mySubId/providers/Microsoft.Authorization/policyDefinitions/storagePolicy" \\ - } \\ + az policy set-definition create -n readOnlyStorage --definitions '[ + { + "policyDefinitionId": "/subscriptions/mySubId/providers/Microsoft.Authorization/policyDefinitions/storagePolicy" + } ]' - name: Create a policy set definition to be used by a subscription. text: | - az policy set-definition create -n readOnlyStorage --subscription '0b1f6471-1bf0-4dda-aec3-111122223333' --definitions '[ \\ - { \\ - "policyDefinitionId": "/subscriptions/mySubId/providers/Microsoft.Authorization/policyDefinitions/storagePolicy" \\ - } \\ + az policy set-definition create -n readOnlyStorage --subscription '0b1f6471-1bf0-4dda-aec3-111122223333' --definitions '[ + { + "policyDefinitionId": "/subscriptions/mySubId/providers/Microsoft.Authorization/policyDefinitions/storagePolicy" + } ]' """ helps['policy set-definition delete'] = """ type: command short-summary: Delete a policy set definition. +examples: + - name: Delete a policy set definition. (autogenerated) + text: az policy set-definition delete --name MyPolicySetDefinition + crafted: true """ helps['policy set-definition list'] = """ @@ -807,11 +867,24 @@ helps['policy set-definition show'] = """ type: command short-summary: Show a policy set definition. +examples: + - name: Show a policy set definition. (autogenerated) + text: az policy set-definition show --name MyPolicySetDefinition + crafted: true """ helps['policy set-definition update'] = """ type: command short-summary: Update a policy set definition. +examples: + - name: Update a policy set definition. (autogenerated) + text: |- + az policy set-definition update --definitions '[ + { + "policyDefinitionId": "/subscriptions/mySubId/providers/Microsoft.Authorization/policyDefinitions/storagePolicy" + } + ]' --name MyPolicySetDefinition + crafted: true """ helps['provider'] = """ @@ -840,16 +913,28 @@ helps['provider operation show'] = """ type: command short-summary: Get an individual provider's operations. +examples: + - name: Get an individual provider's operations. (autogenerated) + text: az provider operation show --namespace Microsoft.Storage + crafted: true """ helps['provider register'] = """ type: command short-summary: Register a provider. +examples: + - name: Register a provider. (autogenerated) + text: az provider register --namespace 'Microsoft.PolicyInsights' + crafted: true """ helps['provider unregister'] = """ type: command short-summary: Unregister a provider. +examples: + - name: Unregister a provider. (autogenerated) + text: az provider unregister --namespace Microsoft.Automation + crafted: true """ helps['resource'] = """ @@ -863,20 +948,20 @@ examples: - name: Create an API app by providing a full JSON configuration. text: | - az resource create -g myRG -n myApiApp --resource-type Microsoft.web/sites --is-full-object --properties '{ \\ - "kind": "api", \\ - "location": "West US", \\ - "properties": { \\ - "serverFarmId": "/subscriptions/{SubID}/resourcegroups/{ResourceGroup}/providers/Microsoft.Web/serverfarms/{ServicePlan}" \\ - } \\ + az resource create -g myRG -n myApiApp --resource-type Microsoft.web/sites --is-full-object --properties '{ + "kind": "api", + "location": "West US", + "properties": { + "serverFarmId": "/subscriptions/{SubID}/resourcegroups/{ResourceGroup}/providers/Microsoft.Web/serverfarms/{ServicePlan}" + } }' - name: Create a resource by loading JSON configuration from a file. text: > az resource create -g myRG -n myApiApp --resource-type Microsoft.web/sites --is-full-object --properties @jsonConfigFile - name: Create a web app with the minimum required configuration information. text: | - az resource create -g myRG -n myWeb --resource-type Microsoft.web/sites --properties '{ \\ - "serverFarmId":"/subscriptions/{SubID}/resourcegroups/{ResourceGroup}/providers/Microsoft.Web/serverfarms/{ServicePlan}" \\ + az resource create -g myRG -n myWeb --resource-type Microsoft.web/sites --properties '{ + "serverFarmId":"/subscriptions/{SubID}/resourcegroups/{ResourceGroup}/providers/Microsoft.Web/serverfarms/{ServicePlan}" }' """ @@ -911,11 +996,14 @@ text: > az resource invoke-action --action capture \\ --ids /subscriptions/{SubID}/resourceGroups/{ResourceGroup}/providers/Microsoft.Compute/virtualMachines/{VMName} \\ - --request-body '{ \\ - "vhdPrefix": "myPrefix", \\ - "destinationContainerName": "myContainer", \\ - "overwriteVhds": true \\ + --request-body '{ + "vhdPrefix": "myPrefix", + "destinationContainerName": "myContainer", + "overwriteVhds": true }' + - name: Invoke an action on the resource. (autogenerated) + text: az resource invoke-action --action capture --name MyResource --resource-group MyResourceGroup --resource-type Microsoft.web/sites + crafted: true """ helps['resource link'] = """ @@ -923,28 +1011,33 @@ short-summary: Manage links between resources. long-summary: > Linking is a feature of the Resource Manager. It enables declaring relationships between resources even if they do not reside in the same resource group. - Linking has no impact on resource usage, no impact on billing, and no impact on role-based access. It allows for managing multiple resources across groups - as a single unit. + Linking has no impact on resource usage, billing, or role-based access. It allows for managing multiple resources across groups as a single unit. """ helps['resource link create'] = """ type: command short-summary: Create a new link between resources. -long-summary: A link-id is of the form /subscriptions/{SubID}/resourceGroups/{ResourceGroupID}/providers/{ProviderNamespace}/{ResourceType}/{ResourceName}/providers/Microsoft.Resources/links/{LinkName} +parameters: + - name: --link + long-summary: > + Format: /subscriptions/{SubID}/resourceGroups/{ResourceGroupID}/providers/{ProviderNamespace}/{ResourceType}/{ResourceName}/providers/Microsoft.Resources/links/{LinkName} examples: - name: Create a link from {SourceID} to {ResourceID} with notes text: > - az resource link create --link-id {SourceID} --target-id {ResourceID} --notes "SourceID depends on ResourceID" + az resource link create --link {SourceID} --target {ResourceID} --notes "SourceID depends on ResourceID" """ helps['resource link delete'] = """ type: command short-summary: Delete a link between resources. -long-summary: A link-id is of the form /subscriptions/{SubID}/resourceGroups/{ResourceGroupID}/providers/{ProviderNamespace}/{ResourceType}/{ResourceName}/providers/Microsoft.Resources/links/{LinkName} +parameters: + - name: --link + long-summary: > + Format: /subscriptions/{SubID}/resourceGroups/{ResourceGroupID}/providers/{ProviderNamespace}/{ResourceType}/{ResourceName}/providers/Microsoft.Resources/links/{LinkName} examples: - name: Delete link {LinkID} text: > - az resource link delete --link-id {LinkID} + az resource link delete --link {LinkID} """ helps['resource link list'] = """ @@ -959,20 +1052,17 @@ az resource link list --scope /subscriptions/{SubID}/resourceGroups/{ResourceGroup} """ -helps['resource link show'] = """ -type: command -short-summary: Get details for a resource link. -long-summary: A link-id is of the form /subscriptions/{SubID}/resourceGroups/{ResourceGroup}/providers/{ProviderNamespace}/{ResourceType}/{ResourceName}/providers/Microsoft.Resources/links/{LinkName} -""" - helps['resource link update'] = """ type: command short-summary: Update link between resources. -long-summary: A link-id is of the form /subscriptions/{SubID}/resourceGroups/{ResourceGroup}/providers/{ProviderNamespace}/{ResourceType}/{ResourceName}/providers/Microsoft.Resources/links/{LinkName} +parameters: + - name: --link + long-summary: > + Format: /subscriptions/{SubID}/resourceGroups/{ResourceGroupID}/providers/{ProviderNamespace}/{ResourceType}/{ResourceName}/providers/Microsoft.Resources/links/{LinkName} examples: - name: Update the notes for {LinkID} notes "some notes to explain this link" text: > - az resource link update --link-id {LinkID} --notes "some notes to explain this link" + az resource link update --link {LinkID} --notes "some notes to explain this link" """ helps['resource list'] = """ @@ -1088,6 +1178,10 @@ helps['resource update'] = """ type: command short-summary: Update a resource. +examples: + - name: Update a resource. (autogenerated) + text: az resource update --ids $id --set properties.connectionType=Proxy + crafted: true """ helps['resource wait'] = """ @@ -1099,3 +1193,15 @@ type: group short-summary: Manage resource tags. """ + +helps['rest'] = """ + type: command + short-summary: invoke a custom request + examples: + - name: Get Audit log through Microsoft Graph + text: > + az rest --method get --uri https://graph.microsoft.com/beta/auditLogs/directoryAudits + - name: Update a Azure Active Directory Graph User's display name + text: > + az rest --method patch --uri "https://graph.microsoft.com/v1.0/users/[email protected]" --body "{\\"displayName\\": \\"jondoe2\\"}" +""" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-resource-2.1.10/azure/cli/command_modules/resource/_params.py new/azure-cli-resource-2.1.16/azure/cli/command_modules/resource/_params.py --- old/azure-cli-resource-2.1.10/azure/cli/command_modules/resource/_params.py 2019-02-12 03:05:13.000000000 +0100 +++ new/azure-cli-resource-2.1.16/azure/cli/command_modules/resource/_params.py 2019-06-13 23:17:47.000000000 +0200 @@ -71,6 +71,13 @@ c.argument('properties', options_list=['--properties', '-p'], help='a JSON-formatted string containing resource properties') c.argument('is_full_object', action='store_true', help='Indicates that the properties object includes other options such as location, tags, sku, and/or plan.') + with self.argument_context('resource link') as c: + c.argument('target_id', options_list=['--target', c.deprecate(target='--target-id', redirect='--target', hide=True)], help='Fully-qualified resource ID of the resource link target.') + c.argument('link_id', options_list=['--link', c.deprecate(target='--link-id', redirect='--link', hide=True)], help='Fully-qualified resource ID of the resource link.') + c.argument('notes', help='Notes for the link.') + c.argument('scope', help='Fully-qualified scope for retrieving links.') + c.argument('filter_string', options_list=['--filter', c.deprecate(target='--filter-string', redirect='--filter', hide=True)], help='Filter string for limiting results.') + with self.argument_context('provider') as c: c.ignore('top') c.argument('resource_provider_namespace', options_list=['--namespace', '-n'], completer=get_providers_completion_list, help=_PROVIDER_HELP_TEXT) @@ -95,6 +102,7 @@ c.argument('resource_group_name', arg_type=resource_group_name_type, help='the resource group where the policy will be applied') with self.argument_context('policy definition', resource_type=ResourceType.MGMT_RESOURCE_POLICY) as c: + from azure.mgmt.resource.policy.models import PolicyMode c.argument('policy_definition_name', arg_type=existing_policy_definition_name_type) c.argument('rules', help='JSON formatted string or a path to a file with such content', type=file_type, completer=FilesCompleter()) c.argument('display_name', help='Display name of policy definition.') @@ -103,11 +111,10 @@ c.argument('metadata', min_api='2017-06-01-preview', nargs='+', validator=validate_metadata, help='Metadata in space-separated key=value pairs.') c.argument('subscription', arg_type=subscription_type) c.argument('management_group', arg_type=management_group_name_type) + c.argument('mode', arg_type=get_enum_type(PolicyMode), options_list=['--mode', '-m'], help='Mode of the policy definition.', min_api='2016-12-01') with self.argument_context('policy definition create', resource_type=ResourceType.MGMT_RESOURCE_POLICY) as c: - from azure.mgmt.resource.policy.models import PolicyMode c.argument('name', options_list=['--name', '-n'], help='Name of the new policy definition.') - c.argument('mode', arg_type=get_enum_type(PolicyMode), options_list=['--mode', '-m'], help='Mode of the new policy definition.', min_api='2016-12-01') with self.argument_context('policy assignment', resource_type=ResourceType.MGMT_RESOURCE_POLICY) as c: c.ignore('_subscription') @@ -119,7 +126,7 @@ with self.argument_context('policy assignment create', resource_type=ResourceType.MGMT_RESOURCE_POLICY) as c: c.argument('name', options_list=['--name', '-n'], help='Name of the new policy assignment.') - c.argument('params', options_list=['--params', '-p'], help='JSON formatted string or path to file with parameter values of policy rule.', min_api='2016-12-01') + c.argument('params', options_list=['--params', '-p'], help='JSON formatted string or a path to a file or uri with parameter values of the policy rule.', type=file_type, completer=FilesCompleter(), min_api='2016-12-01') with self.argument_context('policy assignment create', resource_type=ResourceType.MGMT_RESOURCE_POLICY, min_api='2017-06-01-preview') as c: c.argument('policy_set_definition', options_list=['--policy-set-definition', '-d'], help='Name or id of the policy set definition.') @@ -198,7 +205,7 @@ with self.argument_context('lock') as c: c.argument('lock_name', options_list=['--name', '-n'], validator=validate_lock_parameters) - c.argument('level', arg_type=get_enum_type(LockLevel), options_list=['--lock-type', '-t']) + c.argument('level', arg_type=get_enum_type(LockLevel), options_list=['--lock-type', '-t'], help='The type of lock restriction.') c.argument('parent_resource_path', resource_parent_type) c.argument('resource_provider_namespace', resource_namespace_type) c.argument('resource_type', arg_type=resource_type_type, completer=get_resource_types_completion_list) @@ -226,7 +233,7 @@ for scope in ['lock', 'account lock', 'group lock', 'resource lock']: with self.argument_context(scope) as c: c.argument('lock_name', options_list=['--name', '-n'], help='Name of the lock') - c.argument('level', options_list=['--lock-type', '-t'], arg_type=get_enum_type([LockLevel.can_not_delete, LockLevel.read_only])) + c.argument('level', options_list=['--lock-type', '-t'], arg_type=get_enum_type([LockLevel.can_not_delete, LockLevel.read_only]), help='The type of lock restriction.') c.argument('ids', nargs='+', options_list='--ids', help='One or more resource IDs (space-delimited). If provided, no other "Resource Id" arguments should be specified.') c.argument('notes', help='Notes about this lock.') @@ -246,7 +253,7 @@ c.argument('parameters', help='JSON formatted string or a path to a file with such content', type=file_type) with self.argument_context('managedapp definition create') as c: - c.argument('lock_level', arg_type=get_enum_type(ApplicationLockLevel)) + c.argument('lock_level', arg_type=get_enum_type(ApplicationLockLevel), help='The type of lock restriction.') c.argument('authorizations', options_list=['--authorizations', '-a'], nargs='+', help="space-separated authorization pairs in a format of <principalId>:<roleDefinitionId>") c.argument('createUiDefinition', options_list=['--create-ui-definition', '-c'], help='JSON formatted string or a path to a file with such content', type=file_type) c.argument('mainTemplate', options_list=['--main-template', '-t'], help='JSON formatted string or a path to a file with such content', type=file_type) @@ -269,3 +276,18 @@ with self.argument_context('account management-group update') as c: c.argument('display_name', options_list=['--display-name', '-d']) c.argument('parent_id', options_list=['--parent', '-p']) + + with self.argument_context('rest') as c: + c.argument('method', options_list=['--method', '-m'], arg_type=get_enum_type(['head', 'get', 'put', 'post', 'delete', 'options', 'patch'], default='get'), + help='HTTP request method') + c.argument('uri', options_list=['--uri', '-u'], help='request uri. For uri without host, CLI will assume "https://management.azure.com/".' + ' Common tokens will also be replaced with real values including "{subscriptionId}"') + c.argument('headers', nargs='+', help="Space-separated headers in KEY=VALUE format or JSON string. Use @{file} to load from a file") + c.argument('uri_parameters', nargs='+', help='Space-separated queries in KEY=VALUE format or JSON string. Use @{file} to load from a file') + c.argument('skip_authorization_header', action='store_true', help='do not auto append "Authorization" header') + c.argument('body', options_list=['--body', '-b'], help='request body') + c.argument('output_file', help='save response payload to a file') + c.argument('resource', help='Resource url for which CLI should acquire a token in order to access ' + 'the service. The token will be placed in the "Authorization" header. By default, ' + 'CLI can figure this out based on "--url" argument, unless you use ones not in the list ' + 'of "az cloud show --query endpoints"') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-resource-2.1.10/azure/cli/command_modules/resource/commands.py new/azure-cli-resource-2.1.16/azure/cli/command_modules/resource/commands.py --- old/azure-cli-resource-2.1.10/azure/cli/command_modules/resource/commands.py 2019-02-12 03:05:13.000000000 +0100 +++ new/azure-cli-resource-2.1.16/azure/cli/command_modules/resource/commands.py 2019-06-13 23:17:47.000000000 +0200 @@ -40,9 +40,18 @@ # Resource group deployment commands +def transform_deployment(result): + r = result + return OrderedDict([('Name', r['name']), + ('ResourceGroup', r['resourceGroup']), + ('State', r['properties']['provisioningState']), + ('Timestamp', r['properties']['timestamp']), + ('Mode', r['properties']['mode'])]) + + def transform_deployments_list(result): sort_list = sorted(result, key=lambda deployment: deployment['properties']['timestamp']) - return [OrderedDict([('Name', r['name']), ('Timestamp', r['properties']['timestamp']), ('State', r['properties']['provisioningState'])]) for r in sort_list] + return [transform_deployment(r) for r in sort_list] # pylint: disable=too-many-statements @@ -52,37 +61,37 @@ resource_custom = CliCommandType(operations_tmpl='azure.cli.command_modules.resource.custom#{}') resource_group_sdk = CliCommandType( - operations_tmpl='azure.mgmt.resource.resources.operations.resource_groups_operations#ResourceGroupsOperations.{}', + operations_tmpl='azure.mgmt.resource.resources.operations#ResourceGroupsOperations.{}', client_factory=cf_resource_groups, resource_type=ResourceType.MGMT_RESOURCE_RESOURCES ) resource_provider_sdk = CliCommandType( - operations_tmpl='azure.mgmt.resource.resources.operations.providers_operations#ProvidersOperations.{}', + operations_tmpl='azure.mgmt.resource.resources.operations#ProvidersOperations.{}', client_factory=cf_providers, resource_type=ResourceType.MGMT_RESOURCE_RESOURCES ) resource_feature_sdk = CliCommandType( - operations_tmpl='azure.mgmt.resource.features.operations.features_operations#FeaturesOperations.{}', + operations_tmpl='azure.mgmt.resource.features.operations#FeaturesOperations.{}', client_factory=cf_features, resource_type=ResourceType.MGMT_RESOURCE_FEATURES ) resource_tag_sdk = CliCommandType( - operations_tmpl='azure.mgmt.resource.resources.operations.tags_operations#TagsOperations.{}', + operations_tmpl='azure.mgmt.resource.resources.operations#TagsOperations.{}', client_factory=cf_tags, resource_type=ResourceType.MGMT_RESOURCE_RESOURCES ) resource_deployment_sdk = CliCommandType( - operations_tmpl='azure.mgmt.resource.resources.operations.deployments_operations#DeploymentsOperations.{}', + operations_tmpl='azure.mgmt.resource.resources.operations#DeploymentsOperations.{}', client_factory=cf_deployments, resource_type=ResourceType.MGMT_RESOURCE_RESOURCES ) resource_deployment_operation_sdk = CliCommandType( - operations_tmpl='azure.mgmt.resource.resources.operations.deployment_operations#DeploymentOperations.{}', + operations_tmpl='azure.mgmt.resource.resources.operations#DeploymentOperations.{}', client_factory=cf_deployment_operations, resource_type=ResourceType.MGMT_RESOURCE_RESOURCES ) @@ -122,13 +131,13 @@ ) resource_managementgroups_sdk = CliCommandType( - operations_tmpl='azure.mgmt.managementgroups.operations.management_groups_operations#ManagementGroupsOperations.{}', + operations_tmpl='azure.mgmt.managementgroups.operations#ManagementGroupsOperations.{}', client_factory=cf_management_groups, exception_handler=managementgroups_exception_handler ) resource_managementgroups_subscriptions_sdk = CliCommandType( - operations_tmpl='azure.mgmt.managementgroups.operations.management_group_subscriptions_operations#ManagementGroupSubscriptionsOperations.{}', + operations_tmpl='azure.mgmt.managementgroups.operations#ManagementGroupSubscriptionsOperations.{}', client_factory=cf_management_group_subscriptions, exception_handler=managementgroups_exception_handler ) @@ -193,7 +202,7 @@ # Resource feature commands with self.command_group('feature', resource_feature_sdk, client_factory=cf_features, resource_type=PROFILE_TYPE, - min_api='2018-03-02-hybrid') as g: + min_api='2019-03-02-hybrid') as g: feature_table_transform = '{Name:name, RegistrationState:properties.state}' g.custom_command('list', 'list_features', table_transformer='[].' + feature_table_transform) g.show_command('show', 'get', table_transformer=feature_table_transform) @@ -208,10 +217,11 @@ g.command('remove-value', 'delete_value') with self.command_group('group deployment', resource_deployment_sdk) as g: - g.custom_command('create', 'deploy_arm_template', supports_no_wait=True, validator=process_deployment_create_namespace, exception_handler=handle_template_based_exception) + g.custom_command('create', 'deploy_arm_template', supports_no_wait=True, validator=process_deployment_create_namespace, + table_transformer=transform_deployment, exception_handler=handle_template_based_exception) g.command('list', 'list_by_resource_group', table_transformer=transform_deployments_list, min_api='2017-05-10') g.command('list', 'list', table_transformer=transform_deployments_list, max_api='2016-09-01') - g.show_command('show', 'get') + g.show_command('show', 'get', table_transformer=transform_deployment) g.command('delete', 'delete', supports_no_wait=True) g.custom_command('validate', 'validate_arm_template', table_transformer=deployment_validate_table_format, exception_handler=handle_template_based_exception) g.custom_command('export', 'export_deployment_as_template') @@ -303,3 +313,6 @@ with self.command_group('account management-group subscription', resource_managementgroups_subscriptions_sdk, client_factory=cf_management_group_subscriptions) as g: g.custom_command('add', 'cli_managementgroups_subscription_add') g.custom_command('remove', 'cli_managementgroups_subscription_remove') + + with self.command_group('') as g: + g.custom_command('rest', 'rest_call', is_preview=True) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-resource-2.1.10/azure/cli/command_modules/resource/custom.py new/azure-cli-resource-2.1.16/azure/cli/command_modules/resource/custom.py --- old/azure-cli-resource-2.1.10/azure/cli/command_modules/resource/custom.py 2019-02-12 03:05:13.000000000 +0100 +++ new/azure-cli-resource-2.1.16/azure/cli/command_modules/resource/custom.py 2019-06-13 23:17:47.000000000 +0200 @@ -19,11 +19,7 @@ from six.moves.urllib.request import urlopen # pylint: disable=import-error from six.moves.urllib.parse import urlparse # pylint: disable=import-error -from msrestazure.tools import is_valid_resource_id, parse_resource_id, resource_id as resource_dict_to_id - -from knack.log import get_logger -from knack.prompting import prompt, prompt_pass, prompt_t_f, prompt_choice_list, prompt_int, NoTTYException -from knack.util import CLIError +from msrestazure.tools import is_valid_resource_id, parse_resource_id from azure.mgmt.resource.resources.models import GenericResource @@ -40,18 +36,30 @@ _resource_links_client_factory, _authorization_management_client, _resource_managedapps_client_factory) from azure.cli.command_modules.resource._validators import _parse_lock_id +from knack.log import get_logger +from knack.prompting import prompt, prompt_pass, prompt_t_f, prompt_choice_list, prompt_int, NoTTYException +from knack.util import CLIError + from ._validators import MSI_LOCAL_ID logger = get_logger(__name__) +def _build_resource_id(**kwargs): + from msrestazure.tools import resource_id as resource_id_from_dict + try: + return resource_id_from_dict(**kwargs) + except KeyError: + return None + + def _process_parameters(template_param_defs, parameter_lists): def _try_parse_json_object(value): try: parsed = shell_safe_json_parse(value) return parsed.get('parameters', parsed) - except CLIError: + except Exception: # pylint: disable=broad-except return None def _try_load_file_object(value): @@ -87,7 +95,7 @@ param_type = param.get('type', None) if param_type: param_type = param_type.lower() - if param_type in ['object', 'array']: + if param_type in ['object', 'array', 'secureobject']: parameters[key] = {'value': shell_safe_json_parse(value)} elif param_type in ['string', 'securestring']: parameters[key] = {'value': value} @@ -104,7 +112,11 @@ parameters = {} for params in parameter_lists or []: for item in params: - param_obj = _try_load_file_object(item) or _try_parse_json_object(item) or _try_load_uri(item) + param_obj = _try_load_file_object(item) + if param_obj is None: + param_obj = _try_parse_json_object(item) + if param_obj is None: + param_obj = _try_load_uri(item) if param_obj is not None: parameters.update(param_obj) elif not _try_parse_key_value_object(template_param_defs, parameters, item): @@ -139,7 +151,7 @@ no_tty = False for param_name in prompt_list: param = missing_parameters[param_name] - param_type = param.get('type', 'string') + param_type = param.get('type', 'string').lower() description = 'Missing description' metadata = param.get('metadata', None) if metadata is not None: @@ -212,11 +224,15 @@ def _get_missing_parameters(parameters, template, prompt_fn): missing = _find_missing_parameters(parameters, template) if missing: - prompt_parameters = prompt_fn(missing) - for param_name in prompt_parameters: - parameters[param_name] = { - "value": prompt_parameters[param_name] - } + try: + prompt_parameters = prompt_fn(missing) + for param_name in prompt_parameters: + parameters[param_name] = { + "value": prompt_parameters[param_name] + } + except NoTTYException: + raise CLIError("Missing input parameters: {}" + .format(', '.join(sorted(missing.keys())))) return parameters @@ -420,7 +436,6 @@ def _get_custom_or_builtin_policy(cmd, client, name, subscription=None, management_group=None, for_policy_set=False): from msrest.exceptions import HttpOperationError from msrestazure.azure_exceptions import CloudError - ErrorResponseException = cmd.get_models('ErrorResponseException') policy_operations = client.policy_set_definitions if for_policy_set else client.policy_definitions if cmd.supported_api_version(min_api='2018-03-01'): @@ -435,7 +450,7 @@ if management_group: return policy_operations.get_at_management_group(name, management_group) return policy_operations.get(name) - except (CloudError, HttpOperationError, ErrorResponseException) as ex: + except (CloudError, HttpOperationError) as ex: status_code = ex.status_code if isinstance(ex, CloudError) else ex.response.status_code if status_code == 404: return policy_operations.get_built_in(name) @@ -445,7 +460,7 @@ def _load_file_string_or_uri(file_or_string_or_uri, name, required=True): if file_or_string_or_uri is None: if required: - raise CLIError('One of --{} or --{}-uri is required'.format(name, name)) + raise CLIError('--{} is required'.format(name)) return None url = urlparse(file_or_string_or_uri) if url.scheme == 'http' or url.scheme == 'https' or url.scheme == 'file': @@ -612,8 +627,7 @@ plan_publisher is None and plan_version is None): raise CLIError('--plan-name, --plan-product, --plan-publisher and \ --plan-version are all required if kind is MarketPlace') - else: - application.plan = Plan(name=plan_name, publisher=plan_publisher, product=plan_product, version=plan_version) + application.plan = Plan(name=plan_name, publisher=plan_publisher, product=plan_product, version=plan_version) applicationParameters = None @@ -665,14 +679,12 @@ from azure.mgmt.resource.managedapplications.models import ApplicationDefinition, ApplicationProviderAuthorization if not package_file_uri and not create_ui_definition and not main_template: raise CLIError('usage error: --package-file-uri <url> | --create-ui-definition --main-template') - elif package_file_uri: + if package_file_uri: if create_ui_definition or main_template: - raise CLIError('usage error: must not specify \ - --create-ui-definition --main-template') - elif not package_file_uri: + raise CLIError('usage error: must not specify --create-ui-definition --main-template') + if not package_file_uri: if not create_ui_definition or not main_template: - raise CLIError('usage error: must specify \ - --create-ui-definition --main-template') + raise CLIError('usage error: must specify --create-ui-definition --main-template') racf = _resource_managedapps_client_factory(cmd.cli_ctx) rcf = _resource_client_factory(cmd.cli_ctx) if not location: @@ -776,28 +788,31 @@ if not is_valid_resource_id(rid): raise CLIError('az resource: error: argument --ids: invalid ResourceId value: \'%s\'' % rid) - return (parse_resource_id(rid) for rid in resource_ids) + return ({'resource_id': rid} for rid in resource_ids) def _get_rsrc_util_from_parsed_id(cli_ctx, parsed_id, api_version): return _ResourceUtils(cli_ctx, - parsed_id['resource_group'], - parsed_id['resource_namespace'], - parsed_id['resource_parent'], - parsed_id['resource_type'], - parsed_id['resource_name'], - None, + parsed_id.get('resource_group', None), + parsed_id.get('resource_namespace', None), + parsed_id.get('resource_parent', None), + parsed_id.get('resource_type', None), + parsed_id.get('resource_name', None), + parsed_id.get('resource_id', None), api_version) -def _create_parsed_id(resource_group_name=None, resource_provider_namespace=None, parent_resource_path=None, +def _create_parsed_id(cli_ctx, resource_group_name=None, resource_provider_namespace=None, parent_resource_path=None, resource_type=None, resource_name=None): + from azure.cli.core.commands.client_factory import get_subscription_id + subscription = get_subscription_id(cli_ctx) return { 'resource_group': resource_group_name, 'resource_namespace': resource_provider_namespace, 'resource_parent': parent_resource_path, 'resource_type': resource_type, - 'resource_name': resource_name + 'resource_name': resource_name, + 'subscription': subscription } @@ -815,7 +830,8 @@ def show_resource(cmd, resource_ids=None, resource_group_name=None, resource_provider_namespace=None, parent_resource_path=None, resource_type=None, resource_name=None, api_version=None, include_response_body=False): - parsed_ids = _get_parsed_resource_ids(resource_ids) or [_create_parsed_id(resource_group_name, + parsed_ids = _get_parsed_resource_ids(resource_ids) or [_create_parsed_id(cmd.cli_ctx, + resource_group_name, resource_provider_namespace, parent_resource_path, resource_type, @@ -835,7 +851,8 @@ This function allows deletion of ids with dependencies on one another. This is done with multiple passes through the given ids. """ - parsed_ids = _get_parsed_resource_ids(resource_ids) or [_create_parsed_id(resource_group_name, + parsed_ids = _get_parsed_resource_ids(resource_ids) or [_create_parsed_id(cmd.cli_ctx, + resource_group_name, resource_provider_namespace, parent_resource_path, resource_type, @@ -852,7 +869,7 @@ for rsrc_utils, id_dict in to_be_deleted: try: operations.append(rsrc_utils.delete()) - resource = resource_dict_to_id(**id_dict) if id_dict.get("subscription") else resource_name + resource = _build_resource_id(**id_dict) or resource_name logger.debug("deleting %s", resource) except CloudError as e: # request to delete failed, add parsed id dict back to queue @@ -869,10 +886,11 @@ results.append(operation.result()) if to_be_deleted: - error_msg_builder = ['Some resources failed to be deleted:'] + error_msg_builder = ['Some resources failed to be deleted (run with `--verbose` for more information):'] for _, id_dict in to_be_deleted: - logger.debug(id_dict['exception']) - error_msg_builder.append(resource_dict_to_id(**id_dict)) + logger.info(id_dict['exception']) + resource_id = _build_resource_id(**id_dict) or id_dict['resource_id'] + error_msg_builder.append(resource_id) raise CLIError(os.linesep.join(error_msg_builder)) return _single_or_collection(results) @@ -882,7 +900,8 @@ def update_resource(cmd, parameters, resource_ids=None, resource_group_name=None, resource_provider_namespace=None, parent_resource_path=None, resource_type=None, resource_name=None, api_version=None): - parsed_ids = _get_parsed_resource_ids(resource_ids) or [_create_parsed_id(resource_group_name, + parsed_ids = _get_parsed_resource_ids(resource_ids) or [_create_parsed_id(cmd.cli_ctx, + resource_group_name, resource_provider_namespace, parent_resource_path, resource_type, @@ -898,7 +917,8 @@ parent_resource_path=None, resource_type=None, resource_name=None, api_version=None): """ Updates the tags on an existing resource. To clear tags, specify the --tag option without anything else. """ - parsed_ids = _get_parsed_resource_ids(resource_ids) or [_create_parsed_id(resource_group_name, + parsed_ids = _get_parsed_resource_ids(resource_ids) or [_create_parsed_id(cmd.cli_ctx, + resource_group_name, resource_provider_namespace, parent_resource_path, resource_type, @@ -914,7 +934,8 @@ parent_resource_path=None, resource_type=None, resource_name=None, api_version=None): """ Invokes the provided action on an existing resource.""" - parsed_ids = _get_parsed_resource_ids(resource_ids) or [_create_parsed_id(resource_group_name, + parsed_ids = _get_parsed_resource_ids(resource_ids) or [_create_parsed_id(cmd.cli_ctx, + resource_group_name, resource_provider_namespace, parent_resource_path, resource_type, @@ -999,8 +1020,8 @@ raise CLIError('All resources should be under the same group') rcf = _resource_client_factory(cmd.cli_ctx) - target = resource_dict_to_id(subscription=(destination_subscription_id or rcf.config.subscription_id), - resource_group=destination_group) + target = _build_resource_id(subscription=(destination_subscription_id or rcf.config.subscription_id), + resource_group=destination_group) return rcf.resources.move_resources(resources[0]['resource_group'], ids, target) @@ -1033,12 +1054,7 @@ scope = _build_policy_scope(policy_client.config.subscription_id, resource_group_name, scope) policy_id = _resolve_policy_id(cmd, policy, policy_set_definition, policy_client) - - if params: - if os.path.exists(params): - params = get_file_json(params) - else: - params = shell_safe_json_parse(params) + params = _load_file_string_or_uri(params, 'params', False) PolicyAssignment = cmd.get_models('PolicyAssignment') assignment = PolicyAssignment(display_name=display_name, policy_definition_id=policy_id, scope=scope) @@ -1104,35 +1120,30 @@ def list_policy_assignment(cmd, disable_scope_strict_match=None, resource_group_name=None, scope=None): + from azure.cli.core.commands.client_factory import get_subscription_id policy_client = _resource_policy_client_factory(cmd.cli_ctx) - if scope and not is_valid_resource_id(scope): - parts = scope.strip('/').split('/') - if len(parts) == 4: - resource_group_name = parts[3] - elif len(parts) == 2: - # rarely used, but still verify - if parts[1].lower() != policy_client.config.subscription_id.lower(): - raise CLIError("Please use current active subscription's id") - else: - err = "Invalid scope '{}', it should point to a resource group or a resource" - raise CLIError(err.format(scope)) - scope = None - - _scope = _build_policy_scope(policy_client.config.subscription_id, + _scope = _build_policy_scope(get_subscription_id(cmd.cli_ctx), resource_group_name, scope) - if resource_group_name: - result = policy_client.policy_assignments.list_for_resource_group(resource_group_name) - elif scope: - # pylint: disable=redefined-builtin - id = parse_resource_id(scope) - parent_resource_path = '' if not id.get('child_name_1') else (id['type'] + '/' + id['name']) - resource_type = id.get('child_type_1') or id['type'] - resource_name = id.get('child_name_1') or id['name'] + id_parts = parse_resource_id(_scope) + subscription = id_parts.get('subscription') + resource_group = id_parts.get('resource_group') + resource_type = id_parts.get('child_type_1') or id_parts.get('type') + resource_name = id_parts.get('child_name_1') or id_parts.get('name') + + if all([resource_type, resource_group, subscription]): + namespace = id_parts.get('namespace') + parent_resource_path = '' if not id_parts.get('child_name_1') else (id_parts['type'] + '/' + id_parts['name']) result = policy_client.policy_assignments.list_for_resource( - id['resource_group'], id['namespace'], + resource_group, namespace, parent_resource_path, resource_type, resource_name) - else: + elif resource_group: + result = policy_client.policy_assignments.list_for_resource_group(resource_group) + elif subscription: result = policy_client.policy_assignments.list() + elif scope: + raise CLIError('usage error `--scope`: must be a fully qualified ARM ID.') + else: + raise CLIError('usage error: --scope ARM_ID | --resource-group NAME | --subscription ID') if not disable_scope_strict_match: result = [i for i in result if _scope.lower() == i.scope.lower()] @@ -1289,6 +1300,9 @@ display_name=None, description=None, metadata=None, mode=None, subscription=None, management_group=None): + rules = _load_file_string_or_uri(rules, 'rules', False) + params = _load_file_string_or_uri(params, 'params', False) + policy_client = _resource_policy_client_factory(cmd.cli_ctx) definition = _get_custom_or_builtin_policy(cmd, policy_client, policy_definition_name, subscription, management_group) # pylint: disable=line-too-long,no-member @@ -1318,17 +1332,8 @@ display_name=None, description=None, subscription=None, management_group=None): - if definitions: - if os.path.exists(definitions): - definitions = get_file_json(definitions) - else: - definitions = shell_safe_json_parse(definitions) - - if params: - if os.path.exists(params): - params = get_file_json(params) - else: - params = shell_safe_json_parse(params) + definitions = _load_file_string_or_uri(definitions, 'definitions', False) + params = _load_file_string_or_uri(params, 'params', False) policy_client = _resource_policy_client_factory(cmd.cli_ctx) definition = _get_custom_or_builtin_policy(cmd, policy_client, policy_set_definition_name, subscription, management_group, True) @@ -1736,55 +1741,48 @@ return lock_client.management_locks.create_or_update_at_resource_level( resource_group, resource_provider_namespace, parent_resource_path or '', resource_type, resource_name, lock_name, params) - # endregion -# region ResourceLinks - +# region ResourceLinks def create_resource_link(cmd, link_id, target_id, notes=None): - """ - :param target_id: The id of the resource link target. - :type target_id: str - :param notes: Notes for this link. - :type notes: str - """ links_client = _resource_links_client_factory(cmd.cli_ctx).resource_links - properties = ResourceLinkProperties(target_id, notes) + properties = ResourceLinkProperties(target_id=target_id, notes=notes) links_client.create_or_update(link_id, properties) def update_resource_link(cmd, link_id, target_id=None, notes=None): - """ - :param target_id: The id of the resource link target. - :type target_id: str - :param notes: Notes for this link. - :type notes: str - """ links_client = _resource_links_client_factory(cmd.cli_ctx).resource_links params = links_client.get(link_id) properties = ResourceLinkProperties( - target_id if target_id is not None else params.properties.target_id, + target_id=target_id if target_id is not None else params.properties.target_id, # pylint: disable=no-member notes=notes if notes is not None else params.properties.notes) # pylint: disable=no-member links_client.create_or_update(link_id, properties) def list_resource_links(cmd, scope=None, filter_string=None): - """ - :param scope: The scope for the links - :type scope: str - :param filter_string: A filter for restricting the results - :type filter_string: str - """ links_client = _resource_links_client_factory(cmd.cli_ctx).resource_links if scope is not None: return links_client.list_at_source_scope(scope, filter=filter_string) return links_client.list_at_subscription(filter=filter_string) - # endregion +def rest_call(cmd, method, uri, headers=None, uri_parameters=None, + body=None, skip_authorization_header=False, resource=None, output_file=None): + from azure.cli.core.util import send_raw_request + r = send_raw_request(cmd.cli_ctx, method, uri, headers, uri_parameters, body, + skip_authorization_header, resource, output_file) + if not output_file and r.content: + try: + return r.json() + except ValueError: + logger.warning('Not a json response, outputing to stdout. For binary data ' + 'suggest use "--output-file" to write to a file') + print(r.text) + + class _ResourceUtils(object): # pylint: disable=too-many-instance-attributes def __init__(self, cli_ctx, resource_group_name=None, resource_provider_namespace=None, @@ -1919,6 +1917,7 @@ Formats Url if none provided and sends the POST request with the url and request-body. """ from msrestazure.azure_operation import AzureOperationPoller + query_parameters = {} serialize = self.rcf.resources._serialize # pylint: disable=protected-access client = self.rcf.resources._client # pylint: disable=protected-access @@ -1926,20 +1925,26 @@ url = '/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/' \ '{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}/{action}' - url = client.format_url( - url, - resourceGroupName=serialize.url( - "resource_group_name", self.resource_group_name, 'str', - max_length=90, min_length=1, pattern=r'^[-\w\._\(\)]+$'), - resourceProviderNamespace=serialize.url( - "resource_provider_namespace", self.resource_provider_namespace, 'str'), - parentResourcePath=serialize.url( - "parent_resource_path", self.parent_resource_path, 'str', skip_quote=True), - resourceType=serialize.url("resource_type", self.resource_type, 'str', skip_quote=True), - resourceName=serialize.url("resource_name", self.resource_name, 'str'), - subscriptionId=serialize.url( - "self.config.subscription_id", self.rcf.resources.config.subscription_id, 'str'), - action=serialize.url("action", action, 'str')) + if self.resource_id: + url = client.format_url( + '{resource_id}/{action}', + resource_id=self.resource_id, + action=serialize.url("action", action, 'str')) + else: + url = client.format_url( + url, + resourceGroupName=serialize.url( + "resource_group_name", self.resource_group_name, 'str', + max_length=90, min_length=1, pattern=r'^[-\w\._\(\)]+$'), + resourceProviderNamespace=serialize.url( + "resource_provider_namespace", self.resource_provider_namespace, 'str'), + parentResourcePath=serialize.url( + "parent_resource_path", self.parent_resource_path, 'str', skip_quote=True), + resourceType=serialize.url("resource_type", self.resource_type, 'str', skip_quote=True), + resourceName=serialize.url("resource_name", self.resource_name, 'str'), + subscriptionId=serialize.url( + "self.config.subscription_id", self.rcf.resources.config.subscription_id, 'str'), + action=serialize.url("action", action, 'str')) # Construct parameters query_parameters['api-version'] = serialize.query("api_version", self.api_version, 'str') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-resource-2.1.10/azure_cli_resource.egg-info/PKG-INFO new/azure-cli-resource-2.1.16/azure_cli_resource.egg-info/PKG-INFO --- old/azure-cli-resource-2.1.10/azure_cli_resource.egg-info/PKG-INFO 2019-02-12 03:05:56.000000000 +0100 +++ new/azure-cli-resource-2.1.16/azure_cli_resource.egg-info/PKG-INFO 2019-06-13 23:18:10.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: azure-cli-resource -Version: 2.1.10 +Version: 2.1.16 Summary: Microsoft Azure Command-Line Tools Resource Command Module Home-page: https://github.com/Azure/azure-cli Author: Microsoft Corporation @@ -19,9 +19,43 @@ Release History =============== + + 2.1.16 + ++++++ + * 'az rest': new command for making REST calls + * `policy assignment list`: Fix error when using a resource group or subscription level `--scope`. + + 2.1.15 + ++++++ + * `deployment create`: Improve error message when there is no TTY available + + 2.1.14 + ++++++ + * `resource link`: Deprecate `--link-id`, `--target-id` and `--filter-string` in favor of + `--link`, `--target`, and `--filter` respectively. + * `resource link create/update`: Fix issue where these commands would not work. + * `resource delete`: Fix issue where deleting using a resource ID could crash on error. + + 2.1.13 + ++++++ + * `deployment create`/`group deployment create`: Fixed issue where parameters file with an empty set of parameters would not work. + + 2.1.12 + ++++++ + * `deployment create/list/show`: improve table output + * `deployment create/validate`: fix issue where type secureObject was not recognized. + + 2.1.11 + ++++++ + * `deployment create`: Fix issue where type field was case-sensitive. + * `policy assignment create`: support uri based parameters file + * `policy set-definition update`: support uri based parameters and definitions files + * `policy definition update`: fix handling of parameters and rules files + * `resource show/update/delete/tag/invoke-action`: Fix issue where cross-subscription IDs did not properly honor the subscription ID. + 2.1.10 ++++++ - * Minor fixes + * Minor fixes. 2.1.9 +++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/azure-cli-resource-2.1.10/setup.py new/azure-cli-resource-2.1.16/setup.py --- old/azure-cli-resource-2.1.10/setup.py 2019-02-12 03:05:13.000000000 +0100 +++ new/azure-cli-resource-2.1.16/setup.py 2019-06-13 23:17:47.000000000 +0200 @@ -14,7 +14,7 @@ logger.warn("Wheel is not available, disabling bdist_wheel hook") cmdclass = {} -VERSION = "2.1.10" +VERSION = "2.1.16" CLASSIFIERS = [ 'Development Status :: 5 - Production/Stable',
