Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 4 additions & 0 deletions src/zones/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
Release History
===============

1.0.0b2
++++++
* Minor bugfixes to improve command loading

1.0.0b1
++++++
* Initial preview release.
12 changes: 2 additions & 10 deletions src/zones/azext_zones/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,19 @@
# --------------------------------------------------------------------------------------------


import importlib
from pathlib import Path
from azure.cli.core import AzCommandsLoader
from azext_zones._help import helps # pylint: disable=unused-import

# Import all the resource type validator modules dynamically:
validators_dir = Path(__file__).parent / "resource_type_validators"
for file in validators_dir.glob("*.py"):
if file.name != "__init__.py":
module_name = f".resource_type_validators.{file.stem}"
importlib.import_module(module_name, package=__package__)
from ._resourceTypeValidation import load_validators


class ZonesCommandsLoader(AzCommandsLoader):

def __init__(self, cli_ctx=None):
from azure.cli.core.commands import CliCommandType
from azext_zones._client_factory import cf_zones
zones_custom = CliCommandType(
operations_tmpl='azext_zones.custom#{}',
client_factory=cf_zones)
load_validators()
super(ZonesCommandsLoader, self).__init__(cli_ctx=cli_ctx,
custom_command_type=zones_custom)

Expand Down
2 changes: 1 addition & 1 deletion src/zones/azext_zones/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
examples:
- name: Validate zone redundancy status of all resources in the specified resource group
text: |-
az zones validate --resource-groups myProductionRG --omit-dependent
az zones validate --resource-groups myProductionRG
- name: Validate zone redundancy status of all resources in the specified resource group, but omit the dependent/child resources
text: |-
az zones validate --resource-groups myProductionRG --omit-dependent
Expand Down
32 changes: 32 additions & 0 deletions src/zones/azext_zones/_resourceTypeValidation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------

import importlib
from pathlib import Path
from abc import ABC, abstractmethod
from enum import Enum
from knack.log import get_logger

resource_type_validators = {}
__logger = get_logger(__name__)


# This is the decorator to register resource type validators:
def register_resource_type(resourceType):
__logger.debug("Registering resource type validator for %s", resourceType)

def decorator(cls):
resource_type_validators[resourceType] = cls
return cls
Expand All @@ -25,6 +31,32 @@ def getResourceTypeValidator(resourceType):
return None


def load_validators():
# Import all the resource type validator modules dynamically:
validators_dir = Path(__file__).parent / "resource_type_validators"
__logger.debug("Starting resource type validator module import from %s", validators_dir)

if len(resource_type_validators) > 0:
__logger.debug("Resource type validators already loaded, skipping import.")
return

try:
if validators_dir.exists():
for file in validators_dir.glob("*.py"):
if file.name != "__init__.py":
try:
__logger.debug("Importing resource type validator module: %s", file.name)
module_name = f".resource_type_validators.{file.stem}"
importlib.import_module(module_name, package=__package__)
except ImportError as e:
__logger.warning("Failed to import module %s: %s", module_name, str(e))
else:
__logger.error("Resource type validators directory not found: %s", validators_dir)

except Exception as e: # pylint: disable=broad-except
__logger.warning("Error scanning for resource type validator modules: %s", str(e))


# This is the base class for all resource type validators:
class ResourceTypeValidator(ABC): # pylint: disable=too-few-public-methods`
@abstractmethod
Expand Down
53 changes: 23 additions & 30 deletions src/zones/azext_zones/tests/latest/test_microsoft_apimanagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,38 @@
import os
import unittest

from azure.cli.testsdk import (ScenarioTest)
from ..._resourceTypeValidation import getResourceTypeValidator, ZoneRedundancyValidationResult
from azure.cli.testsdk import ScenarioTest
from ..._resourceTypeValidation import (
getResourceTypeValidator,
load_validators,
ZoneRedundancyValidationResult,
)


class test_microsoft_apimanagement(ScenarioTest):
resource_zr = {
"type": "microsoft.apimanagement/service",
"sku": {"name": "Premium", "capacity": 3},
"zones": ["1", "2", "3"],
}

resource_nonzr = {
"type": "microsoft.apimanagement/service",
"sku": {"name": "Premium", "capacity": 1},
"tags": {},
"zones": None,
}

resource_zr = \
{
"type": "microsoft.apimanagement/service",
"sku": {
"name": "Premium",
"capacity": 3
},
"zones": [
"1",
"2",
"3"
]
}

resource_nonzr = \
{
"type": "microsoft.apimanagement/service",
"sku": {
"name": "Premium",
"capacity": 1
},
"tags": {},
"zones": None
}

validator = None

