diff --git a/src/index.json b/src/index.json index f9534f8fc5..0492c3c278 100644 --- a/src/index.json +++ b/src/index.json @@ -281,9 +281,9 @@ ], "webapp": [ { - "filename": "webapp-0.2.1-py2.py3-none-any.whl", - "sha256Digest": "fe3b28cc9cb2272a36c395ed6279b2a9f925b16877962bf2448a3fa56819bfa4", - "downloadUrl": "https://github.com/panchagnula/azure-cli-extensions/raw/sisirap-extensions-whl/dist/webapp-0.2.1-py2.py3-none-any.whl", + "filename": "webapp-0.2.2-py2.py3-none-any.whl", + "sha256Digest": "db8bdba11e6814ceeff37063d0e7548dab42f9e33a64b4c4a5b7ffea0bc93884", + "downloadUrl": "https://github.com/panchagnula/azure-cli-extensions/raw/sisirap-extensions-whl/dist/webapp-0.2.2-py2.py3-none-any.whl", "metadata": { "azext.isPreview": true, "azext.minCliCoreVersion": "2.0.24", @@ -322,7 +322,7 @@ "metadata_version": "2.0", "name": "webapp", "summary": "An Azure CLI Extension to manage appservice resources", - "version": "0.2.1" + "version": "0.2.2" } } ], diff --git a/src/webapp/azext_webapp/__init__.py b/src/webapp/azext_webapp/__init__.py index 5acbe9846b..468d7885dc 100644 --- a/src/webapp/azext_webapp/__init__.py +++ b/src/webapp/azext_webapp/__init__.py @@ -23,6 +23,8 @@ def __init__(self, cli_ctx=None): def load_command_table(self, _): with self.command_group('webapp') as g: g.custom_command('up', 'create_deploy_webapp') + g.custom_command('config snapshot list', 'list_webapp_snapshots') + g.custom_command('config snapshot restore', 'restore_webapp_snapshot') return self.command_table def load_arguments(self, _): @@ -31,6 +33,19 @@ def load_arguments(self, _): c.argument('dryrun', help="shows summary of the create and deploy operation instead of executing it", default=False, action='store_true') + with self.argument_context('webapp config snapshot list') as c: + c.argument('resource_group', options_list=['--resource-group', '-g'], help='Name of resource group.') + c.argument('name', options_list=['--webapp-name', '-n'], help='Name of the webapp.') + c.argument('slot', options_list=['--slot', '-s'], help='Name of the webapp slot.') + with self.argument_context('webapp config snapshot restore') as c: + c.argument('resource_group', options_list=['--resource-group', '-g'], help='Name of resource group to restore to.') + c.argument('name', options_list=['--webapp-name', '-n'], help='Name of the webapp to restore to.') + c.argument('time', options_list=['--time', '-t'], help='Timestamp of the snapshot to restore.') + c.argument('slot', options_list=['--slot', '-s'], help='Name of the webapp slot to restore to.') + c.argument('restore_config', options_list=['--restore-config'], help='Restore the previous configuration along with web app content.') + c.argument('source_resource_group', options_list=['--source-resource-group'], help='Name of the resource group to retrieve snapshot from.') + c.argument('source_name', options_list=['--source-webapp-name'], help='Name of the webapp to retrieve snapshot from.') + c.argument('source_slot', options_list=['--source-slot'], help='Name of the webapp slot to retrieve snapshot from.') COMMAND_LOADER_CLS = WebappExtCommandLoader diff --git a/src/webapp/azext_webapp/_help.py b/src/webapp/azext_webapp/_help.py index 2aa436e7cd..0d3a1d3e57 100644 --- a/src/webapp/azext_webapp/_help.py +++ b/src/webapp/azext_webapp/_help.py @@ -16,3 +16,26 @@ az webapp up -n MyUniqueAppName --dryrun \n az webapp up -n MyUniqueAppName -l locationName """ + +helps['webapp config snapshot list'] = """ + type: command + short-summary: List the snapshots available for a web app. + Snapshots are automatically managed backups of web app content and configuration. + examples: + - name: List the snapshots available for a web app named MyApp. + text: > + az webapp config snapshot list -g Default-Web-WestUS -n MyApp +""" + +helps['webapp config snapshot restore'] = """ + type: command + short-summary: Restore a snapshot to a web app. + A snapshot from a different web app or slot can be restored by specifying the source. + examples: + - name: Overwrite a web app with its own snapshot. + text: > + az webapp config snapshot restore -g Default-Web-WestUS -n MyApp -t 2018-04-25T00:09:20.8736381Z + - name: Overwrite a web app's staging slot with a snapshot from its production slot. + text: > + az webapp config snapshot restore -g Default-Web-WestUS -n MyApp -s staging -t 2018-04-25T00:09:20.8736381Z --source-resource-group Default-Web-WestUS --source-name MyApp --restore-config +""" diff --git a/src/webapp/azext_webapp/custom.py b/src/webapp/azext_webapp/custom.py index 34be7f65cf..3f076cbe59 100644 --- a/src/webapp/azext_webapp/custom.py +++ b/src/webapp/azext_webapp/custom.py @@ -5,8 +5,11 @@ from __future__ import print_function from knack.log import get_logger +from knack.util import CLIError -from azure.mgmt.web.models import (AppServicePlan, SkuDescription) +from azure.mgmt.web.models import (AppServicePlan, SkuDescription, SnapshotRecoveryRequest, SnapshotRecoveryTarget) + +from azure.cli.core.commands.client_factory import get_subscription_id from azure.cli.command_modules.appservice.custom import ( enable_zip_deploy, @@ -178,3 +181,35 @@ def create_deploy_webapp(cmd, name, location=None, dryrun=False): create_json.update({'app_url': url}) logger.warning("All done.") return create_json + + +def list_webapp_snapshots(cmd, resource_group, name, slot=None): + client = web_client_factory(cmd.cli_ctx) + if slot is None: + return client.web_apps.list_snapshots(resource_group, name) + else: + return client.web_apps.list_snapshots_slot(resource_group, name, slot) + + +def restore_webapp_snapshot(cmd, resource_group, name, time, slot=None, restore_config=False, source_resource_group=None, source_name=None, source_slot=None): + client = web_client_factory(cmd.cli_ctx) + + if all([source_resource_group, source_name]): + sub_id = get_subscription_id(cmd.cli_ctx) + target_id = "/subscriptions/" + sub_id + "/resourceGroups/" + resource_group + "/providers/Microsoft.Web/sites/" + name + if slot: + target_id = target_id + "/slots/" + slot + target = SnapshotRecoveryTarget(id=target_id) + request = SnapshotRecoveryRequest(False, snapshot_time=time, recovery_target=target, recover_configuration=restore_config) + if source_slot: + return client.web_apps.recover_slot(source_resource_group, source_name, request, source_slot) + else: + return client.web_apps.recover(source_resource_group, source_name, request) + elif any([source_resource_group, source_name]): + raise CLIError('usage error: --source-resource-group and --source-name must both be specified if one is used') + else: + request = SnapshotRecoveryRequest(True, snapshot_time=time, recover_configuration=restore_config) + if slot: + return client.web_apps.recover_slot(resource_group, name, request, slot) + else: + return client.web_apps.recover(resource_group, name, request) diff --git a/src/webapp/setup.py b/src/webapp/setup.py index 6dc1e9a56f..a5c94a56fb 100644 --- a/src/webapp/setup.py +++ b/src/webapp/setup.py @@ -8,7 +8,7 @@ from codecs import open from setuptools import setup, find_packages -VERSION = "0.2.1" +VERSION = "0.2.2" CLASSIFIERS = [ 'Development Status :: 4 - Beta',