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

App Insights control plane #600

Merged
merged 39 commits into from
Apr 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
34bfb19
feat: add update command, new help info
alexeldeib Mar 25, 2019
0041ebd
fix: lint whitespace
alexeldeib Mar 25, 2019
83556f6
fix: E302 new lines linting
alexeldeib Mar 25, 2019
974b3c5
fix: summary and hash
alexeldeib Mar 25, 2019
2a0c898
fix: help and unused args
alexeldeib Mar 25, 2019
26e63be
fix: update help for linting
alexeldeib Mar 25, 2019
29a140a
fix: sha
alexeldeib Mar 25, 2019
3272003
fix: sha
alexeldeib Mar 25, 2019
06d44a7
fix: remove colon to make CI happy
alexeldeib Mar 25, 2019
8ddc243
fix: one more lint removal
alexeldeib Mar 25, 2019
67bf1cc
fix: sha
alexeldeib Mar 25, 2019
2f1fc80
fix: extra param in help for apikey
alexeldeib Mar 26, 2019
db16e4c
fix: api key create
alexeldeib Mar 26, 2019
3a621fb
fix: api_key_name -> api_key
alexeldeib Mar 26, 2019
f95ab9d
fix: api_key_name -> api_key again
alexeldeib Mar 26, 2019
77e6b77
fix: sha
alexeldeib Mar 26, 2019
c261d1b
fix: params
alexeldeib Mar 26, 2019
d68333e
fix: remove colon
alexeldeib Mar 26, 2019
9bea1fe
fix: sha
alexeldeib Mar 26, 2019
bda9fae
fix: args
alexeldeib Mar 26, 2019
a62dc68
fix: --kind
alexeldeib Mar 26, 2019
e04f533
fix: undo help
alexeldeib Mar 26, 2019
4b0dc14
fix: short option on flag
alexeldeib Apr 4, 2019
a219a4f
fix: hashs
alexeldeib Apr 4, 2019
4036358
fix: flag example?
alexeldeib Apr 4, 2019
89cc49a
fix: hash and flag
alexeldeib Apr 4, 2019
cc11393
fix: minor features and tests
alexeldeib Apr 5, 2019
194343f
fix: hash
alexeldeib Apr 5, 2019
8cc8da2
fix: hash and spaces
alexeldeib Apr 5, 2019
c757ce7
fix: ci errors
alexeldeib Apr 6, 2019
0bad6b7
fix: missed on dangerous arg
alexeldeib Apr 6, 2019
b35934d
fix: help
alexeldeib Apr 6, 2019
a2172ab
fix: flake8
alexeldeib Apr 6, 2019
f4fc416
fix: blank line
alexeldeib Apr 6, 2019
49aed9e
fix: sha?
alexeldeib Apr 6, 2019
13bea65
fix: revert bad digests
alexeldeib Apr 6, 2019
7ea3228
fix: not empty list doesn't work?
alexeldeib Apr 6, 2019
76f8dea
fix: sha after rebase
alexeldeib Apr 16, 2019
90ba93b
fix: wrong sha
alexeldeib Apr 16, 2019
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
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,7 @@ def cf_events(cli_ctx, _, subscription=None):

def cf_components(cli_ctx, _, subscription=None):
return applicationinsights_mgmt_plane_client(cli_ctx, _, subscription=subscription).components


