diff --git a/scripts/multiapi_init_gen.py b/scripts/multiapi_init_gen.py index d79ab3105f37..a542e48334b8 100644 --- a/scripts/multiapi_init_gen.py +++ b/scripts/multiapi_init_gen.py @@ -1,32 +1,47 @@ import ast import importlib import inspect -import ast import logging import os import pkgutil import re import sys -import types -import glob +import shutil from pathlib import Path -from unittest.mock import MagicMock, patch + +from typing import List, Tuple, Any try: import msrestazure except: # Install msrestazure. Would be best to mock it, since we don't need it, but all scenarios I know are fine with a pip install for now import subprocess - subprocess.call(sys.executable + " -m pip install msrestazure", shell=True) # Use shell to use venv if available + + subprocess.call( + sys.executable + " -m pip install msrestazure", shell=True + ) # Use shell to use venv if available + +try: + from jinja2 import Template, FileSystemLoader, Environment +except: + import subprocess + + subprocess.call( + sys.executable + " -m pip install jinja2", shell=True + ) # Use shell to use venv if available + from jinja2 import Template, FileSystemLoader, Environment + try: import azure.common except: - sdk_root = Path(__file__).parents[1] - sys.path.append(str((sdk_root / "sdk" / "core" / "azure-common").resolve())) + sys.path.append( + str((Path(__file__).parents[1] / "sdk" / "core" / "azure-common").resolve()) + ) import azure.common import pkg_resources -pkg_resources.declare_namespace('azure') + +pkg_resources.declare_namespace("azure") _GENERATE_MARKER = "############ Generated from here ############\n" @@ -37,25 +52,40 @@ def parse_input(input_parameter): """From a syntax like package_name#submodule, build a package name and complete module name. """ - split_package_name = input_parameter.split('#') + split_package_name = input_parameter.split("#") package_name = split_package_name[0] module_name = package_name.replace("-", ".") if len(split_package_name) >= 2: module_name = ".".join([module_name, split_package_name[1]]) return package_name, module_name + # given an input of a name, we need to return the appropriate relative diff between the sdk_root and the actual package directory -def resolve_package_directory(package_name, sdk_root): - packages = [os.path.dirname(p) for p in (glob.glob('{}/setup.py'.format(package_name)) + glob.glob('sdk/*/{}/setup.py'.format(package_name)))] +def resolve_package_directory(package_name, sdk_root=None): + packages = [ + os.path.dirname(p) + for p in ( + list(sdk_root.glob("{}/setup.py".format(package_name))) + + list(sdk_root.glob("sdk/*/{}/setup.py".format(package_name))) + ) + ] if len(packages) > 1: - print('There should only be a single package matched in either repository structure. The following were found: {}'.format(packages)) + print( + "There should only be a single package matched in either repository structure. The following were found: {}".format( + packages + ) + ) sys.exit(1) return os.path.relpath(packages[0], sdk_root) -def get_versioned_modules(package_name, module_name, sdk_root=None): +def get_versioned_modules( + package_name: str, module_name: str, sdk_root: Path = None +) -> List[Tuple[str, Any]]: + """Get (label, submodule) where label starts with "v20" and submodule is the corresponding imported module. + """ if not sdk_root: sdk_root = Path(__file__).parents[1] @@ -65,9 +95,12 @@ def get_versioned_modules(package_name, module_name, sdk_root=None): # Doesn't work with namespace package # sys.path.append(str((sdk_root / package_name).resolve())) module_to_generate = importlib.import_module(module_name) - return [(label, importlib.import_module('.'+label, module_to_generate.__name__)) - for (_, label, ispkg) in pkgutil.iter_modules(module_to_generate.__path__) - if label.startswith("v20") and ispkg] + return { + label: importlib.import_module("." + label, module_to_generate.__name__) + for (_, label, ispkg) in pkgutil.iter_modules(module_to_generate.__path__) + if label.startswith("v20") and ispkg + } + class ApiVersionExtractor(ast.NodeVisitor): def __init__(self, *args, **kwargs): @@ -90,7 +123,7 @@ def extract_api_version_from_code(function): try: ast_tree = ast.parse(srccode) except IndentationError: - ast_tree = ast.parse('with 0:\n'+srccode) + ast_tree = ast.parse("with 0:\n" + srccode) api_version_visitor = ApiVersionExtractor() api_version_visitor.visit(ast_tree) @@ -98,13 +131,38 @@ def extract_api_version_from_code(function): except Exception: raise + +def get_client_class_name_from_module(module): + """Being a module that is an Autorest generation, get the client name.""" + # Using the fact that Client is always the first element in __all__ + # I externalize that code in a class in case we need to be smarter later + return module.__all__[0] + + def build_operation_meta(versioned_modules): + """Introspect the client: + + version_dict => { + 'application_gateways': [ + ('v2018_05_01', 'ApplicationGatewaysOperations') + ] + } + mod_to_api_version => {'v2018_05_01': '2018-05-01'} + """ + version_dict = {} mod_to_api_version = {} - for versionned_label, versionned_mod in versioned_modules: + for versionned_label, versionned_mod in versioned_modules.items(): extracted_api_versions = set() - client_doc = versionned_mod.__dict__[versionned_mod.__all__[0]].__doc__ - operations = list(re.finditer(r':ivar (?P[a-z_]+): \w+ operations\n\s+:vartype (?P=attr): .*.operations.(?P\w+)\n', client_doc)) + client_doc = versionned_mod.__dict__[ + get_client_class_name_from_module(versionned_mod) + ].__doc__ + operations = list( + re.finditer( + r":ivar (?P[a-z_]+): \w+ operations\n\s+:vartype (?P=attr): .*.operations.(?P\w+)\n", + client_doc, + ) + ) for operation in operations: attr, clsname = operation.groups() _LOGGER.debug("Class name: %s", clsname) @@ -113,33 +171,58 @@ def build_operation_meta(versioned_modules): # Create a fake operation group to extract easily the real api version extracted_api_version = None try: - extracted_api_version = versionned_mod.operations.__dict__[clsname](None, None, None, None).api_version + extracted_api_version = versionned_mod.operations.__dict__[clsname]( + None, None, None, None + ).api_version _LOGGER.debug("Found an obvious API version: %s", extracted_api_version) if extracted_api_version: extracted_api_versions.add(extracted_api_version) except Exception: - _LOGGER.debug("Should not happen. I guess it mixed operation groups like VMSS Network...") - for func_name, function in versionned_mod.operations.__dict__[clsname].__dict__.items(): + _LOGGER.debug( + "Should not happen. I guess it mixed operation groups like VMSS Network..." + ) + for func_name, function in versionned_mod.operations.__dict__[ + clsname + ].__dict__.items(): if not func_name.startswith("__"): _LOGGER.debug("Try to extract API version from: %s", func_name) extracted_api_version = extract_api_version_from_code(function) - _LOGGER.debug("Extracted API version: %s", extracted_api_version) + _LOGGER.debug( + "Extracted API version: %s", extracted_api_version + ) if extracted_api_version: extracted_api_versions.add(extracted_api_version) if not extracted_api_versions: - sys.exit("Was not able to extract api_version of {}".format(versionned_label)) + sys.exit( + "Was not able to extract api_version of {}".format(versionned_label) + ) if len(extracted_api_versions) >= 2: # Mixed operation group, try to figure out what we want to use final_api_version = None - _LOGGER.warning("Found too much API version: {} in label {}".format(extracted_api_versions, versionned_label)) + _LOGGER.warning( + "Found too much API version: {} in label {}".format( + extracted_api_versions, versionned_label + ) + ) for candidate_api_version in extracted_api_versions: - if "v{}".format(candidate_api_version.replace("-", "_")) == versionned_label: + if ( + "v{}".format(candidate_api_version.replace("-", "_")) + == versionned_label + ): final_api_version = candidate_api_version - _LOGGER.warning("Guessing you want {} based on label {}".format(final_api_version, versionned_label)) + _LOGGER.warning( + "Guessing you want {} based on label {}".format( + final_api_version, versionned_label + ) + ) break else: - sys.exit("Unble to match {} to label {}".format(extracted_api_versions, versionned_label)) + sys.exit( + "Unble to match {} to label {}".format( + extracted_api_versions, versionned_label + ) + ) extracted_api_versions = {final_api_version} mod_to_api_version[versionned_label] = extracted_api_versions.pop() @@ -148,120 +231,168 @@ def build_operation_meta(versioned_modules): return version_dict, mod_to_api_version -def build_models_string(module_name, mod_to_api_version): - result = """ @classmethod - def models(cls, api_version=DEFAULT_API_VERSION): -""" - - template_models_if = """ - {first}if api_version == '{api_version}': - from .{api_version_module} import models - return models""" - template_models_end_def = """ raise NotImplementedError("APIVersion {} is not available".format(api_version)) -""" - - template_intro_doc= ' """Module depends on the API version:\n' - template_inside_doc=" * {api_version}: :mod:`{api_version_module}.models<{module_name}.{api_version_module}.models>`" - template_end_doc=' """' - - result += template_intro_doc - for attr in sorted(mod_to_api_version.keys()): - result += "\n" - result += template_inside_doc.format( - module_name=module_name, - api_version=mod_to_api_version[attr], - api_version_module=attr) - result += "\n" - result += template_end_doc - - first = True - for attr in sorted(mod_to_api_version.keys()): - result += template_models_if.format( - first='' if first else 'el', - api_version=mod_to_api_version[attr], - api_version_module=attr) - first = False - result += "\n" - result += template_models_end_def - return result - - -def build_operation_group(module_name, operation_name, versions): - - template_def = " @property\n def {attr}(self):\n" - template_intro_doc= ' """Instance depends on the API version:\n\n' - template_inside_doc=" * {api_version}: :class:`{clsname}<{module_name}.{api_version_module}.operations.{clsname}>`\n" - template_end_doc=' """\n' - template_code_prefix=" api_version = self._get_api_version('{attr}')" - template_if = """ {first}if api_version == '{api_version}': - from .{api_version_module}.operations import {clsname} as OperationClass""" - template_end_def = """ else: - raise NotImplementedError("APIVersion {} is not available".format(api_version)) - return OperationClass(self._client, self.config, Serializer(self._models_dict(api_version)), Deserializer(self._models_dict(api_version))) -""" - result = template_def.format(attr=operation_name) - result += template_intro_doc - for version in versions: - result += template_inside_doc.format( - api_version=mod_to_api_version[version[0]], - api_version_module=version[0], - module_name=module_name, - clsname=version[1]) - result += template_end_doc - result += template_code_prefix.format(attr=operation_name) - first = True - for version in versions: - result += "\n" - result += template_if.format( - first='' if first else 'el', - api_version=mod_to_api_version[version[0]], - api_version_module=version[0], - clsname=version[1]) - first = False - result += "\n" - result += template_end_def - return result +def build_operation_mixin_meta(versioned_modules): + """Introspect the client: -def find_client_file(package_name, module_name): - path_to_package = resolve_package_directory(package_name, Path(__file__).parents[1]) - module_path = Path(path_to_package) / Path(module_name.replace(".", os.sep)) + version_dict => { + 'check_dns_name_availability': { + 'doc': 'docstring', + 'signature': '(self, p1, p2, **operation_config), + 'call': 'p1, p2', + 'available_apis': [ + 'v2018_05_01' + ] + } + } + """ + mixin_operations = {} - return next(module_path.glob('*_client.py')) + for versionned_label, versionned_mod in sorted(versioned_modules.items()): -_CODE_PREFIX = """ - @classmethod - def _models_dict(cls, api_version): - return {k: v for k, v in cls.models(api_version).__dict__.items() if isinstance(v, type)} + client_name = get_client_class_name_from_module(versionned_mod) + client_class = versionned_mod.__dict__[client_name] -""" + # Detect if this client is using an operation mixin (Network) + # Operation mixins are available since Autorest.Python 4.x + operations_mixin = next( + (c for c in client_class.__mro__ if "OperationsMixin" in c.__name__), None + ) + if not operations_mixin: + continue -if __name__ == "__main__": - logging.basicConfig(level=logging.INFO) + for func_name, func in operations_mixin.__dict__.items(): + # Work only on functions + if func_name.startswith("_"): + continue + + signature = inspect.signature(func) + mixin_operations.setdefault(func_name, {}).setdefault( + "available_apis", [] + ).append(versionned_label) + mixin_operations[func_name]["doc"] = func.__doc__ + mixin_operations[func_name]["signature"] = str(signature) + mixin_operations[func_name]["call"] = ", ".join( + list(signature.parameters)[1:-1] + ) + + return mixin_operations + + +def find_module_folder(package_name, module_name): + sdk_root = Path(__file__).parents[1] + _LOGGER.debug("SDK root is: %s", sdk_root) + path_to_package = resolve_package_directory(package_name, sdk_root) + module_path = ( + sdk_root / Path(path_to_package) / Path(module_name.replace(".", os.sep)) + ) + _LOGGER.debug("Module path is: %s", module_path) + return module_path - package_name, module_name = parse_input(sys.argv[1]) + +def find_client_file(package_name, module_name): + module_path = find_module_folder(package_name, module_name) + return next(module_path.glob("*_client.py")) + + +def main(input_str): + package_name, module_name = parse_input(input_str) versioned_modules = get_versioned_modules(package_name, module_name) - version_dict, mod_to_api_version = build_operation_meta(versioned_modules) - model_string = build_models_string(module_name, mod_to_api_version) - - operations_string = [] - for attr in sorted(version_dict.keys()): - versions = version_dict[attr] - operations_string.append(build_operation_group(module_name, attr, versions)) - - client_file = find_client_file(package_name, module_name) - with open(client_file, "r") as read_client: - lines = read_client.readlines() - with open(client_file, "w", newline='\n') as write_client: - for line in lines: - write_client.write(line) - if line == _GENERATE_MARKER: - break + versioned_operations_dict, mod_to_api_version = build_operation_meta( + versioned_modules + ) + + client_folder = find_module_folder(package_name, module_name) + last_api_version = sorted(mod_to_api_version.keys())[-1] + last_api_path = client_folder / last_api_version + + _LOGGER.info("Copy _configuration.py if possible") + + shutil.copy( + client_folder / last_api_version / "_configuration.py", + client_folder / "_configuration.py", + ) + shutil.copy( + client_folder / last_api_version / "__init__.py", client_folder / "__init__.py" + ) + + versionned_mod = versioned_modules[last_api_version] + client_name = get_client_class_name_from_module(versionned_mod) + client_class = versionned_mod.__dict__[client_name] + + # Detect if this client is using an operation mixin (Network) + # Operation mixins are available since Autorest.Python 4.x + mixin_operations = build_operation_mixin_meta(versioned_modules) + + # If we get a StopIteration here, means the API version folder is broken + client_file_name = next(last_api_path.glob("*_client.py")).name + + # versioned_operations_dict => { + # 'application_gateways': [ + # ('v2018-05-01', 'ApplicationGatewaysOperations') + # ] + # } + # mod_to_api_version => {'v2018-05-01': '2018-05-01'} + # mixin_operations => { + # 'check_dns_name_availability': { + # 'doc': 'docstring', + # 'signature': '(self, p1, p2, **operation_config), + # 'call': 'p1, p2', + # 'available_apis': [ + # 'v2018_05_01' + # ] + # } + # } + + last_rt_list = {} + for operation, operation_metadata in versioned_operations_dict.items(): + local_last_api_version = sorted(operation_metadata)[-1][0] + if local_last_api_version == last_api_version: + continue + last_rt_list[operation] = mod_to_api_version[local_last_api_version] + + for operation, operation_metadata in mixin_operations.items(): + local_last_api_version = sorted(operation_metadata['available_apis'])[-1] + if local_last_api_version == last_api_version: + continue + last_rt_list[operation] = mod_to_api_version[local_last_api_version] + + conf = { + "api_version_modules": sorted(mod_to_api_version.keys()), + "client_name": client_name, + "module_name": module_name, + "operations": versioned_operations_dict, + "mixin_operations": mixin_operations, + "mod_to_api_version": mod_to_api_version, + "last_api_version": mod_to_api_version[last_api_version], + "client_doc": client_class.__doc__.split("\n")[0], + "last_rt_list": last_rt_list, + } + + env = Environment( + loader=FileSystemLoader(str(Path(__file__).parents[0] / "templates")), + keep_trailing_newline=True, + ) + + for template_name in env.list_templates(): + # Don't generate files if they is not operations mixins + if template_name == "_operations_mixin.py" and not mixin_operations: + continue + + # Some file doesn't use the template name + if template_name == "_multiapi_client.py": + output_filename = client_file_name else: - sys.exit("Didn't find generate lines!!!!") + output_filename = template_name + + future_filepath = client_folder / output_filename - write_client.write(_CODE_PREFIX) - write_client.write(model_string) - for operation in operations_string: - write_client.write("\n") - write_client.write(operation) + template = env.get_template(template_name) + result = template.render(**conf) + with open(future_filepath, "w") as fd: + fd.write(result) + + +if __name__ == "__main__": + logging.basicConfig(level=logging.INFO) + main(sys.argv[1]) diff --git a/scripts/templates/_multiapi_client.py b/scripts/templates/_multiapi_client.py new file mode 100644 index 000000000000..5ad0fcae2762 --- /dev/null +++ b/scripts/templates/_multiapi_client.py @@ -0,0 +1,104 @@ +# 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.service_client import SDKClient +from msrest import Serializer, Deserializer + +from azure.profiles import KnownProfiles, ProfileDefinition +from azure.profiles.multiapiclient import MultiApiClientMixin +from .version import VERSION +from ._configuration import {{ client_name }}Configuration +{% if mixin_operations %}from ._operations_mixin import {{ client_name }}OperationsMixin{% endif %} + + +class {{ client_name }}({% if mixin_operations %}{{ client_name }}OperationsMixin, {% endif %}MultiApiClientMixin, SDKClient): + """{{ client_doc }} + + This ready contains multiple API versions, to help you deal with all Azure clouds + (Azure Stack, Azure Government, Azure China, etc.). + By default, uses latest API version available on public Azure. + For production, you should stick a particular api-version and/or profile. + The profile sets a mapping between the operation group and an API version. + The api-version parameter sets the default API version if the operation + group is not described in the profile. + + :ivar config: Configuration for client. + :vartype config: {{ client_name }}Configuration + + :param credentials: Credentials needed for the client to connect to Azure. + :type credentials: :mod:`A msrestazure Credentials + object` + :param subscription_id: Subscription credentials which uniquely identify + Microsoft Azure subscription. The subscription ID forms part of the URI + for every service call. + :type subscription_id: str + :param str api_version: API version to use if no profile is provided, or if + missing in profile. + :param str base_url: Service URL + :param profile: A profile definition, from KnownProfiles to dict. + :type profile: azure.profiles.KnownProfiles + """ + + DEFAULT_API_VERSION = '{{ last_api_version }}' + _PROFILE_TAG = "{{ module_name }}.{{ client_name }}" + LATEST_PROFILE = ProfileDefinition({ + _PROFILE_TAG: { +{%- for rt_name, api_version in last_rt_list|dictsort %} + '{{ rt_name }}': '{{ api_version }}', +{%- endfor %} + None: DEFAULT_API_VERSION + }}, + _PROFILE_TAG + " latest" + ) + + def __init__(self, credentials, subscription_id, api_version=None, base_url=None, profile=KnownProfiles.default): + self.config = {{ client_name }}Configuration(credentials, subscription_id, base_url) + super({{ client_name }}, self).__init__( + credentials, + self.config, + api_version=api_version, + profile=profile + ) + + @classmethod + def _models_dict(cls, api_version): + return {k: v for k, v in cls.models(api_version).__dict__.items() if isinstance(v, type)} + + @classmethod + def models(cls, api_version=DEFAULT_API_VERSION): + """Module depends on the API version: +{% for mod_api_version, api_version in mod_to_api_version|dictsort %} + * {{ api_version }}: :mod:`{{ mod_api_version }}.models<{{ module_name }}.{{ mod_api_version }}.models>` +{%- endfor %} + """ +{%- for mod_api_version, api_version in mod_to_api_version|dictsort %} + {% if not loop.first %}el{% endif %}if api_version == '{{ api_version }}': + from .{{ mod_api_version }} import models + return models +{%- endfor %} + raise NotImplementedError("APIVersion {} is not available".format(api_version)) +{% for operation_name, available_apis in operations|dictsort %} + @property + def {{ operation_name }}(self): + """Instance depends on the API version: +{% for api in available_apis %} + * {{ mod_to_api_version[api[0]] }}: :class:`{{ api[1] }}<{{ module_name }}.{{ api[0] }}.operations.{{ api[1] }}>` +{%- endfor %} + """ + api_version = self._get_api_version('{{ operation_name }}') +{%- for api in available_apis %} + {% if not loop.first %}el{% endif %}if api_version == '{{ mod_to_api_version[api[0]] }}': + from .{{ api[0] }}.operations import {{ api[1] }} as OperationClass +{%- endfor %} + else: + raise NotImplementedError("APIVersion {} is not available".format(api_version)) + return OperationClass(self._client, self.config, Serializer(self._models_dict(api_version)), Deserializer(self._models_dict(api_version))) +{% endfor %} \ No newline at end of file diff --git a/scripts/templates/_operations_mixin.py b/scripts/templates/_operations_mixin.py new file mode 100644 index 000000000000..a270606d592e --- /dev/null +++ b/scripts/templates/_operations_mixin.py @@ -0,0 +1,33 @@ +# 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 import Serializer, Deserializer + + +class {{ client_name }}OperationsMixin(object): + +{% for operation_name, metadata in mixin_operations|dictsort %} + def {{ operation_name }}{{ metadata['signature'] }}: + """{{ metadata['doc'] }} + """ + api_version = self._get_api_version('{{ operation_name }}') +{%- for api in metadata['available_apis'] %} + {% if not loop.first %}el{% endif %}if api_version == '{{ mod_to_api_version[api] }}': + from .{{ api }}.operations import {{ client_name }}OperationsMixin as OperationClass +{%- endfor %} + else: + raise NotImplementedError("APIVersion {} is not available".format(api_version)) + mixin_instance = OperationClass() + mixin_instance._client = self._client + mixin_instance.config = self.config + mixin_instance._serialize = Serializer(self._models_dict(api_version)) + mixin_instance._deserialize = Deserializer(self._models_dict(api_version)) + return mixin_instance.{{ operation_name }}({{ metadata['call'] }}, **operation_config) +{% endfor %} \ No newline at end of file diff --git a/scripts/templates/models.py b/scripts/templates/models.py new file mode 100644 index 000000000000..55b7454f814b --- /dev/null +++ b/scripts/templates/models.py @@ -0,0 +1,9 @@ +# 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. +# -------------------------------------------------------------------------- +{%- for mod_api_version, _ in mod_to_api_version|dictsort %} +from .{{ mod_api_version }}.models import * +{%- endfor %} diff --git a/sdk/network/azure-mgmt-network/azure/mgmt/network/__init__.py b/sdk/network/azure-mgmt-network/azure/mgmt/network/__init__.py index 905cdbfa0138..6011c1a921c6 100644 --- a/sdk/network/azure-mgmt-network/azure/mgmt/network/__init__.py +++ b/sdk/network/azure-mgmt-network/azure/mgmt/network/__init__.py @@ -1,4 +1,4 @@ -# coding=utf-8 +# coding=utf-8 # -------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for @@ -9,9 +9,11 @@ # regenerated. # -------------------------------------------------------------------------- -from .network_management_client import NetworkManagementClient -from .version import VERSION +from ._configuration import NetworkManagementClientConfiguration +from ._network_management_client import NetworkManagementClient +__all__ = ['NetworkManagementClient', 'NetworkManagementClientConfiguration'] -__all__ = ['NetworkManagementClient'] +from .version import VERSION __version__ = VERSION + diff --git a/sdk/network/azure-mgmt-network/azure/mgmt/network/_configuration.py b/sdk/network/azure-mgmt-network/azure/mgmt/network/_configuration.py new file mode 100644 index 000000000000..a7dd38c001c1 --- /dev/null +++ b/sdk/network/azure-mgmt-network/azure/mgmt/network/_configuration.py @@ -0,0 +1,50 @@ +# 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 msrestazure import AzureConfiguration + +from .version import VERSION + + +class NetworkManagementClientConfiguration(AzureConfiguration): + """Configuration for NetworkManagementClient + Note that all parameters used to create this instance are saved as instance + attributes. + + :param credentials: Credentials needed for the client to connect to Azure. + :type credentials: :mod:`A msrestazure Credentials + object` + :param subscription_id: The subscription credentials which uniquely + identify the Microsoft Azure subscription. The subscription ID forms part + of the URI for every service call. + :type subscription_id: str + :param str base_url: Service URL + """ + + def __init__( + self, credentials, subscription_id, base_url=None): + + if credentials is None: + raise ValueError("Parameter 'credentials' must not be None.") + if subscription_id is None: + raise ValueError("Parameter 'subscription_id' must not be None.") + if not base_url: + base_url = 'https://management.azure.com' + + super(NetworkManagementClientConfiguration, self).__init__(base_url) + + # Starting Autorest.Python 4.0.64, make connection pool activated by default + self.keep_alive = True + + self.add_user_agent('azure-mgmt-network/{}'.format(VERSION)) + self.add_user_agent('Azure-SDK-For-Python') + + self.credentials = credentials + self.subscription_id = subscription_id diff --git a/sdk/network/azure-mgmt-network/azure/mgmt/network/network_management_client.py b/sdk/network/azure-mgmt-network/azure/mgmt/network/_network_management_client.py similarity index 98% rename from sdk/network/azure-mgmt-network/azure/mgmt/network/network_management_client.py rename to sdk/network/azure-mgmt-network/azure/mgmt/network/_network_management_client.py index d171f3b3c28b..8a809ae8d6bf 100644 --- a/sdk/network/azure-mgmt-network/azure/mgmt/network/network_management_client.py +++ b/sdk/network/azure-mgmt-network/azure/mgmt/network/_network_management_client.py @@ -11,47 +11,15 @@ from msrest.service_client import SDKClient from msrest import Serializer, Deserializer -from msrestazure import AzureConfiguration from azure.profiles import KnownProfiles, ProfileDefinition from azure.profiles.multiapiclient import MultiApiClientMixin from .version import VERSION +from ._configuration import NetworkManagementClientConfiguration +from ._operations_mixin import NetworkManagementClientOperationsMixin -class NetworkManagementClientConfiguration(AzureConfiguration): - """Configuration for NetworkManagementClient - Note that all parameters used to create this instance are saved as instance - attributes. - - :param credentials: Credentials needed for the client to connect to Azure. - :type credentials: :mod:`A msrestazure Credentials - object` - :param subscription_id: The subscription credentials which uniquely - identify the Microsoft Azure subscription. The subscription ID forms part - of the URI for every service call. - :type subscription_id: str - :param str base_url: Service URL - """ - - def __init__(self, credentials, subscription_id, base_url=None): - - if credentials is None: - raise ValueError("Parameter 'credentials' must not be None.") - if subscription_id is None: - raise ValueError("Parameter 'subscription_id' must not be None.") - if not base_url: - base_url = 'https://management.azure.com' - - super(NetworkManagementClientConfiguration, self).__init__(base_url) - - self.add_user_agent('networkmanagementclient/{}'.format(VERSION)) - self.add_user_agent('Azure-SDK-For-Python') - - self.credentials = credentials - self.subscription_id = subscription_id - - -class NetworkManagementClient(MultiApiClientMixin, SDKClient): +class NetworkManagementClient(NetworkManagementClientOperationsMixin, MultiApiClientMixin, SDKClient): """Network Client This ready contains multiple API versions, to help you deal with all Azure clouds @@ -83,6 +51,8 @@ class NetworkManagementClient(MultiApiClientMixin, SDKClient): _PROFILE_TAG = "azure.mgmt.network.NetworkManagementClient" LATEST_PROFILE = ProfileDefinition({ _PROFILE_TAG: { + 'interface_endpoints': '2019-02-01', + 'virtual_wa_ns': '2018-07-01', None: DEFAULT_API_VERSION }}, _PROFILE_TAG + " latest" @@ -97,83 +67,6 @@ def __init__(self, credentials, subscription_id, api_version=None, base_url=None profile=profile ) - def check_dns_name_availability( - self, location, domain_name_label, custom_headers=None, raw=False, **operation_config): - """Checks whether a domain name in the cloudapp.azure.com zone is - available for use. - - :param location: The location of the domain name. - :type location: str - :param domain_name_label: The domain name to be verified. It must - conform to the following regular expression: - ^[a-z][a-z0-9-]{1,61}[a-z0-9]$. - :type domain_name_label: str - :param dict custom_headers: headers that will be added to the request - :param bool raw: returns the direct response alongside the - deserialized response - :param operation_config: :ref:`Operation configuration - overrides`. - :return: :class:`DnsNameAvailabilityResult - ` or - :class:`ClientRawResponse` if - raw=true - :rtype: :class:`DnsNameAvailabilityResult - ` or - :class:`ClientRawResponse` - :raises: :class:`CloudError` - """ - api_version = self._get_api_version('check_dns_name_availability') - if api_version == '2019-04-01': - from .v2019_04_01 import NetworkManagementClient as ClientClass - elif api_version == '2019-02-01': - from .v2019_02_01 import NetworkManagementClient as ClientClass - elif api_version == '2018-12-01': - from .v2018_12_01 import NetworkManagementClient as ClientClass - elif api_version == '2018-11-01': - from .v2018_11_01 import NetworkManagementClient as ClientClass - elif api_version == '2018-10-01': - from .v2018_10_01 import NetworkManagementClient as ClientClass - elif api_version == '2018-08-01': - from .v2018_08_01 import NetworkManagementClient as ClientClass - elif api_version == '2018-07-01': - from .v2018_07_01 import NetworkManagementClient as ClientClass - elif api_version == '2018-06-01': - from .v2018_06_01 import NetworkManagementClient as ClientClass - elif api_version == '2018-04-01': - from .v2018_04_01 import NetworkManagementClient as ClientClass - elif api_version == '2018-02-01': - from .v2018_02_01 import NetworkManagementClient as ClientClass - elif api_version == '2018-01-01': - from .v2018_01_01 import NetworkManagementClient as ClientClass - elif api_version == '2017-11-01': - from .v2017_11_01 import NetworkManagementClient as ClientClass - elif api_version == '2017-10-01': - from .v2017_10_01 import NetworkManagementClient as ClientClass - elif api_version == '2017-09-01': - from .v2017_09_01 import NetworkManagementClient as ClientClass - elif api_version == '2017-08-01': - from .v2017_08_01 import NetworkManagementClient as ClientClass - elif api_version == '2017-06-01': - from .v2017_06_01 import NetworkManagementClient as ClientClass - elif api_version == '2017-03-01': - from .v2017_03_01 import NetworkManagementClient as ClientClass - elif api_version == '2016-12-01': - from .v2016_12_01 import NetworkManagementClient as ClientClass - elif api_version == '2016-09-01': - from .v2016_09_01 import NetworkManagementClient as ClientClass - elif api_version == '2015-06-15': - from .v2015_06_15 import NetworkManagementClient as ClientClass - localclient = ClientClass(self.config.credentials, - self.config.subscription_id, - self.config.base_url) - return localclient.check_dns_name_availability(location, - domain_name_label, - custom_headers, - raw, - **operation_config) - -############ Generated from here ############ - @classmethod def _models_dict(cls, api_version): return {k: v for k, v in cls.models(api_version).__dict__.items() if isinstance(v, type)} diff --git a/sdk/network/azure-mgmt-network/azure/mgmt/network/_operations_mixin.py b/sdk/network/azure-mgmt-network/azure/mgmt/network/_operations_mixin.py new file mode 100644 index 000000000000..264c78dbcd0d --- /dev/null +++ b/sdk/network/azure-mgmt-network/azure/mgmt/network/_operations_mixin.py @@ -0,0 +1,130 @@ +# 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 import Serializer, Deserializer + + +class NetworkManagementClientOperationsMixin(object): + + + def check_dns_name_availability(self, location, domain_name_label, custom_headers=None, raw=False, **operation_config): + """Checks whether a domain name in the cloudapp.azure.com zone is + available for use. + + :param location: The location of the domain name. + :type location: str + :param domain_name_label: The domain name to be verified. It must + conform to the following regular expression: + ^[a-z][a-z0-9-]{1,61}[a-z0-9]$. + :type domain_name_label: str + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :return: DnsNameAvailabilityResult or ClientRawResponse if raw=true + :rtype: + ~azure.mgmt.network.v2019_04_01.models.DnsNameAvailabilityResult or + ~msrest.pipeline.ClientRawResponse + :raises: :class:`CloudError` + + """ + api_version = self._get_api_version('check_dns_name_availability') + if api_version == '2015-06-15': + from .v2015_06_15.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2016-09-01': + from .v2016_09_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2016-12-01': + from .v2016_12_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2017-03-01': + from .v2017_03_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2017-06-01': + from .v2017_06_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2017-08-01': + from .v2017_08_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2017-09-01': + from .v2017_09_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2017-10-01': + from .v2017_10_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2017-11-01': + from .v2017_11_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2018-01-01': + from .v2018_01_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2018-02-01': + from .v2018_02_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2018-04-01': + from .v2018_04_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2018-06-01': + from .v2018_06_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2018-07-01': + from .v2018_07_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2018-08-01': + from .v2018_08_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2018-10-01': + from .v2018_10_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2018-11-01': + from .v2018_11_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2018-12-01': + from .v2018_12_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2019-02-01': + from .v2019_02_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2019-04-01': + from .v2019_04_01.operations import NetworkManagementClientOperationsMixin as OperationClass + else: + raise NotImplementedError("APIVersion {} is not available".format(api_version)) + mixin_instance = OperationClass() + mixin_instance._client = self._client + mixin_instance.config = self.config + mixin_instance._serialize = Serializer(self._models_dict(api_version)) + mixin_instance._deserialize = Deserializer(self._models_dict(api_version)) + return mixin_instance.check_dns_name_availability(location, domain_name_label, custom_headers, raw, **operation_config) + + def supported_security_providers(self, resource_group_name, virtual_wan_name, custom_headers=None, raw=False, **operation_config): + """Gives the supported security providers for the virtual wan. + + :param resource_group_name: The resource group name. + :type resource_group_name: str + :param virtual_wan_name: The name of the VirtualWAN for which + supported security providers are needed. + :type virtual_wan_name: str + :param dict custom_headers: headers that will be added to the request + :param bool raw: returns the direct response alongside the + deserialized response + :param operation_config: :ref:`Operation configuration + overrides`. + :return: VirtualWanSecurityProviders or ClientRawResponse if raw=true + :rtype: + ~azure.mgmt.network.v2019_04_01.models.VirtualWanSecurityProviders or + ~msrest.pipeline.ClientRawResponse + :raises: + :class:`ErrorException` + + """ + api_version = self._get_api_version('supported_security_providers') + if api_version == '2018-08-01': + from .v2018_08_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2018-10-01': + from .v2018_10_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2018-11-01': + from .v2018_11_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2018-12-01': + from .v2018_12_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2019-02-01': + from .v2019_02_01.operations import NetworkManagementClientOperationsMixin as OperationClass + elif api_version == '2019-04-01': + from .v2019_04_01.operations import NetworkManagementClientOperationsMixin as OperationClass + else: + raise NotImplementedError("APIVersion {} is not available".format(api_version)) + mixin_instance = OperationClass() + mixin_instance._client = self._client + mixin_instance.config = self.config + mixin_instance._serialize = Serializer(self._models_dict(api_version)) + mixin_instance._deserialize = Deserializer(self._models_dict(api_version)) + return mixin_instance.supported_security_providers(resource_group_name, virtual_wan_name, custom_headers, raw, **operation_config) diff --git a/sdk/network/azure-mgmt-network/azure/mgmt/network/models.py b/sdk/network/azure-mgmt-network/azure/mgmt/network/models.py index 96c1d5c91c89..3d6772a11eb3 100644 --- a/sdk/network/azure-mgmt-network/azure/mgmt/network/models.py +++ b/sdk/network/azure-mgmt-network/azure/mgmt/network/models.py @@ -1,7 +1,26 @@ -# coding=utf-8 +# 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 .v2019_04_01.models import * \ No newline at end of file +from .v2015_06_15.models import * +from .v2016_09_01.models import * +from .v2016_12_01.models import * +from .v2017_03_01.models import * +from .v2017_06_01.models import * +from .v2017_08_01.models import * +from .v2017_09_01.models import * +from .v2017_10_01.models import * +from .v2017_11_01.models import * +from .v2018_01_01.models import * +from .v2018_02_01.models import * +from .v2018_04_01.models import * +from .v2018_06_01.models import * +from .v2018_07_01.models import * +from .v2018_08_01.models import * +from .v2018_10_01.models import * +from .v2018_11_01.models import * +from .v2018_12_01.models import * +from .v2019_02_01.models import * +from .v2019_04_01.models import *