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

Add Subscription RP extension. #49

Merged
merged 13 commits into from
Feb 7, 2018
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@
/src/webapp/ @panchagnula

/src/aem/ @yugangw-msft

/src/subscription/ @wilcobmsft
6 changes: 3 additions & 3 deletions scripts/ci/test_static.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ set -e
proc_number=`python -c 'import multiprocessing; print(multiprocessing.cpu_count())'`

# Run pylint/flake8 on extensions
# - We ignore 'models', 'operations' and files with suffix '_management_client.py' as they typically come from vendored Azure SDKs
pylint ./src/*/azext_*/ --ignore=models,operations,service_bus_management_client --ignore-patterns=[a-zA-Z_]+_management_client.py --rcfile=./pylintrc -j $proc_number
flake8 --statistics --exclude=models,operations,*_management_client.py --append-config=./.flake8 ./src/*/azext_*/
# - We ignore 'models', 'operations' and files with suffix '_client.py' as they typically come from vendored Azure SDKs
pylint ./src/*/azext_*/ --ignore=models,operations,service_bus_management_client,subscription_client --ignore-patterns=[a-zA-Z_]+_client.py --rcfile=./pylintrc -j $proc_number
flake8 --statistics --exclude=models,operations,*_client.py --append-config=./.flake8 ./src/*/azext_*/

