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

Onboard command extension for Azure Managed Grafana service #4495

Merged
merged 36 commits into from
Mar 22, 2022
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
0d142ab
POC: update with command list to implement
yugangw-msft Jan 7, 2022
86a327c
consolidate control plane and dashboard commands
yugangw-msft Jan 8, 2022
f6f0398
half done: make resource group and location optional
yugangw-msft Jan 9, 2022
9f1d64a
more commands and code style fixes
yugangw-msft Jan 15, 2022
118d7c1
add a validator to workspace https://bugs.python.org/issue9334
yugangw-msft Jan 16, 2022
efb83c6
catch up a few TODOs
yugangw-msft Jan 16, 2022
a0e4c6c
Consolidate data source CRUD commands with bug fixes and samples
yugangw-msft Jan 17, 2022
00776b1
add help
yugangw-msft Jan 17, 2022
bff5d4e
bug fixes on data source commands
yugangw-msft Jan 19, 2022
8ea48c2
fix style errors
yugangw-msft Jan 22, 2022
055a128
fix bugs in data-source commands
yugangw-msft Jan 23, 2022
542bc1a
clean up command help
yugangw-msft Jan 23, 2022
fc77db4
upload whl file for tempoaray measures, before we publish it officially
yugangw-msft Jan 24, 2022
5b896a9
update readme and bug fixes
yugangw-msft Jan 24, 2022
ef61108
update get_start doc
yugangw-msft Jan 27, 2022
3cfa442
Update get_start,md
yugangw-msft Jan 25, 2022
22ecfcd
fix typos in get_start.md
yugangw-msft Jan 27, 2022
fa4679e
add vendor SDK
yugangw-msft Mar 5, 2022
3ccce00
new extension
yugangw-msft Mar 5, 2022
7e605bb
new extension built from azdev
yugangw-msft Mar 5, 2022
a439200
rename from ags to amg
yugangw-msft Mar 6, 2022
c2eda5d
add tag support
yugangw-msft Mar 6, 2022
4c97ebd
Update readme.rst
yugangw-msft Mar 6, 2022
4586d2d
undo non related changes
yugangw-msft Mar 6, 2022
f168b98
rename readme to markdown
yugangw-msft Mar 6, 2022
73a4e15
address lint error
yugangw-msft Mar 8, 2022
8b58a18
address linter error
yugangw-msft Mar 8, 2022
db45158
more fix towards command lint error
yugangw-msft Mar 8, 2022
e4d5a62
register the command module in a few common file
yugangw-msft Mar 8, 2022
5c501d8
add import
yugangw-msft Mar 11, 2022
cf46859
support gallery import
yugangw-msft Mar 12, 2022
4242517
use deep copy
yugangw-msft Mar 12, 2022
1a30dc7
address review feedback
yugangw-msft Mar 13, 2022
aa7b87e
set the minimum cli core version
yugangw-msft Mar 18, 2022
c5f3832
fix a bug in 'az grafana user show'
yugangw-msft Mar 19, 2022
8f1c5a1
Remove the 'id' on creating dashboard to prevent 'Not Found' error
yugangw-msft Mar 22, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@

/src/datamigration/ @ashutoshsuman99

/src/amg/ @yugangw-msft

/src/confidentialledger/ @kairu-ms @lynshi

/src/quota/ @kairu-ms @ZengTaoxu
/src/quota/ @kairu-ms @ZengTaoxu
8 changes: 8 additions & 0 deletions src/amg/HISTORY.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.. :changelog:
Release History
===============

0.1.0
++++++
* Initial release.
55 changes: 55 additions & 0 deletions src/amg/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Microsoft Azure CLI 'amg' Extension
This is an extension to manage Azure Manaaged Grafana instances

## How to use ##
Install this extension using the below CLI command
```
az extension add --name amg
```

## Included Features
### Create, show, and delete instances

#### create an instance
*Examples:*
```
az grafana create \
-g MyResourceGroup \
-n MyGrafanaInstance \
--tags department=financial
```

#### delete an instance
*Examples:*
```
az grafana delete \
-n MyGrafanaInstance
```

### Configure folder, data sources and dashboard

#### create a folder
*Examples:*
```
az grafana folder create \
-n MyGrafanaInstance \
--title "Health KPI"
```

#### configure a data source
*Examples:*
```
az grafana data-source create \
-n MyGrafanaInstance \
--definition ~/data-source-sql.json
```