def cf_api_key(cli_ctx, _, subscription=None):
return applicationinsights_mgmt_plane_client(cli_ctx, _, subscription=subscription).api_keys
146 changes: 146 additions & 0 deletions src/application-insights/azext_applicationinsights/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,126 @@
provided, then --offset will be ignored.
"""

helps['monitor app-insights component'] = """
type: group
short-summary: Manage an Application Insights component or its subcomponents.
"""

helps['monitor app-insights component create'] = """
type: command
short-summary: Create a new Application Insights resource.
parameters:
- name: --application-type
type: string
short-summary: Type of application being monitored. Possible values include 'web', 'other'. Default value is'web' .
alexeldeib marked this conversation as resolved.
Show resolved Hide resolved
- name: --kind -k
type: string
short-summary: The kind of application that this component refers to, used to customize UI. This value is a freeform string, values should typically be one of web, ios, other, store, java, phone.
examples:
- name: Create a component with kind web and location.
text: |
az monitor app-insights component create --app demoApp --location westus2 --kind web -g demoRg --application-type web
"""

helps['monitor app-insights component update'] = """
type: command
short-summary: Update properties on an existing Application Insights resource. The primary value which can be updated is kind, which customizes the UI experience.
parameters:
- name: --kind -k
type: string
short-summary: The kind of application that this component refers to, used to customize UI. This value is a freeform string, values should typically be one of web, ios, other, store, java, phone.
examples:
- name: Update a component with kind web.
text: |
az monitor app-insights component update --app demoApp -k web -g demoRg
"""

helps['monitor app-insights component update-tags'] = """
type: command
short-summary: Update tags on an existing Application Insights resource.
examples:
- name: Update the tag 'name' to equal 'value'.
text: |
az monitor app-insights component update-tags --app demoApp --tags name=value -g demoRg
"""

helps['monitor app-insights component show'] = """
alexeldeib marked this conversation as resolved.
Show resolved Hide resolved
type: command
short-summary: Get an Application Insights resource.
examples:
- name: Get a component by name.
text: |
az monitor app-insights component show --app demoApp -g demoRg
- name: List components in a resource group.
text: |
az monitor app-insights component show -g demoRg
- name: List components in the currently selected subscription.
text: |
az monitor app-insights component show
"""

helps['monitor app-insights component delete'] = """
type: command
short-summary: Create a new Application Insights resource.
examples:
- name: Create a component with kind web and location.
alexeldeib marked this conversation as resolved.
Show resolved Hide resolved
text: |
az monitor app-insights component delete --app demoApp -g demoRg
"""

helps['monitor app-insights api-key'] = """
type: group
short-summary: Operations on API keys associated with an Application Insights component.
"""

helps['monitor app-insights api-key show'] = """
alexeldeib marked this conversation as resolved.
Show resolved Hide resolved
type: command
short-summary: Get all keys or a specific API key associated with an Application Insights resource.
parameters:
- name: --api-key
type: string
short-summary: name of the API key to fetch. Can be found using `api-keys show`.
examples:
- name: Fetch API Key.
text: |
az monitor app-insights api-key show --app demoApp -g demoRg --api-key demo-key
- name: Fetch API Keys.
text: |
az monitor app-insights api-key show --app demoApp -g demoRg
"""

helps['monitor app-insights api-key delete'] = """
type: command
short-summary: Delete an API key from an Application Insights resource.
parameters:
- name: --api-key
type: string
short-summary: Name of the API key to delete. Can be found using `api-keys show`.
examples:
- name: Delete API Key.
text: |
az monitor app-insights api-key delete --app demoApp -g demoRg --api-key demo-key
"""

helps['monitor app-insights api-key create'] = """
type: command
short-summary: Create a new API key for use with an Application Insights resource.
parameters:
- name: --api-key
type: string
short-summary: Name of the API key to create.
- name: --read-properties
type: list
short-summary: A space seperated list of names of read Roles for this API key to inherit. Possible values include ReadTelemetry and AuthenticateSDKControlChannel.
- name: --write-properties
type: list
short-summary: A space seperated list of names of write Roles for this API key to inherit. Possible values include WriteAnnotations.
examples:
- name: Create a component with kind web and location.
text: |
az monitor app-insights api-key create --api-key cli-demo --read-properties ReadTelemetry -g demoRg --app testApp
"""

helps['monitor app-insights metrics'] = """
type: group
short-summary: Retrieve metrics from an application.
Expand All @@ -34,6 +154,15 @@
helps['monitor app-insights query'] = """
type: command
short-summary: Execute a query over data in your application.
parameters:
- name: --offset
short-summary: >
Time offset of the query range, in ##d##h format.
long-summary: >
Can be used with either --start-time or --end-time. If used with --start-time, then
the end time will be calculated by adding the offset. If used with --end-time (default), then
the start time will be calculated by subtracting the offset. If --start-time and --end-time are
provided, then --offset will be ignored.
examples:
- name: Execute a simple query over past 3.5 days.
text: |
Expand All @@ -47,6 +176,14 @@
- name: --interval
short-summary: >
The interval over which to aggregate metrics, in ##h##m format.
- name: --offset
short-summary: >
Time offset of the query range, in ##d##h format.
long-summary: >
Can be used with either --start-time or --end-time. If used with --start-time, then
the end time will be calculated by adding the offset. If used with --end-time (default), then
the start time will be calculated by subtracting the offset. If --start-time and --end-time are
provided, then --offset will be ignored.
examples:
- name: View the count of availabilityResults events.
text: |
Expand All @@ -65,6 +202,15 @@
helps['monitor app-insights events show'] = """
type: command
short-summary: List events by type or view a single event from an application, specified by type and ID.
parameters:
- name: --offset
short-summary: >
Time offset of the query range, in ##d##h format.
long-summary: >
Can be used with either --start-time or --end-time. If used with --start-time, then
the end time will be calculated by adding the offset. If used with --end-time (default), then
the start time will be calculated by subtracting the offset. If --start-time and --end-time are
provided, then --offset will be ignored.
examples:
- name: Get an availability result by ID.
text: |
Expand Down
36 changes: 32 additions & 4 deletions src/application-insights/azext_applicationinsights/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,36 @@
# --------------------------------------------------------------------------------------------

