Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,5 @@
/src/account/ @zikalino

/src/datashare/ @fengzhou-msft

/src/log-analytics-solution/ @zhoxing-ms
8 changes: 8 additions & 0 deletions src/log-analytics-solution/HISTORY.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.. :changelog:

Release History
===============

0.1.0
++++++
* Initial release.
57 changes: 57 additions & 0 deletions src/log-analytics-solution/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Azure CLI log-analytics-solution Extension #
This package is for the 'log-analytics-solution' extension, i.e. 'az monitor log-analytics solution'

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

### Included Features
#### Log Analytics Solution Management:
Manage Log Analytics Solution: [more info](https://docs.microsoft.com/en-us/azure/azure-monitor/insights/solutions) \
*Examples:*

##### Create a log-analytics solution for the plan product of OMSGallery/Containers
```
az monitor log-analytics solution create \
--resource-group MyResourceGroup \
--name Containers({SolutionName}) \
--location "East US" \
--plan-publisher Microsoft \
--plan-product "OMSGallery/Containers" \
--workspace-resource-id "/subscriptions/{SubID}/resourceGroups/{ResourceGroup}/providers/ \
Microsoft.OperationalInsights/workspaces/{WorkspaceName}" \
--tags key=value
```

##### Update a log-analytics solution
```
az monitor log-analytics solution update \
--resource-group MyResourceGroup \
--name SolutionName \
--tags key=value
```

##### Delete a log-analytics solution
```
az monitor log-analytics solution delete --resource-group MyResourceGroup --name SolutionName
```

##### Get details about the specified log-analytics solution
```
az monitor log-analytics solution show --resource-group MyResourceGroup --name SolutionName
```

##### List all of the log-analytics solutions in the specified subscription or resource group
```
az monitor log-analytics solution list
```
```
az monitor log-analytics solution list --subscription MySubscription
```
```
az monitor log-analytics solution list --resource-group MyResourceGroup
```

If you have issues, please give feedback by opening an issue at https://github.com/Azure/azure-cli-extensions/issues.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# --------------------------------------------------------------------------------------------
# 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_log_analytics_solution._help import helps # pylint: disable=unused-import


class LogAnalyticsSolutionCommandsLoader(AzCommandsLoader):

def __init__(self, cli_ctx=None):
from azure.cli.core.commands import CliCommandType
from azext_log_analytics_solution._client_factory import cf_log_analytics_solution
log_analytics_solution_custom = CliCommandType(
operations_tmpl='azext_log_analytics_solution.custom#{}',
client_factory=cf_log_analytics_solution)
super(LogAnalyticsSolutionCommandsLoader, self).__init__(cli_ctx=cli_ctx,
custom_command_type=log_analytics_solution_custom)

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

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


COMMAND_LOADER_CLS = LogAnalyticsSolutionCommandsLoader
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------


def cf_log_analytics_solution(cli_ctx, *_):
from azure.cli.core.commands.client_factory import get_mgmt_service_client
from .vendored_sdks.operationsmanagement import OperationsManagementClient
return get_mgmt_service_client(cli_ctx, OperationsManagementClient, provider_name="Microsoft.OperationsManagement",
resource_type="solutions", resource_name="")


def cf_solutions(cli_ctx, *_):
return cf_log_analytics_solution(cli_ctx, *_).solutions
71 changes: 71 additions & 0 deletions src/log-analytics-solution/azext_log_analytics_solution/_help.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# 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.
# --------------------------------------------------------------------------------------------

# pylint: disable=too-many-lines
# pylint: disable=line-too-long
from knack.help_files import helps # pylint: disable=unused-import


helps['monitor log-analytics solution'] = """
type: group
short-summary: Commands to manage monitor log-analytics solution.
"""
Comment on lines +12 to +15

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No need to indent the help. Ctrl+A to select all, then press Shift+Tab to remove the indentations.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Got it~


helps['monitor log-analytics solution create'] = """
type: command
short-summary: Create a log-analytics solution.
examples:
- name: Create a log-analytics solution for the plan product of OMSGallery/Containers
text: |-
az monitor log-analytics solution create --resource-group MyResourceGroup \\
--name Containers({SolutionName}) --location "East US" --tags key=value \\
--plan-publisher Microsoft --plan-product "OMSGallery/Containers" \\
--workspace-resource-id "/subscriptions/{SubID}/resourceGroups/{ResourceGroup}/providers/ \\
Microsoft.OperationalInsights/workspaces/{WorkspaceName}"
"""

helps['monitor log-analytics solution update'] = """
type: command
short-summary: Update an existing log-analytics solution.
examples:
- name: Update a log-analytics solution
text: |-
az monitor log-analytics solution update --resource-group MyResourceGroup \\
--name SolutionName --tags key=value
"""

helps['monitor log-analytics solution delete'] = """
type: command
short-summary: Delete a log-analytics solution.
examples:
- name: Delete a log-analytics solution
text: |-
az monitor log-analytics solution delete --resource-group MyResourceGroup --name SolutionName
"""

helps['monitor log-analytics solution show'] = """
type: command
short-summary: Get details about the specified log-analytics solution.
examples:
- name: Get a log-analytics solution
text: |-
az monitor log-analytics solution show --resource-group MyResourceGroup --name SolutionName
"""

helps['monitor log-analytics solution list'] = """
type: command
short-summary: List all of the log-analytics solutions in the specified subscription or resource group
examples:
- name: List all log-analytics solutions in the current subscription
text: |-
az monitor log-analytics solution list
- name: List all log-analytics solutions in a subscription
text: |-
az monitor log-analytics solution list --subscription MySubscription
- name: List all log-analytics solutions in a resource group
text: |-
az monitor log-analytics solution list --resource-group MyResourceGroup
"""
48 changes: 48 additions & 0 deletions src/log-analytics-solution/azext_log_analytics_solution/_params.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# --------------------------------------------------------------------------------------------
# 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
# pylint: disable=too-many-lines
# pylint: disable=too-many-statements

from azure.cli.core.commands.parameters import (
tags_type,
resource_group_name_type,
get_location_type
)
from azure.cli.core.commands.validators import get_default_location_from_resource_group
from ._validators import validate_workspace_resource_id
from knack.arguments import CLIArgumentType

solution_name = CLIArgumentType(options_list=['--name', '-n'],
help='Name of the log-analytics solution. For Microsoft published solution it '
'should be in the format of solutionType(workspaceName). SolutionType part is '
'case sensitive. For third party solution, it can be anything.')


def load_arguments(self, _):

with self.argument_context('monitor log-analytics solution create') as c:
c.argument('solution_name', solution_name)
c.argument('location', arg_type=get_location_type(self.cli_ctx),
validator=get_default_location_from_resource_group)
c.argument('tags', tags_type)
c.argument('plan_publisher', help='Publisher name of the plan for solution. For gallery solution, it is Microsoft.')
c.argument('plan_product', help='Product name of the plan for solution. '
'For Microsoft published gallery solution it should be in the format of OMSGallery/<solutionType>. This is case sensitive.')
c.argument('workspace_resource_id', options_list=['--workspace-resource-id', '-w'],

@jsntcy jsntcy Apr 26, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

please support workspace name as well #Closed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I mean use one argument "workspace" that supports both name and resource id as storage_account does.


In reply to: 415257345 [](ancestors = 415257345)

validator=validate_workspace_resource_id,
help='The resource ID of the log analytics workspace with which the solution will be linked.')
c.argument('workspace_name', options_list=['--workspace-name'],
help='The name of the log analytics workspace with which the solution will be linked.')

with self.argument_context('monitor log-analytics solution update') as c:
c.argument('solution_name', solution_name)
c.argument('tags', tags_type)

with self.argument_context('monitor log-analytics solution delete') as c:
c.argument('solution_name', solution_name)

with self.argument_context('monitor log-analytics solution show') as c:
c.argument('solution_name', solution_name)
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
from msrestazure.tools import is_valid_resource_id, parse_resource_id
from knack.util import CLIError
from azure.mgmt.loganalytics import LogAnalyticsManagementClient
from azure.cli.core.commands.client_factory import get_mgmt_service_client


def validate_workspace_resource_id(cmd, namespace):
if namespace.workspace_resource_id:
if not is_valid_resource_id(namespace.workspace_resource_id):
raise CLIError('usage error: --workspace-resource-id is invalid')

# Determine whether the workspace already exists
workspace_param = parse_resource_id(namespace.workspace_resource_id)
workspaces_client = get_mgmt_service_client(cmd.cli_ctx, LogAnalyticsManagementClient).workspaces
workspaces = workspaces_client.get(workspace_param['resource_group'], workspace_param['resource_name'])

if workspaces and namespace.location:
if workspaces.location != namespace.location:
raise CLIError('usage error: workspace and solution must be under the same location')

if namespace.workspace_resource_id is None and namespace.workspace_name is None:
raise CLIError('usage error: please specify only one of --workspace-resource-id and --workspace-name')

if namespace.workspace_resource_id and namespace.workspace_name:
raise CLIError('usage error: please specify only one of --workspace-resource-id and --workspace-name, not both')
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"azext.isExperimental": true,
"azext.minCliCoreVersion": "2.3.0"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# --------------------------------------------------------------------------------------------
# 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
# pylint: disable=too-many-lines
# pylint: disable=too-many-statements
# pylint: disable=too-many-locals
from azure.cli.core.commands import CliCommandType
from ._client_factory import cf_solutions


def load_command_table(self, _):

log_analytics_solution_solutions = CliCommandType(
operations_tmpl='azext_log_analytics_solution.vendored_sdks.operationsmanagement.operations._solutions_operations#SolutionsOperations.{}',
client_factory=cf_solutions)

with self.command_group('monitor log-analytics solution', log_analytics_solution_solutions,
client_factory=cf_solutions, is_experimental=True) as g:
g.custom_command('create', 'create_monitor_log_analytics_solution', supports_no_wait=True)
g.custom_command('update', 'update_monitor_log_analytics_solution', supports_no_wait=True)
g.custom_command('delete', 'delete_monitor_log_analytics_solution', supports_no_wait=True, confirmation=True)
g.custom_show_command('show', 'get_monitor_log_analytics_solution')
g.custom_command('list', 'list_monitor_log_analytics_solution')
71 changes: 71 additions & 0 deletions src/log-analytics-solution/azext_log_analytics_solution/custom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# --------------------------------------------------------------------------------------------
# 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
# pylint: disable=too-many-statements
# pylint: disable=too-many-lines
# pylint: disable=too-many-locals
# pylint: disable=unused-argument

from azure.cli.core.commands.client_factory import get_subscription_id


def create_monitor_log_analytics_solution(cmd,
client,
resource_group_name,
solution_name,
plan_publisher,
plan_product,
location=None,
workspace_resource_id=None,
workspace_name=None,
tags=None):
if workspace_name:
reference_workspace = '/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.OperationalInsights/' \
'workspaces/{2}'.format(get_subscription_id(cmd.cli_ctx), resource_group_name,
workspace_name)
else:
reference_workspace = workspace_resource_id

body = {
'location': location,
'tags': tags,
'properties': {
"workspace_resource_id": reference_workspace
},
"plan": {
"name": solution_name,
"product": plan_product,
"publisher": plan_publisher,
"promotion_code": ""
}
}

return client.create_or_update(resource_group_name=resource_group_name, solution_name=solution_name, parameters=body)

@jsntcy jsntcy Apr 29, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

wrap with "sdk_no_wait", like "return sdk_no_wait(no_wait, client.create_or_update, resource_group_name, cluster_name, cluster_instance)". Please also update other commands that support no wait. #Closed



def update_monitor_log_analytics_solution(client,
resource_group_name,
solution_name,
tags=None):

return client.update(resource_group_name=resource_group_name, solution_name=solution_name, tags=tags)


def delete_monitor_log_analytics_solution(client,
resource_group_name,
solution_name):
return client.delete(resource_group_name=resource_group_name, solution_name=solution_name)


def get_monitor_log_analytics_solution(client,
resource_group_name,
solution_name):
return client.get(resource_group_name=resource_group_name, solution_name=solution_name)


def list_monitor_log_analytics_solution(client, resource_group_name=None):
if resource_group_name:
return client.list_by_resource_group(resource_group_name=resource_group_name)
return client.list_by_subscription()
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
Loading