#### Create a dashboard
*Examples:*
```
az grafana dashboard create \
-n MyGrafanaInstance \
--folder "Health KPI" \
--title "SQL status" \
--definition ~/dashboard-sql.json
```
31 changes: 31 additions & 0 deletions src/amg/azext_amg/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from azure.cli.core import AzCommandsLoader

from azext_amg._help import helps # pylint: disable=unused-import


class AmgCommandsLoader(AzCommandsLoader):

def __init__(self, cli_ctx=None):
from azure.cli.core.commands import CliCommandType
amg_custom = CliCommandType(
operations_tmpl='azext_amg.custom#{}')
# pylint: disable=super-with-arguments
super(AmgCommandsLoader, self).__init__(cli_ctx=cli_ctx,
custom_command_type=amg_custom)

def load_command_table(self, args):
from azext_amg.commands import load_command_table
load_command_table(self, args)
return self.command_table

def load_arguments(self, command):
from azext_amg._params import load_arguments
load_arguments(self, command)


COMMAND_LOADER_CLS = AmgCommandsLoader
11 changes: 11 additions & 0 deletions src/amg/azext_amg/_client_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------


def cf_amg(cli_ctx, *_):
# 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)
199 changes: 199 additions & 0 deletions src/amg/azext_amg/_help.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
# coding=utf-8
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from knack.help_files import helps # pylint: disable=unused-import


helps['grafana'] = """
type: group
short-summary: Commands to manage Azure Grafana instanced.
long-summary: For optimized experience, not all data plane Apis, documented at https://grafana.com/docs/grafana/latest/http_api/, are exposed. On coverage gap, please reach out to ad4g@microsoft.com
"""

helps['grafana create'] = """
type: command
short-summary: Create a Azure Managed Grafana instance.
"""

helps['grafana list'] = """
type: command
short-summary: List Azure Managed Grafana instances.
"""

helps['grafana delete'] = """
type: command
short-summary: Delete a Azure Managed Grafana instance.
"""

helps['grafana show'] = """
type: command
short-summary: Show details of a Azure Managed Grafana instance.
"""

helps['grafana data-source'] = """
type: group
short-summary: Commands to manage data sources of an instance.
"""

helps['grafana data-source create'] = """
type: command
short-summary: Create a data source.
examples:
- name: create a data source of Azure SQL
text: |
az grafana data-source create -n MyGrafana --definition '{
"access": "proxy",
"database": "testdb",
"jsonData": {
"authenticationType": "SQL Server Authentication",
"encrypt": "false"
},
"secureJsonData": {
"password": "verySecretPassword"
},
"name": "Microsoft SQL Server",
"type": "mssql",
"url": "testsql.database.windows.net",
"user": "admin1"
}'
"""


helps['grafana data-source update'] = """
type: command
short-summary: Update a data source.
"""

helps['grafana data-source show'] = """
type: command
short-summary: get details of a data source
"""

helps['grafana data-source delete'] = """
type: command
short-summary: delete a data source
"""

helps['grafana data-source list'] = """
type: command
short-summary: List all data sources of an instance.
"""

helps['grafana data-source query'] = """
type: command
short-summary: query a data source having backend implementation
"""

helps['grafana dashboard'] = """
type: group
short-summary: Commands to manage dashboards of an instance.
"""

helps['grafana dashboard create'] = """
type: command
short-summary: Create a new dashboard.
examples:
- name: Create a dashboard with definition in a json file. For quick start, clone from the output of "az grafana dashboard show", remove "id" and "uid", and apply changes.
text: |
az grafana dashboard create -g MyResourceGroup -n MyGrafana --title "My dashboard" --folder folder1 --definition '{
"dashboard": {
"annotations": {
...
},
"panels": {
...
}
},
"message": "Create a new test dashboard"
}'
"""

helps['grafana dashboard update'] = """
type: command
short-summary: Update a dashboard.
examples:
- name: Update a dashboard with definition in a json file. For quick start, get existing configuration from "az grafana dashboard show", and apply changes.
"version" field need to be updated, and "overwrite" field should be true.
text: |
az grafana dashboard update -g MyResourceGroup -n MyGrafana --definition @c:\\temp\\dashboard.json
"""

helps['grafana dashboard list'] = """
type: command
short-summary: List all dashboards of an instance.
examples:
- name: Find the dashboard for K8s API Server and retrieve the unique identifier(in order to invoke "az grafana dashboard show" command)
text: |
az grafana dashboard list -g MyResourceGroup -n MyGrafana --query "[?contains(@.title, 'API server')].uid"
"""