# pylint: disable=line-too-long
from azure.cli.core.commands.parameters import get_datetime_type
from azure.cli.core.commands.parameters import get_datetime_type, get_location_type, tags_type
from azure.cli.command_modules.monitor.actions import get_period_type
from ._validators import validate_applications


def load_arguments(self, _):
with self.argument_context('monitor app-insights') as c:
c.argument('application', options_list=['--app', '-a'], id_part='name', help='GUID, app name, or fully-qualified Azure resource name of Application Insights component. The application GUID may be acquired from the API Access menu item on any Application Insights resource in the Azure portal. If using an application name, please specify resource group.')
c.argument('start_time', arg_type=get_datetime_type(help='Start-time of time range for which to retrieve data.'))
c.argument('end_time', arg_type=get_datetime_type(help='End of time range for current operation. Defaults to the current time.'))
c.argument('offset', help='Filter results based on UTC hour offset.', type=get_period_type(as_timedelta=True))

with self.argument_context('monitor app-insights component create') as c:
c.argument('location', arg_type=get_location_type(self.cli_ctx))
c.argument('application-type', options_list=['application-type', '--type', '-t'], help="Type of application being monitored. Possible values include: 'web', 'other'. Default value: 'web' .")
c.argument('kind', options_list=['--kind', '-k'], help='The kind of application that this component refers to, used to customize UI. This value is a freeform string, values should typically be one of the following: web, ios, other, store, java, phone.')
c.argument('tags', tags_type)

with self.argument_context('monitor app-insights component update') as c:
c.argument('location', arg_type=get_location_type(self.cli_ctx))
c.argument('application-type', options_list=['application-type', '--type', '-t'], help="Type of application being monitored. Possible values include: 'web', 'other'. Default value: 'web' .")
alexeldeib marked this conversation as resolved.
Show resolved Hide resolved
c.argument('kind', options_list=['--kind', '-k'], help='The kind of application that this component refers to, used to customize UI. This value is a freeform string, values should typically be one of the following: web, ios, other, store, java, phone.')

with self.argument_context('monitor app-insights component update-tags') as c:
c.argument('tags', tags_type)

