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

[Compute][Feature]az vm create: Support default data source settings for vm workspace #11704

Merged
Merged
Show file tree
Hide file tree
Changes from 7 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: 1 addition & 1 deletion src/azure-cli-testsdk/azure/cli/testsdk/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def create_random_name(self, prefix, length):
def create_guid(self):
import uuid
self.test_guid_count += 1
moniker = '88888888-0000-0000-0000-00000000' + ("%0.4X" % self.test_guid_count)
moniker = '88888888-0000-0000-0000-00000000' + ("%0.4x" % self.test_guid_count)

if self.in_recording:
name = uuid.uuid4()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ def cf_log_analytics(cli_ctx, subscription_id, *_):
return _log_analytics_client_factory(cli_ctx, subscription_id).workspaces


def cf_log_analytics_data_sources(cli_ctx, subscription_id, *_):
return _log_analytics_client_factory(cli_ctx, subscription_id).data_sources


def cf_log_analytics_data_plane(cli_ctx, _):
"""Initialize Log Analytics data client for use with CLI."""
from azure.loganalytics import LogAnalyticsDataClient
Expand Down
32 changes: 30 additions & 2 deletions src/azure-cli/azure/cli/command_modules/vm/_template_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ def build_av_set_resource(cmd, name, location, tags, platform_update_domain_coun


# used for log analytics workspace
def build_vm_mmaExtension_resource(_, vm_name, location):
def build_vm_linux_log_analytics_workspace_agent(_, vm_name, location):
mmyyrroonn marked this conversation as resolved.
Show resolved Hide resolved
mmaExtension_resource = {
'type': 'Microsoft.Compute/virtualMachines/extensions',
'apiVersion': '2018-10-01',
Expand All @@ -942,7 +942,7 @@ def build_vm_mmaExtension_resource(_, vm_name, location):


# used for log analytics workspace
def build_vm_daExtensionName_resource(_, vm_name, location):
def build_vm_daExtension_resource(_, vm_name, location):
daExtensionName_resource = {
'type': 'Microsoft.Compute/virtualMachines/extensions',
'apiVersion': '2018-10-01',
Expand All @@ -958,3 +958,31 @@ def build_vm_daExtensionName_resource(_, vm_name, location):
daExtensionName_resource['location'] = location
daExtensionName_resource['dependsOn'] = ['Microsoft.Compute/virtualMachines/{0}/extensions/OMSExtension'.format(vm_name)] # pylint: disable=line-too-long
return daExtensionName_resource


def build_vm_windows_log_analytics_workspace_agent(_, vm_name, location):
'''
This function is used for log analytics workspace.
'''
mmaExtension_resource = {
'type': 'Microsoft.Compute/virtualMachines/extensions',
'apiVersion': '2018-10-01',
'properties': {
'publisher': 'Microsoft.EnterpriseCloud.Monitoring',
'type': 'MicrosoftMonitoringAgent',
'typeHandlerVersion': '1.0',
'autoUpgradeMinorVersion': 'true',
'settings': {
'workspaceId': "[reference(parameters('workspaceId'), '2015-11-01-preview').customerId]",
'stopOnMultipleConnections': 'true'
},
'protectedSettings': {
'workspaceKey': "[listKeys(parameters('workspaceId'), '2015-11-01-preview').primarySharedKey]"
}
}
}

mmaExtension_resource['name'] = vm_name + '/MicrosoftMonitoringAgent'
mmaExtension_resource['location'] = location
mmaExtension_resource['dependsOn'] = ['Microsoft.Compute/virtualMachines/' + vm_name]
return mmaExtension_resource
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
from collections import OrderedDict

linux_performance_collection_properties = [
{
'state': 'Enabled'
}
]

linux_performance_object_properties = [
{
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "Memory",
"performanceCounters": [
{
"counterName": "Available MBytes Memory"
},
{
"counterName": "% Used Memory"
},
{
"counterName": "% Used Swap Space"
}
]
},
{
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "Processor",
"performanceCounters": [
{
"counterName": "% Processor Time"
},
{
"counterName": "% Privileged Time"
}
]
},
{
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "Logical Disk",
"performanceCounters": [
{
"counterName": "% Used Inodes"
},
{
"counterName": "Free Megabytes"
},
{
"counterName": "% Used Space"
},
{
"counterName": "Disk Transfers/sec"
},
{
"counterName": "Disk Reads/sec"
},
{
"counterName": "Disk Writes/sec"
}
]
},
{
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "Network",
"performanceCounters": [
{
"counterName": "Total Bytes Transmitted"
},
{
"counterName": "Total Bytes Received"
}
]
}
]

linux_syslog_collection_properties = [
{
'state': 'Enabled'
}
]

linux_syslog_properties = [
{
"syslogName": "syslog",
"syslogSeverities": [
{
"severity": "notice"
},
{
"severity": "info"
},
{
"severity": "debug"
}
]
}
]

windows_event_properties = [
{
"eventLogName": "System",
"eventTypes": [
{
"eventType": "Error"
},
{
"eventType": "Warning"
}
]
}
]

windows_performance_counter_properties = [
{
"collectorType": "Default",
"counterName": "Disk Transfers/sec",
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "LogicalDisk"
},
{
"collectorType": "Default",
"counterName": "Disk Reads/sec",
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "LogicalDisk"
},
{
"collectorType": "Default",
"counterName": "Bytes Total/sec",
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "Network Interface"
},
{
"collectorType": "Default",
"counterName": "Available MBytes",
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "Memory"
},
{
"collectorType": "Default",
"counterName": "% Free Space",
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "LogicalDisk"
},
{
"collectorType": "Default",
"counterName": "Avg. Disk sec/Write",
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "LogicalDisk"
},
{
"collectorType": "Default",
"counterName": "Bytes Received/sec",
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "Network Adapter"
},
{
"collectorType": "Default",
"counterName": "Current Disk Queue Length",
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "LogicalDisk"
},
{
"collectorType": "Default",
"counterName": "% Processor Time",
"instanceName": "_Total",
"intervalSeconds": 10,
"objectName": "Processor"
},
{
"collectorType": "Default",
"counterName": "Free Megabytes",
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "LogicalDisk"
},
{
"collectorType": "Default",
"counterName": "Avg. Disk sec/Read",
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "LogicalDisk"
},
{
"collectorType": "Default",
"counterName": "Bytes Sent/sec",
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "Network Adapter"
},
{
"collectorType": "Default",
"counterName": "% Committed Bytes In Use",
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "Memory"
},
{
"collectorType": "Default",
"counterName": "Disk Writes/sec",
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "LogicalDisk"
},
{
"collectorType": "Default",
"counterName": "Processor Queue Length",
"instanceName": "*",
"intervalSeconds": 10,
"objectName": "System"
}
]

default_linux_data_sources = OrderedDict()

default_linux_data_sources['LinuxPerformanceCollection'] = linux_performance_collection_properties
default_linux_data_sources['LinuxPerformanceObject'] = linux_performance_object_properties
default_linux_data_sources['LinuxSyslogCollection'] = linux_syslog_collection_properties
default_linux_data_sources['LinuxSyslog'] = linux_syslog_properties

default_windows_data_sources = OrderedDict()

default_windows_data_sources['WindowsEvent'] = windows_event_properties
default_windows_data_sources['WindowsPerformanceCounter'] = windows_performance_counter_properties
62 changes: 56 additions & 6 deletions src/azure-cli/azure/cli/command_modules/vm/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,8 +558,9 @@ def create_vm(cmd, vm_name, resource_group_name, image=None, size='Standard_DS1_
build_vnet_resource, build_nsg_resource,
build_public_ip_resource, StorageProfile,
build_msi_role_assignment,
build_vm_mmaExtension_resource,
build_vm_daExtensionName_resource)
build_vm_linux_log_analytics_workspace_agent,
build_vm_daExtension_resource,
build_vm_windows_log_analytics_workspace_agent)
from msrestazure.tools import resource_id, is_valid_resource_id

subscription_id = get_subscription_id(cmd.cli_ctx)
Expand Down Expand Up @@ -716,10 +717,16 @@ def create_vm(cmd, vm_name, resource_group_name, image=None, size='Standard_DS1_
if workspace is not None:
workspace_id = _prepare_workspace(cmd, resource_group_name, workspace)
master_template.add_secure_parameter('workspaceId', workspace_id)
vm_mmaExtension_resource = build_vm_mmaExtension_resource(cmd, vm_name, location)
vm_daExtensionName_resource = build_vm_daExtensionName_resource(cmd, vm_name, location)
master_template.add_resource(vm_mmaExtension_resource)
master_template.add_resource(vm_daExtensionName_resource)
if os_type.lower() == 'linux':
vm_mmaExtension_resource = build_vm_linux_log_analytics_workspace_agent(cmd, vm_name, location)
vm_daExtensionName_resource = build_vm_daExtension_resource(cmd, vm_name, location)
master_template.add_resource(vm_mmaExtension_resource)
master_template.add_resource(vm_daExtensionName_resource)
elif os_type.lower() == 'windows':
vm_mmaExtension_resource = build_vm_windows_log_analytics_workspace_agent(cmd, vm_name, location)
master_template.add_resource(vm_mmaExtension_resource)
else:
logger.warning("Unsupported OS type. Skip the connection step for log analytics workspace.")

master_template.add_resource(vm_resource)

Expand Down Expand Up @@ -753,6 +760,10 @@ def create_vm(cmd, vm_name, resource_group_name, image=None, size='Standard_DS1_
_show_missing_access_warning(resource_group_name, vm_name, 'vm')
setattr(vm, 'identity', _construct_identity_info(identity_scope, identity_role, vm.identity.principal_id,
vm.identity.user_assigned_identities))

if workspace is not None:
_set_data_source_for_workspace(cmd, os_type, resource_group_name, workspace_id)

return vm


Expand Down Expand Up @@ -1071,6 +1082,45 @@ def _prepare_workspace(cmd, resource_group_name, workspace):
else:
workspace_id = workspace
return workspace_id


def _set_data_source_for_workspace(cmd, os_type, resource_group_name, workspace_id):
from ._client_factory import cf_log_analytics_data_sources
from azure.cli.core.commands.client_factory import get_subscription_id
from azure.mgmt.loganalytics.models import DataSource
from msrestazure.tools import parse_resource_id
from msrestazure.azure_exceptions import CloudError

subscription_id = get_subscription_id(cmd.cli_ctx)
data_sources_client = cf_log_analytics_data_sources(cmd.cli_ctx, subscription_id)
workspace_name = parse_resource_id(workspace_id)['name']
data_source_name_template = "DataSource_{}_{}"

default_data_sources = None
if os_type.lower() == 'linux':
from ._workspace_data_source_settings import default_linux_data_sources
default_data_sources = default_linux_data_sources
elif os_type.lower() == 'windows':
from ._workspace_data_source_settings import default_windows_data_sources
default_data_sources = default_windows_data_sources

if default_data_sources is not None:
for data_source_kind, data_source_settings in default_data_sources.items():
for data_source_setting in data_source_settings:
data_source = DataSource(kind=data_source_kind,
properties=data_source_setting)
data_source_name = data_source_name_template.format(data_source_kind, _gen_guid())
try:
data_sources_client.create_or_update(resource_group_name,
workspace_name,
data_source_name,
data_source)
except CloudError as ex:
logger.warning("Failed to set data source due to {}. "
"Skip this step and need manual work later.".format(ex.message))
else:
logger.warning("Unsupported OS type. Skip the default settings for log analytics workspace.")

# endregion


Expand Down
Loading