helps['grafana dashboard show'] = """
type: command
short-summary: show the detail of a dashboard.
examples:
- name: Get details of a dashboard specified by an unique identifier(use "az grafana dashboard list" command to retrieve the uid)
text: |
az grafana dashboard show -g MyResourceGroup -n MyGrafana --dashboard VdrOA7jGz
"""

helps['grafana dashboard delete'] = """
type: command
short-summary: delete a dashboard
examples:
- name: Delete a dashboard specified by an unique identifier(use "az grafana dashboard list" command to retrieve the uid)
text: |
az grafana dashboard delete -g MyResourceGroup -n MyGrafana --dashboard VdrOA7jGz
"""

helps['grafana folder'] = """
type: group
short-summary: Commands to manage folders of an instance.
"""

helps['grafana folder create'] = """
type: command
short-summary: create a new folder.
"""

helps['grafana folder show'] = """
type: command
short-summary: show the details of a folder.
"""

helps['grafana folder list'] = """
type: command
short-summary: list all folders of an instance.
"""

helps['grafana folder update'] = """
type: command
short-summary: update a folder.
"""

helps['grafana folder delete'] = """
type: command
short-summary: delete a folder.
"""

helps['grafana user'] = """
type: group
short-summary: Commands to manage users of an instance.
"""

helps['grafana user actual-user'] = """
type: command
short-summary: show details of current user.
"""

helps['grafana user list'] = """
type: command
short-summary: list users.
"""

helps['grafana user show'] = """
type: command
short-summary: show detail of a user.
"""
57 changes: 57 additions & 0 deletions src/amg/azext_amg/_params.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
# pylint: disable=line-too-long


def load_arguments(self, _):

from knack.arguments import CLIArgumentType
from azure.cli.core.commands.parameters import tags_type, get_three_state_flag
from azure.cli.core.commands.validators import get_default_location_from_resource_group
from ._validators import process_missing_resource_group_parameter

grafana_name_type = CLIArgumentType(options_list="--grafana-name",
help="Name of the Azure Managed Dashboard for Grafana.",
id_part="name")

with self.argument_context("grafana") as c:
c.argument("tags", tags_type)
c.argument("location", validator=get_default_location_from_resource_group)
c.argument("grafana_name", grafana_name_type, options_list=["--name", "-n"], id_part=None, validator=process_missing_resource_group_parameter)
c.argument("id", help=("The identifier (id) of a dashboard/data source is an auto-incrementing "
"numeric value and is only unique per Grafana install."))
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")

with self.argument_context("grafana create") as c:
c.argument("grafana_name", grafana_name_type, options_list=["--name", "-n"], validator=None)
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")

with self.argument_context("grafana delete") as c:
c.argument('yes', options_list=['--yes', '-y'], help='Do not prompt for confirmation.', action='store_true')
yugangw-msft marked this conversation as resolved.
Show resolved Hide resolved

with self.argument_context("grafana dashboard") as c:
c.argument("uid", options_list=["--dashboard"], help="dashboard uid")
c.argument("definition", help="The complete dashboard model in json string, a file path/url or Grafana gallery id")
c.argument("title", help="title of a dashboard")
c.argument('overwrite', arg_type=get_three_state_flag(), help='Overwrite a dashboard with same uid')

with self.argument_context("grafana data-source") as c:
c.argument("data_source", help="name, id, uid which can identify a data source. CLI will search in the order of name, id, and uid, till finds a match")
c.argument("definition", help="json string with data source definition, or a path to a file with such content")

with self.argument_context("grafana data-source query") as c:
c.argument("conditions", nargs="+", help="space-separated condition in a format of `<name>=<value>`")
c.argument("time_from", options_list=["--from"], help="start time in iso 8601, e.g. '2022-01-02T16:15:00'. Default: 1 hour early")
c.argument("time_to", options_list=["--to"], help="end time in iso 8601, e.g. '2022-01-02T17:15:00'. Default: current time ")
c.argument("max_data_points", help="Maximum amount of data points that dashboard panel can render")
c.argument("query_format", help="format of the resule, e.g. table, time_series")
c.argument("internal_ms", help="The time interval in milliseconds of time series")

with self.argument_context("grafana folder") as c:
c.argument("title", help="title of the folder")

with self.argument_context("grafana user") as c:
c.argument("user", help="user login name or email")
Loading