with self.argument_context('monitor app-insights api-key create') as c:
c.argument('api_key', help='The name of the API key to create.')
c.argument('read_properties', nargs='+', options_list=['--read-properties'])
alexeldeib marked this conversation as resolved.
Show resolved Hide resolved
c.argument('write_properties', nargs='+')

with self.argument_context('monitor app-insights api-key show') as c:
c.argument('api_key', help='The name of the API key to fetch.')

with self.argument_context('monitor app-insights metrics show') as c:
c.argument('metric', options_list=['--metrics', '-m'], help='The metric to retrieve. May be either a standard AI metric or an application-specific custom metric.')
Expand All @@ -24,11 +43,20 @@ def load_arguments(self, _):
c.argument('segment', help='The name of the dimension to segment the metric values by. This dimension must be applicable to the metric you are retrieving. To segment by more than one dimension at a time, separate them with a comma (,). In this case, the metric data will be segmented in the order the dimensions are listed in the parameter.')
c.argument('top', help='The number of segments to return. This value is only valid when segment is specified.')
c.argument('filter_arg', options_list=['--filter'], help=' An expression used to filter the results. This value should be a valid OData filter expression where the keys of each clause should be applicable dimensions for the metric you are retrieving.')
c.argument('start_time', arg_type=get_datetime_type(help='Start-time of time range for which to retrieve data.'))
c.argument('end_time', arg_type=get_datetime_type(help='End of time range for current operation. Defaults to the current time.'))
c.argument('offset', help='Filter results based on UTC hour offset.', type=get_period_type(as_timedelta=True))

with self.argument_context('monitor app-insights events show') as c:
c.argument('event_type', options_list=['--type'], help='The type of events to retrieve.')
c.argument('event', options_list=['--event'], help='GUID of the event to retrieve. This could be obtained by first listing and filtering events, then selecting an event of interest.')
c.argument('start_time', arg_type=get_datetime_type(help='Start-time of time range for which to retrieve data.'))
c.argument('end_time', arg_type=get_datetime_type(help='End of time range for current operation. Defaults to the current time.'))
c.argument('offset', help='Filter results based on UTC hour offset.', type=get_period_type(as_timedelta=True))

with self.argument_context('monitor app-insights query') as c:
c.argument('application', validator=validate_applications, options_list=['--apps', '-a'], nargs='+', id_part='name', help='GUID, app name, or fully-qualified Azure resource name of Application Insights component. The application GUID may be acquired from the API Access menu item on any Application Insights resource in the Azure portal. If using an application name, please specify resource group.')
c.argument('analytics_query', help='Query to execute over Application Insights data.')
c.argument('start_time', arg_type=get_datetime_type(help='Start-time of time range for which to retrieve data.'))
c.argument('end_time', arg_type=get_datetime_type(help='End of time range for current operation. Defaults to the current time.'))
c.argument('offset', help='Filter results based on UTC hour offset.', type=get_period_type(as_timedelta=True))
36 changes: 35 additions & 1 deletion src/application-insights/azext_applicationinsights/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from azext_applicationinsights._client_factory import (
cf_events,
cf_metrics,
cf_query
cf_query,
cf_components,
cf_api_key
)

from azure.cli.core.commands import CliCommandType
Expand All @@ -31,6 +33,38 @@ def load_command_table(self, _):
client_factory=cf_query
)

components_sdk = CliCommandType(
operations_tmpl='azext_applicationinsights.vendored_sdks.mgmt_applicationinsights.operations.components_operations#ComponentsOperations.{}',
client_factory=cf_components
)

components_custom_sdk = CliCommandType(
operations_tmpl='azext_applicationinsights.custom#{}',
client_factory=cf_components
)

api_key_sdk = CliCommandType(
operations_tmpl='azext_applicationinsights.vendored_sdks.mgmt_applicationinsights.operations.api_keys_operations#APIKeysOperations.{}',
client_factory=cf_api_key
)

api_key_custom_sdk = CliCommandType(
operations_tmpl='azext_applicationinsights.custom#{}',
client_factory=cf_api_key
)