@classmethod
def setUpClass(cls):
super(test_microsoft_apimanagement, cls).setUpClass()
resourceProvider = cls.resource_zr['type'].split('/')[0]
cls.validator = getResourceTypeValidator(resourceProvider)
# Load the resource type validators
load_validators()

resourceProvider = cls.resource_zr["type"].split("/")[0]
cls.validator = getResourceTypeValidator(resourceProvider)

def test_zr(self):
# Test for zone redundancy scenario
Expand All @@ -54,4 +47,4 @@ def test_zr(self):
def test_nonzr(self):
# Test for non-zone redundancy scenario
zrResult = self.validator.validate(self.resource_nonzr)
self.assertEqual(zrResult, ZoneRedundancyValidationResult.No)
self.assertEqual(zrResult, ZoneRedundancyValidationResult.No)
49 changes: 26 additions & 23 deletions src/zones/azext_zones/tests/latest/test_microsoft_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,41 @@
import os
import unittest

from azure.cli.testsdk import (ScenarioTest)
from ..._resourceTypeValidation import getResourceTypeValidator, ZoneRedundancyValidationResult
from azure.cli.testsdk import ScenarioTest
from ..._resourceTypeValidation import (
getResourceTypeValidator,
load_validators,
ZoneRedundancyValidationResult,
)


class test_microsoft_app(ScenarioTest):
resource_zr = {
"type": "microsoft.app/managedenvironments",
"resourceGroup": "testResourceGroup",
"properties": {
"zoneRedundant": True,
},
}

resource_nonzr = {
"type": "microsoft.app/managedenvironments",
"resourceGroup": "testResourceGroup",
"properties": {
"zoneRedundant": False,
},
}

resource_zr = \
{
"type": "microsoft.app/managedenvironments",
"resourceGroup": "testResourceGroup",
"properties": {
"zoneRedundant": True,
},
}

resource_nonzr = \
{
"type": "microsoft.app/managedenvironments",
"resourceGroup": "testResourceGroup",
"properties": {
"zoneRedundant": False,
},
}

validator = None

@classmethod
def setUpClass(cls):
super(test_microsoft_app, cls).setUpClass()
resourceProvider = cls.resource_zr['type'].split('/')[0]
cls.validator = getResourceTypeValidator(resourceProvider)
# Load the resource type validators
load_validators()

resourceProvider = cls.resource_zr["type"].split("/")[0]
cls.validator = getResourceTypeValidator(resourceProvider)

def test_zr(self):
# Test for zone redundancy scenario
Expand All @@ -47,4 +50,4 @@ def test_zr(self):
def test_nonzr(self):
# Test for non-zone redundancy scenario
zrResult = self.validator.validate(self.resource_nonzr)
self.assertEqual(zrResult, ZoneRedundancyValidationResult.No)
self.assertEqual(zrResult, ZoneRedundancyValidationResult.No)
35 changes: 14 additions & 21 deletions src/zones/azext_zones/tests/latest/test_microsoft_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,29 @@
import os
import unittest

from azure.cli.testsdk import (ScenarioTest)
from ..._resourceTypeValidation import getResourceTypeValidator, ZoneRedundancyValidationResult
from azure.cli.testsdk import ScenarioTest
from ..._resourceTypeValidation import (
getResourceTypeValidator,
load_validators,
ZoneRedundancyValidationResult,
)


class test_microsoft_cache(ScenarioTest):
resource_zr = {"type": "microsoft.cache/redis", "zones": ["1", "2", "3"]}

resource_nonzr = {"type": "microsoft.cache/redis", "zones": None}

resource_zr = \
{
"type": "microsoft.cache/redis",
"zones": [
"1",
"2",
"3"
]
}

resource_nonzr = \
{
"type": "microsoft.cache/redis",
"zones": None
}

validator = None

@classmethod
def setUpClass(cls):
super(test_microsoft_cache, cls).setUpClass()
resourceProvider = cls.resource_zr['type'].split('/')[0]
cls.validator = getResourceTypeValidator(resourceProvider)
# Load the resource type validators
load_validators()

resourceProvider = cls.resource_zr["type"].split("/")[0]
cls.validator = getResourceTypeValidator(resourceProvider)

def test_zr(self):
# Test for zone redundancy scenario
Expand All @@ -45,4 +38,4 @@ def test_zr(self):
def test_nonzr(self):
# Test for non-zone redundancy scenario
zrResult = self.validator.validate(self.resource_nonzr)
self.assertEqual(zrResult, ZoneRedundancyValidationResult.No)
self.assertEqual(zrResult, ZoneRedundancyValidationResult.No)
Loading
Loading