# Run pylint/flake8 on CI files
pylint ./scripts/ci/*.py --rcfile=./pylintrc
Expand Down
31 changes: 31 additions & 0 deletions src/subscription/azext_subscription/__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.
# --------------------------------------------------------------------------------------------

# pylint: disable=unused-import
# pylint: disable=line-too-long

from azure.cli.core import AzCommandsLoader
from ._help import helps


class SubscriptionCommandsLoader(AzCommandsLoader):

def __init__(self, cli_ctx=None):
from azure.cli.core.commands import CliCommandType
subscription_custom = CliCommandType(operations_tmpl='azext_subscription.custom#{}')
super(SubscriptionCommandsLoader, self).__init__(cli_ctx=cli_ctx, custom_command_type=subscription_custom,
min_profile="2017-03-10-profile")

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

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


COMMAND_LOADER_CLS = SubscriptionCommandsLoader
15 changes: 15 additions & 0 deletions src/subscription/azext_subscription/_client_factory.py
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_subscription(cli_ctx, **_):
from azure.cli.core.commands.client_factory import _get_mgmt_service_client
from azext_subscription.subscription import SubscriptionClient
client, _ = _get_mgmt_service_client(cli_ctx, SubscriptionClient, subscription_bound=False)
return client


def subscription_definitions_mgmt_client_factory(cli_ctx, kwargs):
return cf_subscription(cli_ctx, **kwargs).subscription_definitions
17 changes: 17 additions & 0 deletions src/subscription/azext_subscription/_exception_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from knack.util import CLIError


def subscription_exception_handler(ex):
from azext_subscription.subscription.models import ErrorResponseException
if isinstance(ex, ErrorResponseException):
message = ex.error.error.message
raise CLIError(message)
else:
import sys
from six import reraise
reraise(*sys.exc_info())
17 changes: 17 additions & 0 deletions src/subscription/azext_subscription/_help.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# --------------------------------------------------------------------------------------------
# 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


helps['account subscription-definition'] = """
type: group
short-summary: Manage Azure Subscription Definitions.
"""

helps['account subscription-definition create'] = """
type: command
short-summary: Create a subscription definition.
"""
17 changes: 17 additions & 0 deletions src/subscription/azext_subscription/_params.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# --------------------------------------------------------------------------------------------
# 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.commands.parameters import get_enum_type


# pylint: disable=line-too-long
def load_arguments(self, _):
with self.argument_context('account subscription-definition create') as c:
c.argument('offer_type', required=True, help='The offer type of the subscription. For example, MS-AZR-0017P (EnterpriseAgreement) and MS-AZR-0148P (EnterpriseAgreement devTest) are available.', arg_type=get_enum_type(['MS-AZR-0017P', 'MS-AZR-0148P']))
c.argument('subscription_display_name', help='The subscription display name of the subscription definition.')

for scope in ['account subscription-definition create', 'account subscription-definition show']:
with self.argument_context(scope) as c:
c.argument('subscription_definition_name', options_list=['--name', '-n'], help='Name of the subscription definition.')
3 changes: 3 additions & 0 deletions src/subscription/azext_subscription/azext_metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"azext.minCliCoreVersion": "2.0.24"
}
24 changes: 24 additions & 0 deletions src/subscription/azext_subscription/commands.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# --------------------------------------------------------------------------------------------
# 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

from azure.cli.core.commands import CliCommandType
from ._client_factory import subscription_definitions_mgmt_client_factory
from ._exception_handler import subscription_exception_handler


def load_command_table(self, _):
subscription_definition_util = CliCommandType(
operations_tmpl='azext_subscription.subscription.operations.subscription_definitions_operations#SubscriptionDefinitionsOperations.{}',
client_factory=subscription_definitions_mgmt_client_factory,
client_arg_name='self',
Copy link
Member

Choose a reason for hiding this comment

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

client_arg_name shouldn't be needed. What happens if you omit it?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, my commands don't work without this ("missing parameter: self"). This was one of the main surprises I hit when converting from module to extension.

Copy link
Member

Choose a reason for hiding this comment

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

@derekbekoe I see. Can you open an issue in the main CLI repo so I look into this in an upcoming sprint? Ideally this shouldn't be needed.

exception_handler=subscription_exception_handler
)

with self.command_group('account subscription-definition', subscription_definition_util, client_factory=subscription_definitions_mgmt_client_factory) as g:
g.command('list', 'list')
g.command('show', 'get')
g.custom_command('create', 'cli_subscription_create_subscription_definition')
18 changes: 18 additions & 0 deletions src/subscription/azext_subscription/custom.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

from azext_subscription.subscription.models import SubscriptionDefinition


def cli_subscription_create_subscription_definition(client, subscription_definition_name,
offer_type, subscription_display_name=None):
if subscription_display_name is None:
subscription_display_name = subscription_definition_name

new_def = SubscriptionDefinition(
subscription_display_name=subscription_display_name,
offer_type=offer_type)

return client.create(subscription_definition_name, new_def)
17 changes: 17 additions & 0 deletions src/subscription/azext_subscription/subscription/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# 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.
#
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------

from .subscription_client import SubscriptionClient
from .version import VERSION

__all__ = ['SubscriptionClient']

__version__ = VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# 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.
#
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------

from .subscription_definition import SubscriptionDefinition
from .operation_display import OperationDisplay
from .operation import Operation
from .error_response import ErrorResponse, ErrorResponseException
from .location import Location
from .subscription_policies import SubscriptionPolicies
from .subscription import Subscription
from .tenant_id_description import TenantIdDescription
from .operation_paged import OperationPaged
from .subscription_definition_paged import SubscriptionDefinitionPaged
from .location_paged import LocationPaged
from .subscription_paged import SubscriptionPaged
from .tenant_id_description_paged import TenantIdDescriptionPaged
from .subscription_client_enums import (
SubscriptionState,
SpendingLimit,
)

__all__ = [
'SubscriptionDefinition',
'OperationDisplay',
'Operation',
'ErrorResponse', 'ErrorResponseException',
'Location',
'SubscriptionPolicies',
'Subscription',
'TenantIdDescription',
'OperationPaged',
'SubscriptionDefinitionPaged',
'LocationPaged',
'SubscriptionPaged',
'TenantIdDescriptionPaged',
'SubscriptionState',
'SpendingLimit',
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# 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.
#
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------

from msrest.serialization import Model
from msrest.exceptions import HttpOperationError


class ErrorResponse(Model):
"""Describes the format of Error response.

:param code: Error code
:type code: str
:param message: Error message indicating why the operation failed.
:type message: str
"""

_attribute_map = {
'code': {'key': 'code', 'type': 'str'},
'message': {'key': 'message', 'type': 'str'},
}

def __init__(self, code=None, message=None):
self.code = code
self.message = message


class ErrorResponseException(HttpOperationError):
"""Server responsed with exception of type: 'ErrorResponse'.

:param deserialize: A deserializer
:param response: Server response to be deserialized.
"""

def __init__(self, deserialize, response, *args):

super(ErrorResponseException, self).__init__(deserialize, response, 'ErrorResponse', *args)
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# 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.
#
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------

from msrest.serialization import Model


class Location(Model):
"""Location information.

Variables are only populated by the server, and will be ignored when
sending a request.

:ivar id: The fully qualified ID of the location. For example,
/subscriptions/00000000-0000-0000-0000-000000000000/locations/westus.
:vartype id: str
:ivar subscription_id: The subscription ID.
:vartype subscription_id: str
:ivar name: The location name.
:vartype name: str
:ivar display_name: The display name of the location.
:vartype display_name: str
:ivar latitude: The latitude of the location.
:vartype latitude: str
:ivar longitude: The longitude of the location.
:vartype longitude: str
"""

_validation = {
'id': {'readonly': True},
'subscription_id': {'readonly': True},
'name': {'readonly': True},
'display_name': {'readonly': True},
'latitude': {'readonly': True},
'longitude': {'readonly': True},
}

_attribute_map = {
'id': {'key': 'id', 'type': 'str'},
'subscription_id': {'key': 'subscriptionId', 'type': 'str'},
'name': {'key': 'name', 'type': 'str'},
'display_name': {'key': 'displayName', 'type': 'str'},
'latitude': {'key': 'latitude', 'type': 'str'},
'longitude': {'key': 'longitude', 'type': 'str'},
}

def __init__(self):
self.id = None
self.subscription_id = None
self.name = None
self.display_name = None
self.latitude = None
self.longitude = None
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# 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.
#
# Code generated by Microsoft (R) AutoRest Code Generator.
# Changes may cause incorrect behavior and will be lost if the code is
# regenerated.
# --------------------------------------------------------------------------

from msrest.paging import Paged


class LocationPaged(Paged):
"""
A paging container for iterating over a list of :class:`Location <azure.mgmt.subscription.models.Location>` object
"""

_attribute_map = {
'next_link': {'key': 'nextLink', 'type': 'str'},
'current_page': {'key': 'value', 'type': '[Location]'}
}

def __init__(self, *args, **kwargs):

super(LocationPaged, self).__init__(*args, **kwargs)
Loading