Skip to content

Commit

Permalink
[amg]: backup, restore and sync command (#5976)
Browse files Browse the repository at this point in the history
* Support sync, backup, and restore

* add release notes

* bug fixes: better output and support folder inclusion

* add include, exclude, and more output polishing

* simplify phase1

* consolidate and add test

* add a e2e test

* fix all lint errors

* rerun all tests

* clean up temp dir created by the test

* update all tests for wor with track 2

* revert local hack

* update recording

* fix command linter error

* fix command linter error

* fix the cmd lint error

* fix info message of default role assignments

* accept 412 on folder restoration

* ensure old CLI with RBAC track-1 sdk can also work
  • Loading branch information
yugangw-msft committed Mar 15, 2023
1 parent 25ab130 commit d0322dc
Show file tree
Hide file tree
Showing 16 changed files with 13,676 additions and 1,770 deletions.
5 changes: 5 additions & 0 deletions src/amg/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,8 @@ Release History
++++++
* `az grafana update`: support email through new SMTP configuration arguments

1.2
+++++
* `az grafana backup`: backup a grafana workspace
* `az grafana restore`: restore a grafana workspace
* `az grafana dashboard sync`: sync dashboard between 2 grafana workspaces
4 changes: 2 additions & 2 deletions src/amg/azext_amg/_client_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
# --------------------------------------------------------------------------------------------


def cf_amg(cli_ctx, *_):
def cf_amg(cli_ctx, subscription, *_):
# pylint: disable=unused-argument
from azure.cli.core.commands.client_factory import get_mgmt_service_client
from azext_amg.vendored_sdks import DashboardManagementClient
return get_mgmt_service_client(cli_ctx, DashboardManagementClient)
return get_mgmt_service_client(cli_ctx, DashboardManagementClient, subscription_id=subscription)
22 changes: 22 additions & 0 deletions src/amg/azext_amg/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@
short-summary: Show details of a Azure Managed Grafana instance.
"""

helps['grafana backup'] = """
type: command
short-summary: Backup an Azure Managed Grafana instance's content to an achive.
"""

helps['grafana restore'] = """
type: command
short-summary: Restore an Azure Managed Grafana instance from an achive.
"""

helps['grafana update'] = """
type: command
short-summary: Update a Azure Managed Grafana instance.
Expand Down Expand Up @@ -219,6 +229,18 @@
az grafana dashboard delete -g MyResourceGroup -n MyGrafana --dashboard VdrOA7jGz
"""

helps['grafana dashboard sync'] = """
type: command
short-summary: Sync Azure Managed Grafana dashboards from one instance to another instance. Note, dashboards with "provisioned" state will be skipped due to being read-only
examples:
- name: Sync only dashboardss under a few folders
text: |
az grafana dashboard sync --source /subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/workspaces/providers/Microsoft.Dashboard/grafana/source --destination /subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/workspaces/providers/Microsoft.Dashboard/grafana/destination --folders-to-include "Azure Monitor Container Insights" "Azure Monitor"
- name: Preview the sync
text: |
az grafana dashboard sync --source /subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/workspaces/providers/Microsoft.Dashboard/grafana/source --destination /subscriptions/00000000-1111-2222-3333-444444444444/resourceGroups/workspaces/providers/Microsoft.Dashboard/grafana/destination --dry-run
"""

helps['grafana folder'] = """
type: group
short-summary: Commands to manage folders of an instance.
Expand Down
20 changes: 20 additions & 0 deletions src/amg/azext_amg/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,18 @@ def load_arguments(self, _):
c.argument("folder", help="id, uid, title which can identify a folder. CLI will search in the order of id, uid, and title, till finds a match")
c.argument("api_key_or_token", options_list=["--api-key", "--token", '-t'],
help="api key or service account token, a randomly generated string used to interact with Grafana endpoint; if missing, CLI will use logon user's credentials")
c.argument("components", get_enum_type(["dashboards", "datasources", "folders", "snapshots", "annotations"]), nargs='+', options_list=["-c", "--components"], help="grafana artifact types to backup")
c.argument("folders_to_include", nargs='+', options_list=["-i", "--folders-to-include"], help="folders to include in backup or sync")
c.argument("folders_to_exclude", nargs='+', options_list=["-e", "--folders-to-exclude"], help="folders to exclude in backup or sync")
c.ignore("subscription") # a help argument

with self.argument_context("grafana create") as c:
c.argument("grafana_name", grafana_name_type, options_list=["--name", "-n"], validator=None)
c.argument("zone_redundancy", arg_type=get_enum_type(ZoneRedundancy), help="Indicates whether or not zone redundancy should be enabled. Default: Disabled")
c.argument("skip_system_assigned_identity", options_list=["-s", "--skip-system-assigned-identity"], arg_type=get_three_state_flag(), help="Do not enable system assigned identity")
c.argument("skip_role_assignments", arg_type=get_three_state_flag(), help="Do not create role assignments for managed identity and the current login user")
c.argument("principal_ids", nargs="+", help="space-separated Azure AD object ids for users, groups, etc to be made as Grafana Admins. Once provided, CLI won't make the current logon user as Grafana Admin")
c.argument("principal_types", get_enum_type(["User", "Group", "ServicePrincipal"]), nargs="+", help="space-separated Azure AD principal types to pair with --principal-ids")

with self.argument_context("grafana update") as c:
c.argument("api_key_and_service_account", get_enum_type(["Enabled", "Disabled"]), options_list=['--api-key', '--service-account'],
Expand All @@ -51,6 +56,12 @@ def load_arguments(self, _):
c.argument("start_tls_policy", get_enum_type(["OpportunisticStartTLS", "MandatoryStartTLS", "NoStartTLS"]), arg_group='SMTP', help="TLS policy")
c.argument("skip_verify", arg_group='SMTP', arg_type=get_three_state_flag(), help="Skip verifying SSL for SMTP server")

with self.argument_context("grafana backup") as c:
c.argument("directory", options_list=["-d", "--directory"], help="directory to backup Grafana artifacts")

with self.argument_context("grafana restore") as c:
c.argument("archive_file", options_list=["-a", "--archive-file"], help="archive to restore Grafana artifacts from")

with self.argument_context("grafana dashboard") as c:
c.argument("uid", options_list=["--dashboard"], help="dashboard uid")
c.argument("title", help="title of a dashboard")
Expand All @@ -65,6 +76,15 @@ def load_arguments(self, _):
with self.argument_context("grafana dashboard import") as c:
c.argument("definition", help="The complete dashboard model in json string, Grafana gallery id, a path or url to a file with such content")

with self.argument_context("grafana dashboard delete") as c:
c.ignore("ignore_error")

with self.argument_context("grafana dashboard sync") as c:
c.argument("source", options_list=["--source", "-s"], help="resource id of the source workspace")
c.argument("destination", options_list=["--destination", "-d"], help="resource id of the destination workspace")
c.argument("dry_run", arg_type=get_three_state_flag(), help="preview changes w/o committing")
c.argument("folders", nargs="+", help="space separated folder list which sync command shall handle dashboards underneath")

with self.argument_context("grafana") as c:
c.argument("time_to_live", default="1d", help="The life duration. For example, 1d if your key is going to last fr one day. Supported units are: s,m,h,d,w,M,y")

Expand Down
Loading

0 comments on commit d0322dc

Please sign in to comment.