with self.command_group('monitor app-insights component', command_type=components_sdk, custom_command_type=components_custom_sdk) as g:
g.custom_command('create', 'create_or_update_component')
g.custom_command('update', 'update_component')
g.custom_command('show', 'show_components')
g.custom_command('delete', 'delete_component')
g.custom_command('update-tags', 'update_component_tags')

with self.command_group('monitor app-insights api-key', command_type=api_key_sdk, custom_command_type=api_key_custom_sdk) as g:
g.custom_command('create', 'create_api_key')
g.custom_command('show', 'show_api_key')
g.custom_command('delete', 'delete_api_key')

with self.command_group('monitor app-insights metrics', metrics_sdk) as g:
g.custom_command('show', 'get_metric')
g.custom_command('get-metadata', 'get_metrics_metadata')
Expand Down
67 changes: 66 additions & 1 deletion src/application-insights/azext_applicationinsights/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

# pylint: disable=line-too-long

from knack.util import CLIError
from knack.log import get_logger
from .util import get_id_from_azure_resource, get_query_targets, get_timespan
from .util import get_id_from_azure_resource, get_query_targets, get_timespan, get_linked_properties

logger = get_logger(__name__)

Expand All @@ -31,3 +32,67 @@ def get_metric(cmd, client, application, metric, start_time=None, end_time=None,

def get_metrics_metadata(cmd, client, application, resource_group_name=None):
return client.metrics.get_metadata(get_id_from_azure_resource(cmd.cli_ctx, application, resource_group=resource_group_name))


def create_or_update_component(client, application, resource_group_name, location, tags=None, kind="web", application_type='web'):
from .vendored_sdks.mgmt_applicationinsights.models import ApplicationInsightsComponent
component = ApplicationInsightsComponent(location, kind, application_type=application_type, tags=tags)
return client.create_or_update(resource_group_name, application, component)


def update_component(client, application, resource_group_name, kind=None):
existing_component = client.get(resource_group_name, application)
if kind:
existing_component.kind = kind
return client.create_or_update(resource_group_name, application, existing_component)


def update_component_tags(client, application, resource_group_name, tags):
return client.update_tags(resource_group_name, application, tags)


def get_component(client, application, resource_group_name):
return client.get(resource_group_name, application)


def show_components(client, application=None, resource_group_name=None):
if application:
if resource_group_name:
return client.get(resource_group_name, application)
raise CLIError("Application provided without resource group. Either specify app with resource group, or remove app.")
if resource_group_name:
return client.list_by_resource_group(resource_group_name)
return client.list()


def delete_component(client, application, resource_group_name):
return client.delete(resource_group_name, application)


def create_api_key(cmd, client, application, resource_group_name, api_key, read_properties=None, write_properties=None):
from .vendored_sdks.mgmt_applicationinsights.models import APIKeyRequest
if read_properties is None:
read_properties = ['ReadTelemetry', 'AuthenticateSDKControlChannel']
if write_properties is None:
write_properties = ['WriteAnnotations']
linked_read_properties, linked_write_properties = get_linked_properties(cmd.cli_ctx, application, resource_group_name, read_properties, write_properties)
api_key_request = APIKeyRequest(api_key, linked_read_properties, linked_write_properties)
return client.create(resource_group_name, application, api_key_request)


def show_api_key(client, application, resource_group_name, api_key=None):
if api_key is None:
return client.list(resource_group_name, application)
result = list(filter(lambda result: result.name == api_key, client.list(resource_group_name, application)))
if len(result) == 1:
return result[0]
alexeldeib marked this conversation as resolved.
Show resolved Hide resolved
elif len(result) > 1:
return result
return None


def delete_api_key(client, application, resource_group_name, api_key):
existing_key = list(filter(lambda result: result.name == api_key, client.list(resource_group_name, application)))
if existing_key != []:
return client.delete(resource_group_name, application, existing_key[0].id.split('/')[-1])
raise CLIError('--api-key provided but key not found for deletion.')
Loading