We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
az postgres up does not create the resource group
## Describe the bug
**Tutorial link:** [Deploy a Django web app with PostgreSQL in Azure App Service](https://docs.microsoft.com/en-us/azure/app-service/tutorial-python-postgresql-app?tabs=cmd%2Cclone)

It is expected that the `az postgres up` command creates the resource group if it does not already exist, as mentioned in the [doc](https://docs.microsoft.com/en-us/azure/app-service/tutorial-python-postgresql-app?tabs=cmd%2Cclone#3-create-postgres-database-in-azure).

Running this command on Azure CLI version **2.22.1** and `db-up` extension version **0.2.3** works as expected.
![image](https://user-images.githubusercontent.com/44050820/121654952-de2b3200-cabb-11eb-9d67-de07c7d20097.png)

However, this does not work with the latest Azure CLI version **2.24.2** and `db-up` extension version **0.2.3**.

**Command Name**
`az postgres up
Extension Name: db-up. Version: 0.2.3.`

**Errors:**
```
(ResourceGroupNotFound) Resource group 'DjangoPostgres-tutorial-rg-2242' could not be found.
```

## To Reproduce:
Steps to reproduce the behavior. Note that argument values have been redacted, as they may contain sensitive information.

- Install Azure CLI version `2.24.2`.
- `az postgres up --resource-group {} --location {} --sku-name {} --server-name {} --database-name {} --admin-user {} --admin-password {} --ssl-enforcement {}`

## Expected Behavior
The command should create the specified resource group and proceed with provisioning the postgres db server, as shown in the screenshot above.

## Environment Summary
```
Windows-10-10.0.19041-SP0
Python 3.8.9
Installer: MSI

azure-cli 2.24.2
azure-cli-ml 1.24.0

Extensions:
azure-cli-ml 1.24.0
azure-devops 0.18.0
azure-iot 0.10.9
db-up 0.2.3
mesh 0.10.6
resource-graph 1.1.0
scheduled-query 0.2.0
spring-cloud 1.1.1

```
## Additional Context
GitHub Issue: https://github.com/MicrosoftDocs/azure-docs/issues/76722

<!--Please don't remove this:-->
<!--auto-generated-->

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/db-up/setup.py`
Content:
```
1 #!/usr/bin/env python
2 
3 # --------------------------------------------------------------------------------------------
4 # Copyright (c) Microsoft Corporation. All rights reserved.
5 # Licensed under the MIT License. See License.txt in the project root for license information.
6 # --------------------------------------------------------------------------------------------
7 
8 from codecs import open
9 from setuptools import setup, find_packages
10 
11 VERSION = "0.2.3"
12 
13 CLASSIFIERS = [
14     'Development Status :: 4 - Beta',
15     'Intended Audience :: Developers',
16     'Intended Audience :: System Administrators',
17     'Programming Language :: Python',
18     'Programming Language :: Python :: 3',
19     'Programming Language :: Python :: 3.6',
20     'Programming Language :: Python :: 3.7',
21     'Programming Language :: Python :: 3.8',
22     'License :: OSI Approved :: MIT License',
23 ]
24 
25 DEPENDENCIES = [
26     'Cython==0.29.17',
27     'mysql-connector-python==8.0.14',
28     'psycopg2-binary==2.8.5'
29 ]
30 
31 setup(
32     name='db-up',
33     version=VERSION,
34     description='Additional commands to simplify Azure Database workflows.',
35     long_description='An Azure CLI Extension to provide additional DB commands.',
36     license='MIT',
37     author='Microsoft Corporation',
38     author_email='azpycli@microsoft.com',
39     url='https://github.com/Azure/azure-cli-extensions/tree/master/src/db-up',
40     classifiers=CLASSIFIERS,
41     package_data={'azext_db_up': ['azext_metadata.json', 'random_name/*']},
42     packages=find_packages(exclude=["tests"]),
43     install_requires=DEPENDENCIES
44 )
45
```

Path: `src/db-up/azext_db_up/_validators.py`
Content:
```
1 # --------------------------------------------------------------------------------------------
2 # Copyright (c) Microsoft Corporation. All rights reserved.
3 # Licensed under the MIT License. See License.txt in the project root for license information.
4 # --------------------------------------------------------------------------------------------
5 
6 # pylint: disable=import-error
7 import uuid
8 from six.moves import configparser
9 from azure.cli.core.commands.validators import get_default_location_from_resource_group
10 from azure.mgmt.resource.resources.models import ResourceGroup
11 from knack.log import get_logger
12 from knack.util import CLIError
13 from msrestazure.azure_exceptions import CloudError
14 from msrest.exceptions import ValidationError
15 from azext_db_up._client_factory import resource_client_factory
16 from azext_db_up.random_name.generate import generate_username
17 from azext_db_up.util import create_random_resource_name, get_config_value, set_config_value, remove_config_value
18 
19 logger = get_logger(__name__)
20 
21 DEFAULT_LOCATION = 'westus2'
22 DEFAULT_DATABASE_NAME = 'sampledb'
23 
24 
25 def db_up_namespace_processor(db_type):
26     return lambda cmd, namespace: _process_db_up_namespace(cmd, namespace, db_type=db_type)
27 
28 
29 def db_down_namespace_processor(db_type):
30     return lambda cmd, namespace: _process_db_down_namespace(namespace, db_type=db_type)
31 
32 
33 # pylint: disable=bare-except
34 def _process_db_up_namespace(cmd, namespace, db_type=None):
35     # populate from cache if existing when no resource group name provided
36     resource_client = resource_client_factory(cmd.cli_ctx)
37     if namespace.resource_group_name is None:
38         _set_value(db_type, namespace, 'resource_group_name', 'group', cache=False)
39         try:
40             resource_client.resource_groups.get(namespace.resource_group_name)
41         except:  # Clear resource group name information when it is invalid
42             namespace.resource_group_name = None
43 
44     # populate from cache if existing when no location provided
45     if namespace.location is None:
46         _set_value(db_type, namespace, 'location', 'location', cache=False)
47     # generate smart defaults when namespace.location is None
48     if _get_value(db_type, namespace, 'location', 'location') is None:
49         try:
50             get_default_location_from_resource_group(cmd, namespace)
51         except (CLIError, ValidationError):
52             namespace.location = 'eastus'
53     _set_value(db_type, namespace, 'location', 'location', default=namespace.location)
54 
55     # When resource group name in namespace is different from what in cache, reset it and create new server name
56     if namespace.resource_group_name != get_config_value(db_type, 'group', None):
57         set_config_value(db_type, 'group', namespace.resource_group_name)
58         if namespace.server_name is None:
59             namespace.server_name = create_random_resource_name('server')
60             set_config_value(db_type, 'server', namespace.server_name)
61 
62     # When no resource group name in namespace and cache, create new resource group with random name
63     create_resource_group = True
64     if namespace.resource_group_name is None:  # No resource group provided and in cache
65         namespace.resource_group_name = create_random_resource_name('group')
66     else:
67         try:
68             resource_client.resource_groups.get(namespace.resource_group_name)
69             create_resource_group = False
70         except CloudError:  # throw exception when resource group name is invalid
71             pass
72 
73     if create_resource_group:
74         # create new resource group
75         params = ResourceGroup(location=namespace.location)
76         logger.warning('Creating Resource Group \'%s\'...', namespace.resource_group_name)
77         resource_client.resource_groups.create_or_update(namespace.resource_group_name, params)
78     _set_value(db_type, namespace, 'resource_group_name', 'group', default=namespace.resource_group_name)
79 
80     _set_value(db_type, namespace, 'server_name', 'server', default=create_random_resource_name('server'))
81     _set_value(db_type, namespace, 'administrator_login', 'login', default=generate_username())
82     if namespace.generate_password:
83         namespace.administrator_login_password = str(uuid.uuid4())
84     del namespace.generate_password
85     _set_value(db_type, namespace, 'database_name', 'database', default=DEFAULT_DATABASE_NAME)
86 
87 
88 def _process_db_down_namespace(namespace, db_type=None):
89     # populate from cache if existing
90     if namespace.resource_group_name is None:
91         namespace.resource_group_name = _get_value(db_type, namespace, 'resource_group_name', 'group')
92         remove_config_value(db_type, 'group')
93     if namespace.server_name is None and not namespace.delete_group:
94         namespace.server_name = _get_value(db_type, namespace, 'server_name', 'server')
95         remove_config_value(db_type, 'server')
96         remove_config_value(db_type, 'login')
97         remove_config_value(db_type, 'database')
98         remove_config_value(db_type, 'location')
99 
100     # put resource group info back in config if user does not want to delete it
101     if not namespace.delete_group and namespace.resource_group_name:
102         _set_value(db_type, namespace, 'resource_group_name', 'group')
103 
104     # error handling
105     if namespace.delete_group and not namespace.resource_group_name:
106         raise CLIError("Please specify the resource group name to delete.")
107     if not namespace.delete_group and not namespace.resource_group_name and not namespace.server_name:
108         raise CLIError("Please specify the {} server name to delete and its resource group name if you only want to "
109                        "delete the specific {} server.".format(db_type, db_type))
110 
111 
112 def _set_value(db_type, namespace, attribute, option, default=None, cache=True):
113     if getattr(namespace, attribute) is None:
114         try:
115             if get_config_value(db_type, option):
116                 setattr(namespace, attribute, get_config_value(db_type, option))
117             else:
118                 setattr(namespace, attribute, default)
119         except (configparser.NoSectionError, configparser.NoOptionError):
120             if default is not None:
121                 setattr(namespace, attribute, default)
122     if cache:
123         set_config_value(db_type, option, getattr(namespace, attribute))
124 
125 
126 def _get_value(db_type, namespace, attribute, option):
127     return getattr(namespace, attribute, None) or get_config_value(db_type, option, None)
128
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/db-up/azext_db_up/_validators.py b/src/db-up/azext_db_up/_validators.py
--- a/src/db-up/azext_db_up/_validators.py
+++ b/src/db-up/azext_db_up/_validators.py
@@ -48,7 +48,7 @@
     if _get_value(db_type, namespace, 'location', 'location') is None:
         try:
             get_default_location_from_resource_group(cmd, namespace)
-        except (CLIError, ValidationError):
+        except Exception:
             namespace.location = 'eastus'
     _set_value(db_type, namespace, 'location', 'location', default=namespace.location)
 
@@ -67,7 +67,7 @@
         try:
             resource_client.resource_groups.get(namespace.resource_group_name)
             create_resource_group = False
-        except CloudError:  # throw exception when resource group name is invalid
+        except Exception:  # throw exception when resource group name is invalid
             pass
 
     if create_resource_group:
diff --git a/src/db-up/setup.py b/src/db-up/setup.py
--- a/src/db-up/setup.py
+++ b/src/db-up/setup.py
@@ -8,7 +8,7 @@
 from codecs import open
 from setuptools import setup, find_packages
 
-VERSION = "0.2.3"
+VERSION = "0.2.4"
 
 CLASSIFIERS = [
     'Development Status :: 4 - Beta',

{"golden_diff": "diff --git a/src/db-up/azext_db_up/_validators.py b/src/db-up/azext_db_up/_validators.py\n--- a/src/db-up/azext_db_up/_validators.py\n+++ b/src/db-up/azext_db_up/_validators.py\n@@ -48,7 +48,7 @@\n     if _get_value(db_type, namespace, 'location', 'location') is None:\n         try:\n             get_default_location_from_resource_group(cmd, namespace)\n-        except (CLIError, ValidationError):\n+        except Exception:\n             namespace.location = 'eastus'\n     _set_value(db_type, namespace, 'location', 'location', default=namespace.location)\n \n@@ -67,7 +67,7 @@\n         try:\n             resource_client.resource_groups.get(namespace.resource_group_name)\n             create_resource_group = False\n-        except CloudError:  # throw exception when resource group name is invalid\n+        except Exception:  # throw exception when resource group name is invalid\n             pass\n \n     if create_resource_group:\ndiff --git a/src/db-up/setup.py b/src/db-up/setup.py\n--- a/src/db-up/setup.py\n+++ b/src/db-up/setup.py\n@@ -8,7 +8,7 @@\n from codecs import open\n from setuptools import setup, find_packages\n \n-VERSION = \"0.2.3\"\n+VERSION = \"0.2.4\"\n \n CLASSIFIERS = [\n     'Development Status :: 4 - Beta',\n", "issue": "az postgres up does not create the resource group\n## Describe the bug\r\n**Tutorial link:** [Deploy a Django web app with PostgreSQL in Azure App Service](https://docs.microsoft.com/en-us/azure/app-service/tutorial-python-postgresql-app?tabs=cmd%2Cclone)\r\n\r\nIt is expected that the `az postgres up` command creates the resource group if it does not already exist, as mentioned in the [doc](https://docs.microsoft.com/en-us/azure/app-service/tutorial-python-postgresql-app?tabs=cmd%2Cclone#3-create-postgres-database-in-azure).\r\n\r\nRunning this command on Azure CLI version **2.22.1** and `db-up` extension version **0.2.3** works as expected.\r\n![image](https://user-images.githubusercontent.com/44050820/121654952-de2b3200-cabb-11eb-9d67-de07c7d20097.png)\r\n\r\nHowever, this does not work with the latest Azure CLI version **2.24.2** and `db-up` extension version **0.2.3**.\r\n\r\n**Command Name**\r\n`az postgres up\r\nExtension Name: db-up. Version: 0.2.3.`\r\n\r\n**Errors:**\r\n```\r\n(ResourceGroupNotFound) Resource group 'DjangoPostgres-tutorial-rg-2242' could not be found.\r\n```\r\n\r\n## To Reproduce:\r\nSteps to reproduce the behavior. Note that argument values have been redacted, as they may contain sensitive information.\r\n\r\n- Install Azure CLI version `2.24.2`.\r\n- `az postgres up --resource-group {} --location {} --sku-name {} --server-name {} --database-name {} --admin-user {} --admin-password {} --ssl-enforcement {}`\r\n\r\n## Expected Behavior\r\nThe command should create the specified resource group and proceed with provisioning the postgres db server, as shown in the screenshot above.\r\n\r\n## Environment Summary\r\n```\r\nWindows-10-10.0.19041-SP0\r\nPython 3.8.9\r\nInstaller: MSI\r\n\r\nazure-cli 2.24.2\r\nazure-cli-ml 1.24.0\r\n\r\nExtensions:\r\nazure-cli-ml 1.24.0\r\nazure-devops 0.18.0\r\nazure-iot 0.10.9\r\ndb-up 0.2.3\r\nmesh 0.10.6\r\nresource-graph 1.1.0\r\nscheduled-query 0.2.0\r\nspring-cloud 1.1.1\r\n\r\n```\r\n## Additional Context\r\nGitHub Issue: https://github.com/MicrosoftDocs/azure-docs/issues/76722\r\n\r\n<!--Please don't remove this:-->\r\n<!--auto-generated-->\n", "before_files": [{"content": "#!/usr/bin/env python\n\n# --------------------------------------------------------------------------------------------\n# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License. See License.txt in the project root for license information.\n# --------------------------------------------------------------------------------------------\n\nfrom codecs import open\nfrom setuptools import setup, find_packages\n\nVERSION = \"0.2.3\"\n\nCLASSIFIERS = [\n    'Development Status :: 4 - Beta',\n    'Intended Audience :: Developers',\n    'Intended Audience :: System Administrators',\n    'Programming Language :: Python',\n    'Programming Language :: Python :: 3',\n    'Programming Language :: Python :: 3.6',\n    'Programming Language :: Python :: 3.7',\n    'Programming Language :: Python :: 3.8',\n    'License :: OSI Approved :: MIT License',\n]\n\nDEPENDENCIES = [\n    'Cython==0.29.17',\n    'mysql-connector-python==8.0.14',\n    'psycopg2-binary==2.8.5'\n]\n\nsetup(\n    name='db-up',\n    version=VERSION,\n    description='Additional commands to simplify Azure Database workflows.',\n    long_description='An Azure CLI Extension to provide additional DB commands.',\n    license='MIT',\n    author='Microsoft Corporation',\n    author_email='azpycli@microsoft.com',\n    url='https://github.com/Azure/azure-cli-extensions/tree/master/src/db-up',\n    classifiers=CLASSIFIERS,\n    package_data={'azext_db_up': ['azext_metadata.json', 'random_name/*']},\n    packages=find_packages(exclude=[\"tests\"]),\n    install_requires=DEPENDENCIES\n)\n", "path": "src/db-up/setup.py"}, {"content": "# --------------------------------------------------------------------------------------------\n# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License. See License.txt in the project root for license information.\n# --------------------------------------------------------------------------------------------\n\n# pylint: disable=import-error\nimport uuid\nfrom six.moves import configparser\nfrom azure.cli.core.commands.validators import get_default_location_from_resource_group\nfrom azure.mgmt.resource.resources.models import ResourceGroup\nfrom knack.log import get_logger\nfrom knack.util import CLIError\nfrom msrestazure.azure_exceptions import CloudError\nfrom msrest.exceptions import ValidationError\nfrom azext_db_up._client_factory import resource_client_factory\nfrom azext_db_up.random_name.generate import generate_username\nfrom azext_db_up.util import create_random_resource_name, get_config_value, set_config_value, remove_config_value\n\nlogger = get_logger(__name__)\n\nDEFAULT_LOCATION = 'westus2'\nDEFAULT_DATABASE_NAME = 'sampledb'\n\n\ndef db_up_namespace_processor(db_type):\n    return lambda cmd, namespace: _process_db_up_namespace(cmd, namespace, db_type=db_type)\n\n\ndef db_down_namespace_processor(db_type):\n    return lambda cmd, namespace: _process_db_down_namespace(namespace, db_type=db_type)\n\n\n# pylint: disable=bare-except\ndef _process_db_up_namespace(cmd, namespace, db_type=None):\n    # populate from cache if existing when no resource group name provided\n    resource_client = resource_client_factory(cmd.cli_ctx)\n    if namespace.resource_group_name is None:\n        _set_value(db_type, namespace, 'resource_group_name', 'group', cache=False)\n        try:\n            resource_client.resource_groups.get(namespace.resource_group_name)\n        except:  # Clear resource group name information when it is invalid\n            namespace.resource_group_name = None\n\n    # populate from cache if existing when no location provided\n    if namespace.location is None:\n        _set_value(db_type, namespace, 'location', 'location', cache=False)\n    # generate smart defaults when namespace.location is None\n    if _get_value(db_type, namespace, 'location', 'location') is None:\n        try:\n            get_default_location_from_resource_group(cmd, namespace)\n        except (CLIError, ValidationError):\n            namespace.location = 'eastus'\n    _set_value(db_type, namespace, 'location', 'location', default=namespace.location)\n\n    # When resource group name in namespace is different from what in cache, reset it and create new server name\n    if namespace.resource_group_name != get_config_value(db_type, 'group', None):\n        set_config_value(db_type, 'group', namespace.resource_group_name)\n        if namespace.server_name is None:\n            namespace.server_name = create_random_resource_name('server')\n            set_config_value(db_type, 'server', namespace.server_name)\n\n    # When no resource group name in namespace and cache, create new resource group with random name\n    create_resource_group = True\n    if namespace.resource_group_name is None:  # No resource group provided and in cache\n        namespace.resource_group_name = create_random_resource_name('group')\n    else:\n        try:\n            resource_client.resource_groups.get(namespace.resource_group_name)\n            create_resource_group = False\n        except CloudError:  # throw exception when resource group name is invalid\n            pass\n\n    if create_resource_group:\n        # create new resource group\n        params = ResourceGroup(location=namespace.location)\n        logger.warning('Creating Resource Group \\'%s\\'...', namespace.resource_group_name)\n        resource_client.resource_groups.create_or_update(namespace.resource_group_name, params)\n    _set_value(db_type, namespace, 'resource_group_name', 'group', default=namespace.resource_group_name)\n\n    _set_value(db_type, namespace, 'server_name', 'server', default=create_random_resource_name('server'))\n    _set_value(db_type, namespace, 'administrator_login', 'login', default=generate_username())\n    if namespace.generate_password:\n        namespace.administrator_login_password = str(uuid.uuid4())\n    del namespace.generate_password\n    _set_value(db_type, namespace, 'database_name', 'database', default=DEFAULT_DATABASE_NAME)\n\n\ndef _process_db_down_namespace(namespace, db_type=None):\n    # populate from cache if existing\n    if namespace.resource_group_name is None:\n        namespace.resource_group_name = _get_value(db_type, namespace, 'resource_group_name', 'group')\n        remove_config_value(db_type, 'group')\n    if namespace.server_name is None and not namespace.delete_group:\n        namespace.server_name = _get_value(db_type, namespace, 'server_name', 'server')\n        remove_config_value(db_type, 'server')\n        remove_config_value(db_type, 'login')\n        remove_config_value(db_type, 'database')\n        remove_config_value(db_type, 'location')\n\n    # put resource group info back in config if user does not want to delete it\n    if not namespace.delete_group and namespace.resource_group_name:\n        _set_value(db_type, namespace, 'resource_group_name', 'group')\n\n    # error handling\n    if namespace.delete_group and not namespace.resource_group_name:\n        raise CLIError(\"Please specify the resource group name to delete.\")\n    if not namespace.delete_group and not namespace.resource_group_name and not namespace.server_name:\n        raise CLIError(\"Please specify the {} server name to delete and its resource group name if you only want to \"\n                       \"delete the specific {} server.\".format(db_type, db_type))\n\n\ndef _set_value(db_type, namespace, attribute, option, default=None, cache=True):\n    if getattr(namespace, attribute) is None:\n        try:\n            if get_config_value(db_type, option):\n                setattr(namespace, attribute, get_config_value(db_type, option))\n            else:\n                setattr(namespace, attribute, default)\n        except (configparser.NoSectionError, configparser.NoOptionError):\n            if default is not None:\n                setattr(namespace, attribute, default)\n    if cache:\n        set_config_value(db_type, option, getattr(namespace, attribute))\n\n\ndef _get_value(db_type, namespace, attribute, option):\n    return getattr(namespace, attribute, None) or get_config_value(db_type, option, None)\n", "path": "src/db-up/azext_db_up/_validators.py"}], "after_files": [{"content": "#!/usr/bin/env python\n\n# --------------------------------------------------------------------------------------------\n# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License. See License.txt in the project root for license information.\n# --------------------------------------------------------------------------------------------\n\nfrom codecs import open\nfrom setuptools import setup, find_packages\n\nVERSION = \"0.2.4\"\n\nCLASSIFIERS = [\n    'Development Status :: 4 - Beta',\n    'Intended Audience :: Developers',\n    'Intended Audience :: System Administrators',\n    'Programming Language :: Python',\n    'Programming Language :: Python :: 3',\n    'Programming Language :: Python :: 3.6',\n    'Programming Language :: Python :: 3.7',\n    'Programming Language :: Python :: 3.8',\n    'License :: OSI Approved :: MIT License',\n]\n\nDEPENDENCIES = [\n    'Cython==0.29.17',\n    'mysql-connector-python==8.0.14',\n    'psycopg2-binary==2.8.5'\n]\n\nsetup(\n    name='db-up',\n    version=VERSION,\n    description='Additional commands to simplify Azure Database workflows.',\n    long_description='An Azure CLI Extension to provide additional DB commands.',\n    license='MIT',\n    author='Microsoft Corporation',\n    author_email='azpycli@microsoft.com',\n    url='https://github.com/Azure/azure-cli-extensions/tree/master/src/db-up',\n    classifiers=CLASSIFIERS,\n    package_data={'azext_db_up': ['azext_metadata.json', 'random_name/*']},\n    packages=find_packages(exclude=[\"tests\"]),\n    install_requires=DEPENDENCIES\n)\n", "path": "src/db-up/setup.py"}, {"content": "# --------------------------------------------------------------------------------------------\n# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License. See License.txt in the project root for license information.\n# --------------------------------------------------------------------------------------------\n\n# pylint: disable=import-error\nimport uuid\nfrom six.moves import configparser\nfrom azure.cli.core.commands.validators import get_default_location_from_resource_group\nfrom azure.mgmt.resource.resources.models import ResourceGroup\nfrom knack.log import get_logger\nfrom knack.util import CLIError\nfrom msrestazure.azure_exceptions import CloudError\nfrom msrest.exceptions import ValidationError\nfrom azext_db_up._client_factory import resource_client_factory\nfrom azext_db_up.random_name.generate import generate_username\nfrom azext_db_up.util import create_random_resource_name, get_config_value, set_config_value, remove_config_value\n\nlogger = get_logger(__name__)\n\nDEFAULT_LOCATION = 'westus2'\nDEFAULT_DATABASE_NAME = 'sampledb'\n\n\ndef db_up_namespace_processor(db_type):\n    return lambda cmd, namespace: _process_db_up_namespace(cmd, namespace, db_type=db_type)\n\n\ndef db_down_namespace_processor(db_type):\n    return lambda cmd, namespace: _process_db_down_namespace(namespace, db_type=db_type)\n\n\n# pylint: disable=bare-except\ndef _process_db_up_namespace(cmd, namespace, db_type=None):\n    # populate from cache if existing when no resource group name provided\n    resource_client = resource_client_factory(cmd.cli_ctx)\n    if namespace.resource_group_name is None:\n        _set_value(db_type, namespace, 'resource_group_name', 'group', cache=False)\n        try:\n            resource_client.resource_groups.get(namespace.resource_group_name)\n        except:  # Clear resource group name information when it is invalid\n            namespace.resource_group_name = None\n\n    # populate from cache if existing when no location provided\n    if namespace.location is None:\n        _set_value(db_type, namespace, 'location', 'location', cache=False)\n    # generate smart defaults when namespace.location is None\n    if _get_value(db_type, namespace, 'location', 'location') is None:\n        try:\n            get_default_location_from_resource_group(cmd, namespace)\n        except Exception:\n            namespace.location = 'eastus'\n    _set_value(db_type, namespace, 'location', 'location', default=namespace.location)\n\n    # When resource group name in namespace is different from what in cache, reset it and create new server name\n    if namespace.resource_group_name != get_config_value(db_type, 'group', None):\n        set_config_value(db_type, 'group', namespace.resource_group_name)\n        if namespace.server_name is None:\n            namespace.server_name = create_random_resource_name('server')\n            set_config_value(db_type, 'server', namespace.server_name)\n\n    # When no resource group name in namespace and cache, create new resource group with random name\n    create_resource_group = True\n    if namespace.resource_group_name is None:  # No resource group provided and in cache\n        namespace.resource_group_name = create_random_resource_name('group')\n    else:\n        try:\n            resource_client.resource_groups.get(namespace.resource_group_name)\n            create_resource_group = False\n        except Exception:  # throw exception when resource group name is invalid\n            pass\n\n    if create_resource_group:\n        # create new resource group\n        params = ResourceGroup(location=namespace.location)\n        logger.warning('Creating Resource Group \\'%s\\'...', namespace.resource_group_name)\n        resource_client.resource_groups.create_or_update(namespace.resource_group_name, params)\n    _set_value(db_type, namespace, 'resource_group_name', 'group', default=namespace.resource_group_name)\n\n    _set_value(db_type, namespace, 'server_name', 'server', default=create_random_resource_name('server'))\n    _set_value(db_type, namespace, 'administrator_login', 'login', default=generate_username())\n    if namespace.generate_password:\n        namespace.administrator_login_password = str(uuid.uuid4())\n    del namespace.generate_password\n    _set_value(db_type, namespace, 'database_name', 'database', default=DEFAULT_DATABASE_NAME)\n\n\ndef _process_db_down_namespace(namespace, db_type=None):\n    # populate from cache if existing\n    if namespace.resource_group_name is None:\n        namespace.resource_group_name = _get_value(db_type, namespace, 'resource_group_name', 'group')\n        remove_config_value(db_type, 'group')\n    if namespace.server_name is None and not namespace.delete_group:\n        namespace.server_name = _get_value(db_type, namespace, 'server_name', 'server')\n        remove_config_value(db_type, 'server')\n        remove_config_value(db_type, 'login')\n        remove_config_value(db_type, 'database')\n        remove_config_value(db_type, 'location')\n\n    # put resource group info back in config if user does not want to delete it\n    if not namespace.delete_group and namespace.resource_group_name:\n        _set_value(db_type, namespace, 'resource_group_name', 'group')\n\n    # error handling\n    if namespace.delete_group and not namespace.resource_group_name:\n        raise CLIError(\"Please specify the resource group name to delete.\")\n    if not namespace.delete_group and not namespace.resource_group_name and not namespace.server_name:\n        raise CLIError(\"Please specify the {} server name to delete and its resource group name if you only want to \"\n                       \"delete the specific {} server.\".format(db_type, db_type))\n\n\ndef _set_value(db_type, namespace, attribute, option, default=None, cache=True):\n    if getattr(namespace, attribute) is None:\n        try:\n            if get_config_value(db_type, option):\n                setattr(namespace, attribute, get_config_value(db_type, option))\n            else:\n                setattr(namespace, attribute, default)\n        except (configparser.NoSectionError, configparser.NoOptionError):\n            if default is not None:\n                setattr(namespace, attribute, default)\n    if cache:\n        set_config_value(db_type, option, getattr(namespace, attribute))\n\n\ndef _get_value(db_type, namespace, attribute, option):\n    return getattr(namespace, attribute, None) or get_config_value(db_type, option, None)\n", "path": "src/db-up/azext_db_up/_validators.py"}]}