From 22dfa54da95ee176e3cbedaf5415f81043f7e001 Mon Sep 17 00:00:00 2001 From: Richard Chen Date: Thu, 5 Feb 2026 15:41:19 +0800 Subject: [PATCH 1/2] Deprecate Neon postgres connection --- .../serviceconnector/_resource_config.py | 5 ++++- .../cli/command_modules/serviceconnector/custom.py | 14 +++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/serviceconnector/_resource_config.py b/src/azure-cli/azure/cli/command_modules/serviceconnector/_resource_config.py index 2ea9d9fd4ef..2a205c6b866 100644 --- a/src/azure-cli/azure/cli/command_modules/serviceconnector/_resource_config.py +++ b/src/azure-cli/azure/cli/command_modules/serviceconnector/_resource_config.py @@ -107,7 +107,10 @@ class CLIENT_TYPE(Enum): TARGET_RESOURCES_CONNECTION_STRING = [RESOURCE.Sql, RESOURCE.Mysql, RESOURCE.MysqlFlexible, RESOURCE.Postgres, RESOURCE.PostgresFlexible] # The target resources to be deprecated -TARGET_RESOURCES_DEPRECATED = [RESOURCE.Mysql, RESOURCE.Postgres] +TARGET_RESOURCES_DEPRECATED = [RESOURCE.Mysql, RESOURCE.Postgres, RESOURCE.NeonPostgres] + +# The target resources to be blocked (deprecated and no longer functional) +TARGET_RESOURCES_BLOCKED = [RESOURCE.NeonPostgres] # The dict defines the resource id pattern of source resources. SOURCE_RESOURCES = { diff --git a/src/azure-cli/azure/cli/command_modules/serviceconnector/custom.py b/src/azure-cli/azure/cli/command_modules/serviceconnector/custom.py index 467d6e98816..c15e257c58e 100644 --- a/src/azure-cli/azure/cli/command_modules/serviceconnector/custom.py +++ b/src/azure-cli/azure/cli/command_modules/serviceconnector/custom.py @@ -22,7 +22,8 @@ TARGET_RESOURCES, AUTH_TYPE, RESOURCE, - OPT_OUT_OPTION + OPT_OUT_OPTION, + TARGET_RESOURCES_BLOCKED ) from ._validators import ( get_source_resource_name, @@ -322,6 +323,12 @@ def connection_create(cmd, client, # pylint: disable=too-many-locals,too-many-s fabric_sql_db_uuid=None, no_recreate=False, ): + # Check if target resource is blocked + target_type = get_target_resource_name(cmd) + if target_type in TARGET_RESOURCES_BLOCKED: + raise ValidationError(f"Creating connections to '{target_type.value}' is no longer supported. " + "This resource type has been deprecated and blocked.") + auth_action = 'optOutAllAuth' if (opt_out_list is not None and OPT_OUT_OPTION.AUTHENTICATION.value in opt_out_list) else None config_action = 'optOut' if (opt_out_list is not None and @@ -705,6 +712,11 @@ def connection_update(cmd, client, # pylint: disable=too-many-locals, too-many- connstr_props=None, # Resource.FabricSql opt_out_list=None, ): + # Check if target resource is blocked + target_type = get_target_resource_name(cmd) + if target_type in TARGET_RESOURCES_BLOCKED: + raise ValidationError(f"Updating connections to '{target_type.value}' is no longer supported. " + "This resource type has been deprecated and blocked.") linker = todict(client.get(resource_uri=source_id, linker_name=connection_name)) From c9a7d5a56080a97a4e2cfc31b35128b054af8b2a Mon Sep 17 00:00:00 2001 From: Richard Chen Date: Fri, 6 Feb 2026 16:22:44 +0800 Subject: [PATCH 2/2] update test --- .../serviceconnector/custom.py | 4 +-- .../latest/test_webpp_connection_scenario.py | 35 ++++++------------- 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/serviceconnector/custom.py b/src/azure-cli/azure/cli/command_modules/serviceconnector/custom.py index c15e257c58e..95120aad34f 100644 --- a/src/azure-cli/azure/cli/command_modules/serviceconnector/custom.py +++ b/src/azure-cli/azure/cli/command_modules/serviceconnector/custom.py @@ -325,7 +325,7 @@ def connection_create(cmd, client, # pylint: disable=too-many-locals,too-many-s ): # Check if target resource is blocked target_type = get_target_resource_name(cmd) - if target_type in TARGET_RESOURCES_BLOCKED: + if target_type and target_type in TARGET_RESOURCES_BLOCKED: raise ValidationError(f"Creating connections to '{target_type.value}' is no longer supported. " "This resource type has been deprecated and blocked.") @@ -714,7 +714,7 @@ def connection_update(cmd, client, # pylint: disable=too-many-locals, too-many- ): # Check if target resource is blocked target_type = get_target_resource_name(cmd) - if target_type in TARGET_RESOURCES_BLOCKED: + if target_type and target_type in TARGET_RESOURCES_BLOCKED: raise ValidationError(f"Updating connections to '{target_type.value}' is no longer supported. " "This resource type has been deprecated and blocked.") diff --git a/src/azure-cli/azure/cli/command_modules/serviceconnector/tests/latest/test_webpp_connection_scenario.py b/src/azure-cli/azure/cli/command_modules/serviceconnector/tests/latest/test_webpp_connection_scenario.py index 65a3c7f3a9f..22c11863e9d 100644 --- a/src/azure-cli/azure/cli/command_modules/serviceconnector/tests/latest/test_webpp_connection_scenario.py +++ b/src/azure-cli/azure/cli/command_modules/serviceconnector/tests/latest/test_webpp_connection_scenario.py @@ -651,9 +651,7 @@ def test_webapp_postgresflexible_e2e(self): # delete connection self.cmd('webapp connection delete --id {} --yes'.format(connection_id)) - - @record_only() - def test_webapp_neon_postgres_e2e(self): + def test_webapp_neon_postgres_blocked(self): self.kwargs.update({ 'subscription': get_subscription_id(self.cli_ctx), 'source_resource_group': 'servicelinker-test-linux-group', @@ -671,29 +669,18 @@ def test_webapp_neon_postgres_e2e(self): server = 'neontest-serve' database = 'testdb' - # create connection - self.cmd('webapp connection create neon-postgres --connection {} --source-id {} --server {} --database {} ' - '--secret name={} secret={} --client-type python'.format(name, source_id, server, database, user, password)) + # verify that creating neon-postgres connection is blocked + with self.assertRaises(Exception) as context: + self.cmd('webapp connection create neon-postgres --connection {} --source-id {} --server {} --database {} ' + '--secret name={} secret={} --client-type python'.format(name, source_id, server, database, user, password)) + self.assertIn('no longer supported', str(context.exception)) - + # verify that updating neon-postgres connection is also blocked connection_id = source_id + "/providers/Microsoft.ServiceLinker/linkers/" + name - - # update connection - self.cmd('webapp connection update neon-postgres --id {} --client-type dotnet ' - '--secret name={} secret={}'.format(connection_id, user, password), - checks = [ self.check('clientType', 'dotnet') ]) - - # list configuration - self.cmd('webapp connection list-configuration --id {}'.format(connection_id)) - - # validate connection - self.cmd('webapp connection validate --id {}'.format(connection_id)) - - # show connection - self.cmd('webapp connection show --id {}'.format(connection_id)) - - # delete connection - self.cmd('webapp connection delete --id {} --yes'.format(connection_id)) + with self.assertRaises(Exception) as context: + self.cmd('webapp connection update neon-postgres --id {} --client-type dotnet ' + '--secret name={} secret={}'.format(connection_id, user, password)) + self.assertIn('no longer supported', str(context.exception)) @record_only() def test_webapp_mongodb_atlas_e2e(self):