prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  make all/tre-deploy fails due to db-migrate
  **Describe the bug**
  Running make `all` (or `tre-deploy` for that matter) fails because it runs `db-migrate` that needs direct access to cosmos.
  
  **Steps to reproduce**
  
  1. Make sure you don't have `ENABLE_LOCAL_DEBUGGING=true` in your .env files
  2. Deploy a new environment by running `make all` or `make tre-deploy`
  3. See that the activity fail due to lack of access to cosmos
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `scripts/db_migrations.py`
  Content:
  ```
  1 #!/usr/local/bin/python3
  2 
  3 from datetime import datetime
  4 import os
  5 from azure.cosmos.cosmos_client import CosmosClient
  6 from azure.mgmt.cosmosdb import CosmosDBManagementClient
  7 from azure.cosmos import PartitionKey
  8 from azure.identity import DefaultAzureCredential
  9 import json
  10 import semantic_version
  11 import uuid
  12 
  13 STATE_STORE_DATABASE = "AzureTRE"
  14 
  15 
  16 class TRECosmosDBMigrations:
  17 
  18     def __init__(self):
  19 
  20         url = os.environ['STATE_STORE_ENDPOINT']
  21         key = self.get_store_key()
  22         self.client = CosmosClient(url=url, credential=key)
  23         self.database = self.client.get_database_client(STATE_STORE_DATABASE)
  24 
  25     def get_store_key(self) -> str:
  26         if 'STATE_STORE_KEY' in os.environ:
  27             primary_master_key = os.getenv('STATE_STORE_KEY')
  28         else:
  29             credential = DefaultAzureCredential()
  30             cosmosdb_client = CosmosDBManagementClient(credential, subscription_id=os.environ['SUBSCRIPTION_ID'])
  31             database_keys = cosmosdb_client.database_accounts.list_keys(resource_group_name=os.environ['RESOURCE_GROUP_NAME'], account_name=os.environ['COSMOSDB_ACCOUNT_NAME'])
  32             primary_master_key = database_keys.primary_master_key
  33 
  34         return primary_master_key
  35 
  36     def renameCosmosDBFields(self, container_name, old_field_name, new_field_name):
  37 
  38         container = self.database.get_container_client(container_name)
  39 
  40         for item in container.query_items(query='SELECT * FROM c', enable_cross_partition_query=True):
  41             print(json.dumps(item, indent=True))
  42             if old_field_name in item:
  43                 item[new_field_name] = item[old_field_name]
  44                 del item[old_field_name]
  45                 container.upsert_item(item)
  46 
  47     def moveDeploymentsToOperations(self, resources_container_name, operations_container_name):
  48         resources_container = self.database.get_container_client(resources_container_name)
  49 
  50         # create operations container if needed
  51         self.database.create_container_if_not_exists(id=operations_container_name, partition_key=PartitionKey(path="/id"))
  52         operations_container = self.database.get_container_client(operations_container_name)
  53 
  54         for item in resources_container.query_items(query='SELECT * FROM c', enable_cross_partition_query=True):
  55             isActive = True
  56             if ("deployment" in item):
  57                 newOperation = {
  58                     "id": str(uuid.uuid4()),
  59                     "resourceId": item["id"],
  60                     "status": item["deployment"]["status"],
  61                     "message": item["deployment"]["message"],
  62                     "resourceVersion": 0,
  63                     "createdWhen": datetime.utcnow().timestamp(),
  64                     "updatedWhen": datetime.utcnow().timestamp()
  65                 }
  66                 operations_container.create_item(newOperation)
  67 
  68                 if item["deployment"]["status"] == "deleted":
  69                     isActive = False
  70 
  71                 del item["deployment"]
  72                 item["isActive"] = isActive
  73                 resources_container.upsert_item(item)
  74                 print(f'Moved deployment from resource id {item["id"]} to operations')
  75 
  76     def deleteDuplicatedSharedServices(self, resource_container_name):
  77         resources_container = self.database.get_container_client(resource_container_name)
  78 
  79         template_names = ['tre-shared-service-firewall', 'tre-shared-service-nexus', 'tre-shared-service-gitea']
  80 
  81         for template_name in template_names:
  82             for item in resources_container.query_items(query=f'SELECT * FROM c WHERE c.resourceType = "shared-service" AND c.templateName = "{template_name}" \
  83                                                                 ORDER BY c.updatedWhen ASC OFFSET 1 LIMIT 10000', enable_cross_partition_query=True):
  84                 print(f"Deleting element {item}")
  85                 resources_container.delete_item(item, partition_key=item["id"])
  86 
  87     def moveAuthInformationToProperties(self, resources_container_name):
  88         resources_container = self.database.get_container_client(resources_container_name)
  89 
  90         for item in resources_container.query_items(query='SELECT * FROM c', enable_cross_partition_query=True):
  91             template_version = semantic_version.Version(item["templateVersion"])
  92             if (template_version > semantic_version.Version('0.3.0') and "authInformation" in item):
  93                 print(f'Found workspace {item["id"]} that needs migrating')
  94 
  95                 # Rename app_id to be client_id
  96                 item["properties"]["client_id"] = item["properties"]["app_id"]
  97                 del item["properties"]["app_id"]
  98                 del item["authInformation"]["app_id"]
  99 
  100                 # merge authInformation into properties
  101                 item["properties"] = {**item["authInformation"], **item["properties"]}
  102                 del item["authInformation"]
  103                 resources_container.upsert_item(item)
  104                 print(f'Upgraded authentication info for workspace id {item["id"]}')
  105 
  106 
  107 def main():
  108     migrations = TRECosmosDBMigrations()
  109     # PR 1030
  110     migrations.renameCosmosDBFields("Resources", 'resourceTemplateName', 'templateName')
  111     migrations.renameCosmosDBFields("Resources", 'resourceTemplateVersion', 'templateVersion')
  112     migrations.renameCosmosDBFields("Resources", 'resourceTemplateParameters', 'properties')
  113 
  114     # PR 1031
  115     migrations.renameCosmosDBFields("Resources", 'workspaceType', 'templateName')
  116     migrations.renameCosmosDBFields("Resources", 'workspaceServiceType', 'templateName')
  117     migrations.renameCosmosDBFields("Resources", 'userResourceType', 'templateName')
  118 
  119     # Operations History
  120     migrations.moveDeploymentsToOperations("Resources", "Operations")
  121 
  122     # Shared services (PR #1717)
  123     migrations.deleteDuplicatedSharedServices("Resources")
  124 
  125     # Authentication needs to be in properties so we can update them. (PR #1726)
  126     migrations.moveAuthInformationToProperties("Resources")
  127 
  128 
  129 if __name__ == "__main__":
  130     main()
  131
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/scripts/db_migrations.py b/scripts/db_migrations.py
  --- a/scripts/db_migrations.py
  +++ b/scripts/db_migrations.py
  @@ -16,11 +16,14 @@
   class TRECosmosDBMigrations:
   
       def __init__(self):
  +        if (self.can_connect_to_cosmos()):
  +            url = os.environ['STATE_STORE_ENDPOINT']
  +            key = self.get_store_key()
  +            self.client = CosmosClient(url=url, credential=key)
  +            self.database = self.client.get_database_client(STATE_STORE_DATABASE)
   
  -        url = os.environ['STATE_STORE_ENDPOINT']
  -        key = self.get_store_key()
  -        self.client = CosmosClient(url=url, credential=key)
  -        self.database = self.client.get_database_client(STATE_STORE_DATABASE)
  +    def can_connect_to_cosmos(self) -> bool:
  +        return os.getenv('ENABLE_LOCAL_DEBUGGING', 'False').lower() in ('true', 1, 't') if 'ENABLE_LOCAL_DEBUGGING' in os.environ else False
   
       def get_store_key(self) -> str:
           if 'STATE_STORE_KEY' in os.environ:
  @@ -106,24 +109,27 @@
   
   def main():
       migrations = TRECosmosDBMigrations()
  -    # PR 1030
  -    migrations.renameCosmosDBFields("Resources", 'resourceTemplateName', 'templateName')
  -    migrations.renameCosmosDBFields("Resources", 'resourceTemplateVersion', 'templateVersion')
  -    migrations.renameCosmosDBFields("Resources", 'resourceTemplateParameters', 'properties')
  -
  -    # PR 1031
  -    migrations.renameCosmosDBFields("Resources", 'workspaceType', 'templateName')
  -    migrations.renameCosmosDBFields("Resources", 'workspaceServiceType', 'templateName')
  -    migrations.renameCosmosDBFields("Resources", 'userResourceType', 'templateName')
  -
  -    # Operations History
  -    migrations.moveDeploymentsToOperations("Resources", "Operations")
  -
  -    # Shared services (PR #1717)
  -    migrations.deleteDuplicatedSharedServices("Resources")
  -
  -    # Authentication needs to be in properties so we can update them. (PR #1726)
  -    migrations.moveAuthInformationToProperties("Resources")
  +    if not migrations.can_connect_to_cosmos():
  +        print('You cannot migrate the cosmos database without setting ENABLE_LOCAL_DEBUGGING to true.')
  +    else:
  +        # PR 1030
  +        migrations.renameCosmosDBFields("Resources", 'resourceTemplateName', 'templateName')
  +        migrations.renameCosmosDBFields("Resources", 'resourceTemplateVersion', 'templateVersion')
  +        migrations.renameCosmosDBFields("Resources", 'resourceTemplateParameters', 'properties')
  +
  +        # PR 1031
  +        migrations.renameCosmosDBFields("Resources", 'workspaceType', 'templateName')
  +        migrations.renameCosmosDBFields("Resources", 'workspaceServiceType', 'templateName')
  +        migrations.renameCosmosDBFields("Resources", 'userResourceType', 'templateName')
  +
  +        # Operations History
  +        migrations.moveDeploymentsToOperations("Resources", "Operations")
  +
  +        # Shared services (PR #1717)
  +        migrations.deleteDuplicatedSharedServices("Resources")
  +
  +        # Authentication needs to be in properties so we can update them. (PR #1726)
  +        migrations.moveAuthInformationToProperties("Resources")
   
   
   if __name__ == "__main__":
  
verification_info: {"golden_diff": "diff --git a/scripts/db_migrations.py b/scripts/db_migrations.py\n--- a/scripts/db_migrations.py\n+++ b/scripts/db_migrations.py\n@@ -16,11 +16,14 @@\n class TRECosmosDBMigrations:\n \n     def __init__(self):\n+        if (self.can_connect_to_cosmos()):\n+            url = os.environ['STATE_STORE_ENDPOINT']\n+            key = self.get_store_key()\n+            self.client = CosmosClient(url=url, credential=key)\n+            self.database = self.client.get_database_client(STATE_STORE_DATABASE)\n \n-        url = os.environ['STATE_STORE_ENDPOINT']\n-        key = self.get_store_key()\n-        self.client = CosmosClient(url=url, credential=key)\n-        self.database = self.client.get_database_client(STATE_STORE_DATABASE)\n+    def can_connect_to_cosmos(self) -> bool:\n+        return os.getenv('ENABLE_LOCAL_DEBUGGING', 'False').lower() in ('true', 1, 't') if 'ENABLE_LOCAL_DEBUGGING' in os.environ else False\n \n     def get_store_key(self) -> str:\n         if 'STATE_STORE_KEY' in os.environ:\n@@ -106,24 +109,27 @@\n \n def main():\n     migrations = TRECosmosDBMigrations()\n-    # PR 1030\n-    migrations.renameCosmosDBFields(\"Resources\", 'resourceTemplateName', 'templateName')\n-    migrations.renameCosmosDBFields(\"Resources\", 'resourceTemplateVersion', 'templateVersion')\n-    migrations.renameCosmosDBFields(\"Resources\", 'resourceTemplateParameters', 'properties')\n-\n-    # PR 1031\n-    migrations.renameCosmosDBFields(\"Resources\", 'workspaceType', 'templateName')\n-    migrations.renameCosmosDBFields(\"Resources\", 'workspaceServiceType', 'templateName')\n-    migrations.renameCosmosDBFields(\"Resources\", 'userResourceType', 'templateName')\n-\n-    # Operations History\n-    migrations.moveDeploymentsToOperations(\"Resources\", \"Operations\")\n-\n-    # Shared services (PR #1717)\n-    migrations.deleteDuplicatedSharedServices(\"Resources\")\n-\n-    # Authentication needs to be in properties so we can update them. (PR #1726)\n-    migrations.moveAuthInformationToProperties(\"Resources\")\n+    if not migrations.can_connect_to_cosmos():\n+        print('You cannot migrate the cosmos database without setting ENABLE_LOCAL_DEBUGGING to true.')\n+    else:\n+        # PR 1030\n+        migrations.renameCosmosDBFields(\"Resources\", 'resourceTemplateName', 'templateName')\n+        migrations.renameCosmosDBFields(\"Resources\", 'resourceTemplateVersion', 'templateVersion')\n+        migrations.renameCosmosDBFields(\"Resources\", 'resourceTemplateParameters', 'properties')\n+\n+        # PR 1031\n+        migrations.renameCosmosDBFields(\"Resources\", 'workspaceType', 'templateName')\n+        migrations.renameCosmosDBFields(\"Resources\", 'workspaceServiceType', 'templateName')\n+        migrations.renameCosmosDBFields(\"Resources\", 'userResourceType', 'templateName')\n+\n+        # Operations History\n+        migrations.moveDeploymentsToOperations(\"Resources\", \"Operations\")\n+\n+        # Shared services (PR #1717)\n+        migrations.deleteDuplicatedSharedServices(\"Resources\")\n+\n+        # Authentication needs to be in properties so we can update them. (PR #1726)\n+        migrations.moveAuthInformationToProperties(\"Resources\")\n \n \n if __name__ == \"__main__\":\n", "issue": "make all/tre-deploy fails due to db-migrate\n**Describe the bug**\r\nRunning make `all` (or `tre-deploy` for that matter) fails because it runs `db-migrate` that needs direct access to cosmos.\r\n\r\n**Steps to reproduce**\r\n\r\n1. Make sure you don't have `ENABLE_LOCAL_DEBUGGING=true` in your .env files\r\n2. Deploy a new environment by running `make all` or `make tre-deploy`\r\n3. See that the activity fail due to lack of access to cosmos\r\n\n", "before_files": [{"content": "#!/usr/local/bin/python3\n\nfrom datetime import datetime\nimport os\nfrom azure.cosmos.cosmos_client import CosmosClient\nfrom azure.mgmt.cosmosdb import CosmosDBManagementClient\nfrom azure.cosmos import PartitionKey\nfrom azure.identity import DefaultAzureCredential\nimport json\nimport semantic_version\nimport uuid\n\nSTATE_STORE_DATABASE = \"AzureTRE\"\n\n\nclass TRECosmosDBMigrations:\n\n    def __init__(self):\n\n        url = os.environ['STATE_STORE_ENDPOINT']\n        key = self.get_store_key()\n        self.client = CosmosClient(url=url, credential=key)\n        self.database = self.client.get_database_client(STATE_STORE_DATABASE)\n\n    def get_store_key(self) -> str:\n        if 'STATE_STORE_KEY' in os.environ:\n            primary_master_key = os.getenv('STATE_STORE_KEY')\n        else:\n            credential = DefaultAzureCredential()\n            cosmosdb_client = CosmosDBManagementClient(credential, subscription_id=os.environ['SUBSCRIPTION_ID'])\n            database_keys = cosmosdb_client.database_accounts.list_keys(resource_group_name=os.environ['RESOURCE_GROUP_NAME'], account_name=os.environ['COSMOSDB_ACCOUNT_NAME'])\n            primary_master_key = database_keys.primary_master_key\n\n        return primary_master_key\n\n    def renameCosmosDBFields(self, container_name, old_field_name, new_field_name):\n\n        container = self.database.get_container_client(container_name)\n\n        for item in container.query_items(query='SELECT * FROM c', enable_cross_partition_query=True):\n            print(json.dumps(item, indent=True))\n            if old_field_name in item:\n                item[new_field_name] = item[old_field_name]\n                del item[old_field_name]\n                container.upsert_item(item)\n\n    def moveDeploymentsToOperations(self, resources_container_name, operations_container_name):\n        resources_container = self.database.get_container_client(resources_container_name)\n\n        # create operations container if needed\n        self.database.create_container_if_not_exists(id=operations_container_name, partition_key=PartitionKey(path=\"/id\"))\n        operations_container = self.database.get_container_client(operations_container_name)\n\n        for item in resources_container.query_items(query='SELECT * FROM c', enable_cross_partition_query=True):\n            isActive = True\n            if (\"deployment\" in item):\n                newOperation = {\n                    \"id\": str(uuid.uuid4()),\n                    \"resourceId\": item[\"id\"],\n                    \"status\": item[\"deployment\"][\"status\"],\n                    \"message\": item[\"deployment\"][\"message\"],\n                    \"resourceVersion\": 0,\n                    \"createdWhen\": datetime.utcnow().timestamp(),\n                    \"updatedWhen\": datetime.utcnow().timestamp()\n                }\n                operations_container.create_item(newOperation)\n\n                if item[\"deployment\"][\"status\"] == \"deleted\":\n                    isActive = False\n\n                del item[\"deployment\"]\n                item[\"isActive\"] = isActive\n                resources_container.upsert_item(item)\n                print(f'Moved deployment from resource id {item[\"id\"]} to operations')\n\n    def deleteDuplicatedSharedServices(self, resource_container_name):\n        resources_container = self.database.get_container_client(resource_container_name)\n\n        template_names = ['tre-shared-service-firewall', 'tre-shared-service-nexus', 'tre-shared-service-gitea']\n\n        for template_name in template_names:\n            for item in resources_container.query_items(query=f'SELECT * FROM c WHERE c.resourceType = \"shared-service\" AND c.templateName = \"{template_name}\" \\\n                                                                ORDER BY c.updatedWhen ASC OFFSET 1 LIMIT 10000', enable_cross_partition_query=True):\n                print(f\"Deleting element {item}\")\n                resources_container.delete_item(item, partition_key=item[\"id\"])\n\n    def moveAuthInformationToProperties(self, resources_container_name):\n        resources_container = self.database.get_container_client(resources_container_name)\n\n        for item in resources_container.query_items(query='SELECT * FROM c', enable_cross_partition_query=True):\n            template_version = semantic_version.Version(item[\"templateVersion\"])\n            if (template_version > semantic_version.Version('0.3.0') and \"authInformation\" in item):\n                print(f'Found workspace {item[\"id\"]} that needs migrating')\n\n                # Rename app_id to be client_id\n                item[\"properties\"][\"client_id\"] = item[\"properties\"][\"app_id\"]\n                del item[\"properties\"][\"app_id\"]\n                del item[\"authInformation\"][\"app_id\"]\n\n                # merge authInformation into properties\n                item[\"properties\"] = {**item[\"authInformation\"], **item[\"properties\"]}\n                del item[\"authInformation\"]\n                resources_container.upsert_item(item)\n                print(f'Upgraded authentication info for workspace id {item[\"id\"]}')\n\n\ndef main():\n    migrations = TRECosmosDBMigrations()\n    # PR 1030\n    migrations.renameCosmosDBFields(\"Resources\", 'resourceTemplateName', 'templateName')\n    migrations.renameCosmosDBFields(\"Resources\", 'resourceTemplateVersion', 'templateVersion')\n    migrations.renameCosmosDBFields(\"Resources\", 'resourceTemplateParameters', 'properties')\n\n    # PR 1031\n    migrations.renameCosmosDBFields(\"Resources\", 'workspaceType', 'templateName')\n    migrations.renameCosmosDBFields(\"Resources\", 'workspaceServiceType', 'templateName')\n    migrations.renameCosmosDBFields(\"Resources\", 'userResourceType', 'templateName')\n\n    # Operations History\n    migrations.moveDeploymentsToOperations(\"Resources\", \"Operations\")\n\n    # Shared services (PR #1717)\n    migrations.deleteDuplicatedSharedServices(\"Resources\")\n\n    # Authentication needs to be in properties so we can update them. (PR #1726)\n    migrations.moveAuthInformationToProperties(\"Resources\")\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "scripts/db_migrations.py"}], "after_files": [{"content": "#!/usr/local/bin/python3\n\nfrom datetime import datetime\nimport os\nfrom azure.cosmos.cosmos_client import CosmosClient\nfrom azure.mgmt.cosmosdb import CosmosDBManagementClient\nfrom azure.cosmos import PartitionKey\nfrom azure.identity import DefaultAzureCredential\nimport json\nimport semantic_version\nimport uuid\n\nSTATE_STORE_DATABASE = \"AzureTRE\"\n\n\nclass TRECosmosDBMigrations:\n\n    def __init__(self):\n        if (self.can_connect_to_cosmos()):\n            url = os.environ['STATE_STORE_ENDPOINT']\n            key = self.get_store_key()\n            self.client = CosmosClient(url=url, credential=key)\n            self.database = self.client.get_database_client(STATE_STORE_DATABASE)\n\n    def can_connect_to_cosmos(self) -> bool:\n        return os.getenv('ENABLE_LOCAL_DEBUGGING', 'False').lower() in ('true', 1, 't') if 'ENABLE_LOCAL_DEBUGGING' in os.environ else False\n\n    def get_store_key(self) -> str:\n        if 'STATE_STORE_KEY' in os.environ:\n            primary_master_key = os.getenv('STATE_STORE_KEY')\n        else:\n            credential = DefaultAzureCredential()\n            cosmosdb_client = CosmosDBManagementClient(credential, subscription_id=os.environ['SUBSCRIPTION_ID'])\n            database_keys = cosmosdb_client.database_accounts.list_keys(resource_group_name=os.environ['RESOURCE_GROUP_NAME'], account_name=os.environ['COSMOSDB_ACCOUNT_NAME'])\n            primary_master_key = database_keys.primary_master_key\n\n        return primary_master_key\n\n    def renameCosmosDBFields(self, container_name, old_field_name, new_field_name):\n\n        container = self.database.get_container_client(container_name)\n\n        for item in container.query_items(query='SELECT * FROM c', enable_cross_partition_query=True):\n            print(json.dumps(item, indent=True))\n            if old_field_name in item:\n                item[new_field_name] = item[old_field_name]\n                del item[old_field_name]\n                container.upsert_item(item)\n\n    def moveDeploymentsToOperations(self, resources_container_name, operations_container_name):\n        resources_container = self.database.get_container_client(resources_container_name)\n\n        # create operations container if needed\n        self.database.create_container_if_not_exists(id=operations_container_name, partition_key=PartitionKey(path=\"/id\"))\n        operations_container = self.database.get_container_client(operations_container_name)\n\n        for item in resources_container.query_items(query='SELECT * FROM c', enable_cross_partition_query=True):\n            isActive = True\n            if (\"deployment\" in item):\n                newOperation = {\n                    \"id\": str(uuid.uuid4()),\n                    \"resourceId\": item[\"id\"],\n                    \"status\": item[\"deployment\"][\"status\"],\n                    \"message\": item[\"deployment\"][\"message\"],\n                    \"resourceVersion\": 0,\n                    \"createdWhen\": datetime.utcnow().timestamp(),\n                    \"updatedWhen\": datetime.utcnow().timestamp()\n                }\n                operations_container.create_item(newOperation)\n\n                if item[\"deployment\"][\"status\"] == \"deleted\":\n                    isActive = False\n\n                del item[\"deployment\"]\n                item[\"isActive\"] = isActive\n                resources_container.upsert_item(item)\n                print(f'Moved deployment from resource id {item[\"id\"]} to operations')\n\n    def deleteDuplicatedSharedServices(self, resource_container_name):\n        resources_container = self.database.get_container_client(resource_container_name)\n\n        template_names = ['tre-shared-service-firewall', 'tre-shared-service-nexus', 'tre-shared-service-gitea']\n\n        for template_name in template_names:\n            for item in resources_container.query_items(query=f'SELECT * FROM c WHERE c.resourceType = \"shared-service\" AND c.templateName = \"{template_name}\" \\\n                                                                ORDER BY c.updatedWhen ASC OFFSET 1 LIMIT 10000', enable_cross_partition_query=True):\n                print(f\"Deleting element {item}\")\n                resources_container.delete_item(item, partition_key=item[\"id\"])\n\n    def moveAuthInformationToProperties(self, resources_container_name):\n        resources_container = self.database.get_container_client(resources_container_name)\n\n        for item in resources_container.query_items(query='SELECT * FROM c', enable_cross_partition_query=True):\n            template_version = semantic_version.Version(item[\"templateVersion\"])\n            if (template_version > semantic_version.Version('0.3.0') and \"authInformation\" in item):\n                print(f'Found workspace {item[\"id\"]} that needs migrating')\n\n                # Rename app_id to be client_id\n                item[\"properties\"][\"client_id\"] = item[\"properties\"][\"app_id\"]\n                del item[\"properties\"][\"app_id\"]\n                del item[\"authInformation\"][\"app_id\"]\n\n                # merge authInformation into properties\n                item[\"properties\"] = {**item[\"authInformation\"], **item[\"properties\"]}\n                del item[\"authInformation\"]\n                resources_container.upsert_item(item)\n                print(f'Upgraded authentication info for workspace id {item[\"id\"]}')\n\n\ndef main():\n    migrations = TRECosmosDBMigrations()\n    if not migrations.can_connect_to_cosmos():\n        print('You cannot migrate the cosmos database without setting ENABLE_LOCAL_DEBUGGING to true.')\n    else:\n        # PR 1030\n        migrations.renameCosmosDBFields(\"Resources\", 'resourceTemplateName', 'templateName')\n        migrations.renameCosmosDBFields(\"Resources\", 'resourceTemplateVersion', 'templateVersion')\n        migrations.renameCosmosDBFields(\"Resources\", 'resourceTemplateParameters', 'properties')\n\n        # PR 1031\n        migrations.renameCosmosDBFields(\"Resources\", 'workspaceType', 'templateName')\n        migrations.renameCosmosDBFields(\"Resources\", 'workspaceServiceType', 'templateName')\n        migrations.renameCosmosDBFields(\"Resources\", 'userResourceType', 'templateName')\n\n        # Operations History\n        migrations.moveDeploymentsToOperations(\"Resources\", \"Operations\")\n\n        # Shared services (PR #1717)\n        migrations.deleteDuplicatedSharedServices(\"Resources\")\n\n        # Authentication needs to be in properties so we can update them. (PR #1726)\n        migrations.moveAuthInformationToProperties(\"Resources\")\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "scripts/db_migrations.py"}]}