From ee1192caf251a3f6e013a17f5aef281503507f9b Mon Sep 17 00:00:00 2001 From: Naia Scott Date: Mon, 24 Feb 2025 15:49:24 -0500 Subject: [PATCH 01/12] add to ignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 9c6b9c0edd0..418398caed6 100644 --- a/.gitignore +++ b/.gitignore @@ -122,3 +122,5 @@ cmd_coverage/* # Ignore test results test_results.xml +.githooks/azdev_active.ps1 +.vscode/launch.json From 63700885c776b3a20e60c24b45f5b314494ed8f8 Mon Sep 17 00:00:00 2001 From: Naia Scott Date: Tue, 4 Mar 2025 15:00:57 -0500 Subject: [PATCH 02/12] Fix bug when updating cmk geo --- .../command_modules/rdbms/flexible_server_custom_postgres.py | 4 +++- src/azure-cli/azure/cli/command_modules/rdbms/validators.py | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py index 4517b1d31dc..3fe7596bf48 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py @@ -394,7 +394,9 @@ def flexible_server_update_custom_func(cmd, client, instance, identity, data_encryption = build_identity_and_data_encryption(db_engine='postgres', byok_identity=byok_identity, - byok_key=byok_key) + byok_key=byok_key, + backup_byok_identity=backup_byok_identity, + backup_byok_key=backup_byok_key) auth_config = instance.auth_config administrator_login = instance.administrator_login if instance.administrator_login else None diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/validators.py b/src/azure-cli/azure/cli/command_modules/rdbms/validators.py index ba99ca82d98..82cd419d098 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/validators.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/validators.py @@ -552,6 +552,10 @@ def pg_byok_validator(byok_identity, byok_key, backup_byok_identity=None, backup raise ArgumentUsageError("User assigned identity and keyvault key need to be provided together. " "Please provide --backup-identity and --backup-key together.") + if (byok_identity is None and byok_key is None) and (backup_byok_identity is not None and backup_byok_key is not None): + raise ArgumentUsageError("Primary user assigned identity and keyvault key need to be provided. " + "Please also provide --identity and --key.") + if (instance is not None) and \ not (instance.data_encryption and instance.data_encryption.type == 'AzureKeyVault') and \ (byok_key or backup_byok_key): From 7f198018f1756b4fd5f63ec076232b55ce82192b Mon Sep 17 00:00:00 2001 From: Naia Scott Date: Tue, 4 Mar 2025 17:52:30 -0500 Subject: [PATCH 03/12] Revert "add to ignore" This reverts commit ee1192caf251a3f6e013a17f5aef281503507f9b. --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 418398caed6..9c6b9c0edd0 100644 --- a/.gitignore +++ b/.gitignore @@ -122,5 +122,3 @@ cmd_coverage/* # Ignore test results test_results.xml -.githooks/azdev_active.ps1 -.vscode/launch.json From 3b1d20b74be6e09cb85a8b5789492bab2e6bb0b5 Mon Sep 17 00:00:00 2001 From: Naia Scott Date: Sun, 9 Mar 2025 21:47:32 -0400 Subject: [PATCH 04/12] Updates to not create password if pasword is disabled --- .../rdbms/flexible_server_custom_postgres.py | 54 ++++++++++++------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py index 876f436fb0d..c1b927c9d3b 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py @@ -42,6 +42,7 @@ logger = get_logger(__name__) DEFAULT_DB_NAME = 'flexibleserverdb' +POSTGRES_DB_NAME = 'postgres' DELEGATION_SERVICE_NAME = "Microsoft.DBforPostgreSQL/flexibleServers" RESOURCE_PROVIDER = 'Microsoft.DBforPostgreSQL' @@ -132,7 +133,8 @@ def flexible_server_create(cmd, client, high_availability = postgresql_flexibleservers.models.HighAvailability(mode=high_availability, standby_availability_zone=standby_availability_zone) - administrator_login_password = generate_password(administrator_login_password) + if password_auth is not None and password_auth.lower() != 'disabled': + administrator_login_password = generate_password(administrator_login_password) identity, data_encryption = build_identity_and_data_encryption(db_engine='postgres', byok_identity=byok_identity, @@ -166,12 +168,14 @@ def flexible_server_create(cmd, client, if start_ip != -1 and end_ip != -1: firewall_id = create_firewall_rule(db_context, cmd, resource_group_name, server_name, start_ip, end_ip) - # Create mysql database if it does not exist + # Create database if it does not exist if (database_name is not None or (create_default_db and create_default_db.lower() == 'enabled') and create_cluster != 'ElasticCluster'): db_name = database_name if database_name else DEFAULT_DB_NAME _create_database(db_context, cmd, resource_group_name, server_name, db_name) + else: + db_name = POSTGRES_DB_NAME - user = server_result.administrator_login + user = server_result.administrator_login if server_result.administrator_login else '' server_id = server_result.id loc = server_result.location version = server_result.version @@ -179,17 +183,18 @@ def flexible_server_create(cmd, client, host = server_result.fully_qualified_domain_name subnet_id = None if network is None else network.delegated_subnet_resource_id - logger.warning('Make a note of your password. If you forget, you would have to ' - 'reset your password with "az postgres flexible-server update -n %s -g %s -p ".', - server_name, resource_group_name) + if password_auth is not None and password_auth.lower() != 'disabled': + logger.warning('Make a note of your password. If you forget, you would have to ' + 'reset your password with "az postgres flexible-server update -n %s -g %s -p ".', + server_name, resource_group_name) logger.warning('Try using \'az postgres flexible-server connect\' command to test out connection.') - _update_local_contexts(cmd, server_name, resource_group_name, database_name, location, user) + _update_local_contexts(cmd, server_name, resource_group_name, db_name, location, user) return _form_response(user, sku, loc, server_id, host, version, - administrator_login_password if administrator_login_password is not None else '*****', - _create_postgresql_connection_string(host, user, administrator_login_password, database_name), database_name, firewall_id, - subnet_id) + administrator_login_password, + _create_postgresql_connection_string(host, user, administrator_login_password, db_name), + db_name, firewall_id, subnet_id, password_auth) # endregion create without args @@ -1753,22 +1758,28 @@ def _create_postgresql_connection_strings(host, user, password, database, port): def _create_postgresql_connection_string(host, user, password, database): - connection_kwargs = { - 'user': user, - 'host': host, - 'password': password if password is not None else '{password}', - 'database': database, - } - return 'postgresql://{user}:{password}@{host}/{database}?sslmode=require'.format(**connection_kwargs) + if password: + connection_kwargs = { + 'user': user, + 'host': host, + 'password': password, + 'database': database, + } + return 'postgresql://{user}:{password}@{host}/{database}?sslmode=require'.format(**connection_kwargs) + else: + connection_kwargs = { + 'user': user, + 'host': host, + 'database': database, + } + return 'postgresql://{user}@{host}/{database}?sslmode=require'.format(**connection_kwargs) def _form_response(username, sku, location, server_id, host, version, password, connection_string, database_name, firewall_id=None, - subnet_id=None): + subnet_id=None, password_auth=None): output = { 'host': host, - 'username': username, - 'password': password, 'skuname': sku, 'location': location, 'id': server_id, @@ -1776,6 +1787,9 @@ def _form_response(username, sku, location, server_id, host, version, password, 'databaseName': database_name, 'connectionString': connection_string } + if password_auth is not None and password_auth != "Disabled": + output['username'] = username + output['password'] = password if firewall_id is not None: output['firewallName'] = firewall_id if subnet_id is not None: From 8737f01be80368423c6c6d805e101143eb5e9b74 Mon Sep 17 00:00:00 2001 From: Naia Scott Date: Mon, 10 Mar 2025 14:01:51 -0400 Subject: [PATCH 05/12] Add admin during create --- .../cli/command_modules/rdbms/_params.py | 4 ++ .../rdbms/flexible_server_custom_postgres.py | 45 +++++++++++++------ .../cli/command_modules/rdbms/validators.py | 14 +++++- 3 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/_params.py b/src/azure-cli/azure/cli/command_modules/rdbms/_params.py index 4b9bcead324..793cdc95871 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/_params.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/_params.py @@ -594,6 +594,10 @@ def _flexible_server_params(command_group): c.argument('version', default='16', arg_type=version_arg_type) c.argument('backup_retention', default=7, arg_type=pg_backup_retention_arg_type) c.argument('active_directory_auth', default='Disabled', arg_type=active_directory_auth_arg_type) + c.argument('sid', options_list=['--admin-object-id', '-i'], help='The unique ID of the Azure AD administrator.') + c.argument('login', options_list=['--admin-display-name', '-m'], help='Display name of the Azure AD administrator user or group.') + c.argument('principal_type', options_list=['--admin-type', '-t'], default='User', + arg_type=get_enum_type(['User', 'Group', 'ServicePrincipal', 'Unknown']), help='Type of the Azure AD administrator.') c.argument('password_auth', default='Enabled', arg_type=password_auth_arg_type) c.argument('auto_grow', default='Disabled', arg_type=auto_grow_arg_type) c.argument('storage_type', default=None, arg_type=storage_type_arg_type) diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py index c1b927c9d3b..af8d4e20df0 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py @@ -28,7 +28,7 @@ cf_postgres_check_resource_availability_with_location, \ cf_postgres_flexible_private_dns_zone_suffix_operations, \ cf_postgres_flexible_private_endpoint_connections, \ - cf_postgres_flexible_tuning_options + cf_postgres_flexible_tuning_options, cf_postgres_flexible_adadmin from ._flexible_server_util import generate_missing_parameters, resolve_poller, \ generate_password, parse_maintenance_window, get_current_time, build_identity_and_data_encryption, \ _is_resource_name, get_tenant_id, get_case_insensitive_key_value, get_enum_value_true_false @@ -55,14 +55,15 @@ def flexible_server_create(cmd, client, resource_group_name=None, server_name=None, location=None, backup_retention=None, sku_name=None, tier=None, - storage_gb=None, administrator_login=None, - administrator_login_password=None, version=None, + storage_gb=None, version=None, active_directory_auth=None, + login=None, sid=None, principal_type=None, + password_auth=None, administrator_login=None, administrator_login_password=None, tags=None, database_name=None, subnet=None, subnet_address_prefix=None, vnet=None, vnet_address_prefix=None, private_dns_zone_arguments=None, public_access=None, high_availability=None, zone=None, standby_availability_zone=None, geo_redundant_backup=None, byok_identity=None, byok_key=None, backup_byok_identity=None, backup_byok_key=None, - active_directory_auth=None, password_auth=None, auto_grow=None, performance_tier=None, + auto_grow=None, performance_tier=None, storage_type=None, iops=None, throughput=None, create_default_db='Enabled', create_cluster=None, cluster_size=None, yes=False): if not check_resource_group(resource_group_name): @@ -101,7 +102,9 @@ def flexible_server_create(cmd, client, backup_byok_identity=backup_byok_identity, backup_byok_key=backup_byok_key, performance_tier=performance_tier, - create_cluster=create_cluster) + create_cluster=create_cluster, + active_directory_auth=active_directory_auth, + login=login, sid=sid, principal_type=principal_type,) cluster = None if create_cluster == 'ElasticCluster': @@ -133,7 +136,9 @@ def flexible_server_create(cmd, client, high_availability = postgresql_flexibleservers.models.HighAvailability(mode=high_availability, standby_availability_zone=standby_availability_zone) - if password_auth is not None and password_auth.lower() != 'disabled': + is_password_euth_enabled = True if (password_auth is not None and password_auth.lower() == 'enabled') else False + is_microsoft_entra_auth_enabled = True if (active_directory_auth is not None and active_directory_auth.lower() == 'enabled') else False + if is_password_euth_enabled: administrator_login_password = generate_password(administrator_login_password) identity, data_encryption = build_identity_and_data_encryption(db_engine='postgres', @@ -164,6 +169,12 @@ def flexible_server_create(cmd, client, auth_config=auth_config, cluster=cluster) + # Add Microsoft Entra Admin + if is_microsoft_entra_auth_enabled and login is not None or sid is not None: + server_admin_client = cf_postgres_flexible_adadmin(cmd.cli_ctx, '_') + logger.warning("Add Microsoft Entra Admin '%s'.", login) + _create_admin(server_admin_client, resource_group_name, server_name, login, sid, principal_type) + # Adding firewall rule if start_ip != -1 and end_ip != -1: firewall_id = create_firewall_rule(db_context, cmd, resource_group_name, server_name, start_ip, end_ip) @@ -175,7 +186,8 @@ def flexible_server_create(cmd, client, else: db_name = POSTGRES_DB_NAME - user = server_result.administrator_login if server_result.administrator_login else '' + user = server_result.administrator_login + admin = login server_id = server_result.id loc = server_result.location version = server_result.version @@ -183,7 +195,7 @@ def flexible_server_create(cmd, client, host = server_result.fully_qualified_domain_name subnet_id = None if network is None else network.delegated_subnet_resource_id - if password_auth is not None and password_auth.lower() != 'disabled': + if is_password_euth_enabled: logger.warning('Make a note of your password. If you forget, you would have to ' 'reset your password with "az postgres flexible-server update -n %s -g %s -p ".', server_name, resource_group_name) @@ -193,8 +205,8 @@ def flexible_server_create(cmd, client, return _form_response(user, sku, loc, server_id, host, version, administrator_login_password, - _create_postgresql_connection_string(host, user, administrator_login_password, db_name), - db_name, firewall_id, subnet_id, password_auth) + _create_postgresql_connection_string(host, user, administrator_login_password, db_name, admin), + db_name, firewall_id, subnet_id, password_auth, active_directory_auth, login) # endregion create without args @@ -1090,6 +1102,11 @@ def flexible_server_ad_admin_set(cmd, client, resource_group_name, server_name, if 'replica' in instance.replication_role.lower(): raise CLIError("Cannot create an AD admin on a server with replication role. Use the primary server instead.") + return _create_admin(client, resource_group_name, server_name, login, sid, principal_type, no_wait) + + +# Create Microsoft Entra admin +def _create_admin(client, resource_group_name, server_name, login, sid, principal_type=None, no_wait=False): parameters = { 'principal_name': login, 'tenant_id': get_tenant_id(), @@ -1757,7 +1774,7 @@ def _create_postgresql_connection_strings(host, user, password, database, port): return result -def _create_postgresql_connection_string(host, user, password, database): +def _create_postgresql_connection_string(host, user, password, database, admin=''): if password: connection_kwargs = { 'user': user, @@ -1768,7 +1785,7 @@ def _create_postgresql_connection_string(host, user, password, database): return 'postgresql://{user}:{password}@{host}/{database}?sslmode=require'.format(**connection_kwargs) else: connection_kwargs = { - 'user': user, + 'user': admin, 'host': host, 'database': database, } @@ -1776,7 +1793,7 @@ def _create_postgresql_connection_string(host, user, password, database): def _form_response(username, sku, location, server_id, host, version, password, connection_string, database_name, firewall_id=None, - subnet_id=None, password_auth=None): + subnet_id=None, password_auth=None, active_directory_auth=None, microsoft_admin=None): output = { 'host': host, @@ -1790,6 +1807,8 @@ def _form_response(username, sku, location, server_id, host, version, password, if password_auth is not None and password_auth != "Disabled": output['username'] = username output['password'] = password + if active_directory_auth is not None and active_directory_auth != "Disabled": + output['admin'] = microsoft_admin if firewall_id is not None: output['firewallName'] = firewall_id if subnet_id is not None: diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/validators.py b/src/azure-cli/azure/cli/command_modules/rdbms/validators.py index abe4e645e12..906a10dcfa9 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/validators.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/validators.py @@ -309,7 +309,8 @@ def pg_arguments_validator(db_context, location, tier, sku_name, storage_gb, ser version=None, instance=None, geo_redundant_backup=None, byok_identity=None, byok_key=None, backup_byok_identity=None, backup_byok_key=None, auto_grow=None, performance_tier=None, - storage_type=None, iops=None, throughput=None, create_cluster=None, cluster_size=None): + storage_type=None, iops=None, throughput=None, create_cluster=None, cluster_size=None, + active_directory_auth=None, login=None, sid=None, principal_type=None): validate_server_name(db_context, server_name, 'Microsoft.DBforPostgreSQL/flexibleServers') is_create = not instance if is_create: @@ -349,6 +350,7 @@ def pg_arguments_validator(db_context, location, tier, sku_name, storage_gb, ser _pg_high_availability_validator(high_availability, standby_availability_zone, zone, tier, single_az, instance) _pg_version_validator(version, list_location_capability_info['server_versions'], is_create) pg_byok_validator(byok_identity, byok_key, backup_byok_identity, backup_byok_key, geo_redundant_backup, instance) + _pg_microsoft_entra_validator(active_directory_auth, login, sid, principal_type) def _cluster_validator(create_cluster, cluster_size, auto_grow, geo_redundant_backup, version, tier, @@ -921,6 +923,16 @@ def _pg_storage_type_validator(storage_type, auto_grow, high_availability, geo_r if iops is not None: raise CLIError('Updating storage iops is only capable for server created with Premium SSD v2.') +def _pg_microsoft_entra_validator(active_directory_auth, login, sid, principal_type): + is_microsoft_entra = active_directory_auth is not None and active_directory_auth.lower() == 'enabled' + if not is_microsoft_entra and (login or sid or principal_type): + raise CLIError('To provide values for --object-id, --display-name, or --type ' + 'please set --active-directory-auth to "Enable".') + if is_microsoft_entra and (bool(login is None) ^ bool(sid is None)): + raise CLIError('To add Microsoft Entra admin, please provide values for --object-id and --display-name') + if principal_type is not None and (bool(login is None) or bool(sid is None)): + raise CLIError('To set --admin-type for adding Microsoft Entra admin, please provide values for --object-id and --display-name') + def check_resource_group(resource_group_name): # check if rg is already null originally From 201906ea20ca7e67d3bf4306f44166b0f3f7bd50 Mon Sep 17 00:00:00 2001 From: Naia Scott Date: Mon, 10 Mar 2025 16:44:59 -0400 Subject: [PATCH 06/12] Update text --- .../cli/command_modules/rdbms/_helptext_pg.py | 35 ++++++++++--------- .../cli/command_modules/rdbms/_params.py | 26 +++++++------- .../rdbms/flexible_server_custom_postgres.py | 22 ++++++------ .../cli/command_modules/rdbms/validators.py | 18 +++++----- 4 files changed, 51 insertions(+), 50 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/_helptext_pg.py b/src/azure-cli/azure/cli/command_modules/rdbms/_helptext_pg.py index 5fcb48b66b4..46541a10023 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/_helptext_pg.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/_helptext_pg.py @@ -135,19 +135,20 @@ az postgres flexible-server create -g testGroup -n testServer --location testLocation \\ --key $keyIdentifier --identity testIdentity - name: > - Create a PostgreSQL flexible server with active directory auth as well as password auth. + Create a PostgreSQL flexible server with Microsoft Entra auth as well as password auth. text: > # create flexible server with aad auth and password auth enabled az postgres flexible-server create -g testGroup -n testServer --location testLocation \\ --active-directory-auth Enabled - name: > - Create a PostgreSQL flexible server with active directory auth only. + Create a PostgreSQL flexible server with Microsoft Entra auth only and primary administrator specified. text: > - # create flexible server with aad only auth and password auth disabled + # create flexible server with aad only auth and password auth disabled with primary administrator specified az postgres flexible-server create -g testGroup -n testServer --location testLocation \\ - --active-directory-auth Enabled --password-auth Disabled + --active-directory-auth Enabled --password-auth Disabled \\ + --admin-object-id 00000000-0000-0000-0000-000000000000 --admin-display-name john@contoso.com --admin-type User - name: > Create a PostgreSQL flexible server with public access, geo-redundant backup enabled and add the range of IP address to have access to this server. The --public-access parameter can be 'All', 'None', , or - @@ -256,7 +257,7 @@ text: az postgres flexible-server update --resource-group testGroup --name testserver --tags "k1=v1" "k2=v2" - name: Reset password text: az postgres flexible-server update --resource-group testGroup --name testserver -p password123 - - name: Update a flexible server to enable active directory auth for password auth enabled server + - name: Update a flexible server to enable Microsoft Entra auth for password auth enabled server text: az postgres flexible-server update --resource-group testGroup --name testserver --active-directory-auth Enabled - name: Change key/identity for data encryption. Data encryption cannot be enabled post server creation, this will only update the key/identity. text: > @@ -959,48 +960,48 @@ helps['postgres flexible-server ad-admin'] = """ type: group -short-summary: Manage server Active Directory administrators. +short-summary: Manage server Microsoft Entra administrators. """ helps['postgres flexible-server ad-admin create'] = """ type: command -short-summary: Create an Active Directory administrator. +short-summary: Create a Microsoft Entra administrator. examples: - - name: Create Active Directory administrator with user 'john@contoso.com', administrator ID '00000000-0000-0000-0000-000000000000' and type User. + - name: Create Microsoft Entra administrator with user 'john@contoso.com', administrator ID '00000000-0000-0000-0000-000000000000' and type User. text: az postgres flexible-server ad-admin create -g testgroup -s testsvr -u john@contoso.com -i 00000000-0000-0000-0000-000000000000 -t User """ helps['postgres flexible-server ad-admin delete'] = """ type: command -short-summary: Delete an Active Directory administrator. +short-summary: Delete a Microsoft Entra administrator. examples: - - name: Delete Active Directory administrator with ID '00000000-0000-0000-0000-000000000000'. + - name: Delete Microsoft Entra administrator with ID '00000000-0000-0000-0000-000000000000'. text: az postgres flexible-server ad-admin delete -g testgroup -s testsvr -i 00000000-0000-0000-0000-000000000000 """ helps['postgres flexible-server ad-admin list'] = """ type: command -short-summary: List all Active Directory administrators. +short-summary: List all Microsoft Entra administrators. examples: - - name: List Active Directory administrators. + - name: List Microsoft Entra administrators. text: az postgres flexible-server ad-admin list -g testgroup -s testsvr """ helps['postgres flexible-server ad-admin show'] = """ type: command -short-summary: Get an Active Directory administrator. +short-summary: Get a Microsoft Entra administrator. examples: - - name: Get Active Directory administrator with ID '00000000-0000-0000-0000-000000000000'. + - name: Get Microsoft Entra administrator with ID '00000000-0000-0000-0000-000000000000'. text: az postgres flexible-server ad-admin show -g testgroup -s testsvr -i 00000000-0000-0000-0000-000000000000 """ helps['postgres flexible-server ad-admin wait'] = """ type: command -short-summary: Wait for an Active Directory administrator to satisfy certain conditions. +short-summary: Wait for a Microsoft Entra administrator to satisfy certain conditions. examples: - - name: Wait until an Active Directory administrator exists. + - name: Wait until a Microsoft Entra administrator exists. text: az postgres flexible-server ad-admin wait -g testgroup -s testsvr -i 00000000-0000-0000-0000-000000000000 --exists - - name: Wait for an Active Directory administrator to be deleted. + - name: Wait for a Microsoft Entra administrator to be deleted. text: az postgres flexible-server ad-admin wait -g testgroup -s testsvr -i 00000000-0000-0000-0000-000000000000 --deleted """ diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/_params.py b/src/azure-cli/azure/cli/command_modules/rdbms/_params.py index 793cdc95871..22dbc010e4a 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/_params.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/_params.py @@ -70,7 +70,7 @@ def _complex_params(command_group): # pylint: disable=too-many-statements c.argument('auto_grow', arg_type=get_enum_type(['Enabled', 'Disabled']), options_list=['--auto-grow'], help='Enable or disable autogrow of the storage. Default value is Enabled.') c.argument('auto_scale_iops', arg_type=get_enum_type(['Enabled', 'Disabled']), options_list=['--auto-scale-iops'], help='Enable or disable autoscale of iops. Default value is Disabled.') c.argument('infrastructure_encryption', arg_type=get_enum_type(['Enabled', 'Disabled']), options_list=['--infrastructure-encryption', '-i'], help='Add an optional second layer of encryption for data using new encryption algorithm. Default value is Disabled.') - c.argument('assign_identity', options_list=['--assign-identity'], help='Generate and assign an Azure Active Directory Identity for this server for use with key management services like Azure KeyVault.') + c.argument('assign_identity', options_list=['--assign-identity'], help='Generate and assign an Microsoft Entra Identity for this server for use with key management services like Azure KeyVault.') c.argument('tags', tags_type) if command_group == 'mariadb': @@ -90,7 +90,7 @@ def _complex_params(command_group): # pylint: disable=too-many-statements c.argument('auto_grow', arg_type=get_enum_type(['Enabled', 'Disabled']), options_list=['--auto-grow'], help='Enable or disable autogrow of the storage. Default value is Enabled.') c.argument('auto_scale_iops', arg_type=get_enum_type(['Enabled', 'Disabled']), options_list=['--auto-scale-iops'], help='Enable or disable autogrow of the storage. Default value is Disabled.') c.argument('infrastructure_encryption', arg_type=get_enum_type(['Enabled', 'Disabled']), options_list=['--infrastructure-encryption', '-i'], help='Add an optional second layer of encryption for data using new encryption algorithm. Default value is Disabled.') - c.argument('assign_identity', options_list=['--assign-identity'], help='Generate and assign an Azure Active Directory Identity for this server for use with key management services like Azure KeyVault.') + c.argument('assign_identity', options_list=['--assign-identity'], help='Generate and assign an Microsoft Entra Identity for this server for use with key management services like Azure KeyVault.') c.argument('location', arg_type=get_location_type(self.cli_ctx)) if command_group == 'postgres': @@ -102,7 +102,7 @@ def _complex_params(command_group): # pylint: disable=too-many-statements with self.argument_context('{} server update'.format(command_group)) as c: c.ignore('family', 'capacity', 'tier') c.argument('sku_name', options_list=['--sku-name'], help='The name of the sku. Follows the convention {pricing tier}_{compute generation}_{vCores} in shorthand. Examples: B_Gen5_1, GP_Gen5_4, MO_Gen5_16.') - c.argument('assign_identity', options_list=['--assign-identity'], help='Generate and assign an Azure Active Directory Identity for this server for use with key management services like Azure KeyVault.') + c.argument('assign_identity', options_list=['--assign-identity'], help='Generate and assign an Microsoft Entra Identity for this server for use with key management services like Azure KeyVault.') with self.argument_context('{} server restore'. format(command_group)) as c: c.argument('server_name', options_list=['--name', '-n'], arg_type=overriding_none_arg_type) @@ -211,8 +211,8 @@ def _complex_params(command_group): # pylint: disable=too-many-statements with self.argument_context('{} server ad-admin'.format(command_group)) as c: c.argument('server_name', options_list=['--server-name', '-s']) - c.argument('login', options_list=['--display-name', '-u'], help='Display name of the Azure AD administrator user or group.') - c.argument('sid', options_list=['--object-id', '-i'], help='The unique ID of the Azure AD administrator.') + c.argument('login', options_list=['--display-name', '-u'], help='Display name of the Microsoft Entra administrator user or group.') + c.argument('sid', options_list=['--object-id', '-i'], help='The unique ID of the Microsoft Entra administrator.') if command_group == 'mysql': with self.argument_context('{} server upgrade'.format(command_group)) as c: @@ -529,7 +529,7 @@ def _flexible_server_params(command_group): active_directory_auth_arg_type = CLIArgumentType( options_list=['--active-directory-auth'], arg_type=get_enum_type(['Enabled', 'Disabled']), - help='Whether Azure Active Directory authentication is enabled.' + help='Whether Microsoft Entra authentication is enabled.' ) password_auth_arg_type = CLIArgumentType( @@ -594,10 +594,10 @@ def _flexible_server_params(command_group): c.argument('version', default='16', arg_type=version_arg_type) c.argument('backup_retention', default=7, arg_type=pg_backup_retention_arg_type) c.argument('active_directory_auth', default='Disabled', arg_type=active_directory_auth_arg_type) - c.argument('sid', options_list=['--admin-object-id', '-i'], help='The unique ID of the Azure AD administrator.') - c.argument('login', options_list=['--admin-display-name', '-m'], help='Display name of the Azure AD administrator user or group.') - c.argument('principal_type', options_list=['--admin-type', '-t'], default='User', - arg_type=get_enum_type(['User', 'Group', 'ServicePrincipal', 'Unknown']), help='Type of the Azure AD administrator.') + c.argument('admin_id', options_list=['--admin-object-id', '-i'], help='The unique ID of the Microsoft Entra administrator.') + c.argument('admin_name', options_list=['--admin-display-name', '-m'], help='Display name of the Microsoft Entra administrator user or group.') + c.argument('admin_type', options_list=['--admin-type', '-t'], default='User', + arg_type=get_enum_type(['User', 'Group', 'ServicePrincipal', 'Unknown']), help='Type of the Microsoft Entra administrator.') c.argument('password_auth', default='Enabled', arg_type=password_auth_arg_type) c.argument('auto_grow', default='Disabled', arg_type=auto_grow_arg_type) c.argument('storage_type', default=None, arg_type=storage_type_arg_type) @@ -981,11 +981,11 @@ def _flexible_server_params(command_group): for scope in ['create', 'show', 'delete', 'wait']: with self.argument_context('{} flexible-server ad-admin {}'.format(command_group, scope)) as c: - c.argument('sid', options_list=['--object-id', '-i'], help='The unique ID of the Azure AD administrator.') + c.argument('sid', options_list=['--object-id', '-i'], help='The unique ID of the Microsoft Entra administrator.') with self.argument_context('{} flexible-server ad-admin create'.format(command_group)) as c: - c.argument('login', options_list=['--display-name', '-u'], help='Display name of the Azure AD administrator user or group.') - c.argument('principal_type', options_list=['--type', '-t'], default='User', arg_type=get_enum_type(['User', 'Group', 'ServicePrincipal', 'Unknown']), help='Type of the Azure AD administrator.') + c.argument('login', options_list=['--display-name', '-u'], help='Display name of the Microsoft Entra administrator user or group.') + c.argument('principal_type', options_list=['--type', '-t'], default='User', arg_type=get_enum_type(['User', 'Group', 'ServicePrincipal', 'Unknown']), help='Type of the Microsoft Entra administrator.') c.argument('identity', help='Name or ID of identity used for AAD Authentication.', validator=validate_identity) # server advanced threat protection settings diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py index af8d4e20df0..f820cce6351 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py @@ -56,7 +56,7 @@ def flexible_server_create(cmd, client, location=None, backup_retention=None, sku_name=None, tier=None, storage_gb=None, version=None, active_directory_auth=None, - login=None, sid=None, principal_type=None, + admin_name=None, admin_id=None, admin_type=None, password_auth=None, administrator_login=None, administrator_login_password=None, tags=None, database_name=None, subnet=None, subnet_address_prefix=None, vnet=None, vnet_address_prefix=None, @@ -104,7 +104,7 @@ def flexible_server_create(cmd, client, performance_tier=performance_tier, create_cluster=create_cluster, active_directory_auth=active_directory_auth, - login=login, sid=sid, principal_type=principal_type,) + admin_name=admin_name, admin_id=admin_id, admin_type=admin_type,) cluster = None if create_cluster == 'ElasticCluster': @@ -170,10 +170,10 @@ def flexible_server_create(cmd, client, cluster=cluster) # Add Microsoft Entra Admin - if is_microsoft_entra_auth_enabled and login is not None or sid is not None: + if is_microsoft_entra_auth_enabled and admin_name is not None or admin_id is not None: server_admin_client = cf_postgres_flexible_adadmin(cmd.cli_ctx, '_') - logger.warning("Add Microsoft Entra Admin '%s'.", login) - _create_admin(server_admin_client, resource_group_name, server_name, login, sid, principal_type) + logger.warning("Add Microsoft Entra Admin '%s'.", admin_name) + _create_admin(server_admin_client, resource_group_name, server_name, admin_name, admin_id, admin_type) # Adding firewall rule if start_ip != -1 and end_ip != -1: @@ -187,7 +187,7 @@ def flexible_server_create(cmd, client, db_name = POSTGRES_DB_NAME user = server_result.administrator_login - admin = login + admin = admin_name server_id = server_result.id loc = server_result.location version = server_result.version @@ -206,7 +206,7 @@ def flexible_server_create(cmd, client, return _form_response(user, sku, loc, server_id, host, version, administrator_login_password, _create_postgresql_connection_string(host, user, administrator_login_password, db_name, admin), - db_name, firewall_id, subnet_id, password_auth, active_directory_auth, login) + db_name, firewall_id, subnet_id, password_auth, active_directory_auth, admin_name) # endregion create without args @@ -1100,15 +1100,15 @@ def flexible_server_ad_admin_set(cmd, client, resource_group_name, server_name, instance = server_operations_client.get(resource_group_name, server_name) if 'replica' in instance.replication_role.lower(): - raise CLIError("Cannot create an AD admin on a server with replication role. Use the primary server instead.") + raise CLIError("Cannot create a Microsoft Entra admin on a server with replication role. Use the primary server instead.") return _create_admin(client, resource_group_name, server_name, login, sid, principal_type, no_wait) # Create Microsoft Entra admin -def _create_admin(client, resource_group_name, server_name, login, sid, principal_type=None, no_wait=False): +def _create_admin(client, resource_group_name, server_name, principal_name, sid, principal_type=None, no_wait=False): parameters = { - 'principal_name': login, + 'principal_name': principal_name, 'tenant_id': get_tenant_id(), 'principal_type': principal_type } @@ -1124,7 +1124,7 @@ def flexible_server_ad_admin_delete(cmd, client, resource_group_name, server_nam instance = server_operations_client.get(resource_group_name, server_name) if 'replica' in instance.replication_role.lower(): - raise CLIError("Cannot delete an AD admin on a server with replication role. Use the primary server instead.") + raise CLIError("Cannot delete an Microsoft Entra admin on a server with replication role. Use the primary server instead.") return sdk_no_wait(no_wait, client.begin_delete, resource_group_name, server_name, sid) diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/validators.py b/src/azure-cli/azure/cli/command_modules/rdbms/validators.py index 906a10dcfa9..ee1021f1122 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/validators.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/validators.py @@ -310,7 +310,7 @@ def pg_arguments_validator(db_context, location, tier, sku_name, storage_gb, ser byok_identity=None, byok_key=None, backup_byok_identity=None, backup_byok_key=None, auto_grow=None, performance_tier=None, storage_type=None, iops=None, throughput=None, create_cluster=None, cluster_size=None, - active_directory_auth=None, login=None, sid=None, principal_type=None): + active_directory_auth=None, admin_name=None, admin_id=None, admin_type=None): validate_server_name(db_context, server_name, 'Microsoft.DBforPostgreSQL/flexibleServers') is_create = not instance if is_create: @@ -350,7 +350,7 @@ def pg_arguments_validator(db_context, location, tier, sku_name, storage_gb, ser _pg_high_availability_validator(high_availability, standby_availability_zone, zone, tier, single_az, instance) _pg_version_validator(version, list_location_capability_info['server_versions'], is_create) pg_byok_validator(byok_identity, byok_key, backup_byok_identity, backup_byok_key, geo_redundant_backup, instance) - _pg_microsoft_entra_validator(active_directory_auth, login, sid, principal_type) + _pg_microsoft_entra_validator(active_directory_auth, admin_name, admin_id, admin_type) def _cluster_validator(create_cluster, cluster_size, auto_grow, geo_redundant_backup, version, tier, @@ -923,15 +923,15 @@ def _pg_storage_type_validator(storage_type, auto_grow, high_availability, geo_r if iops is not None: raise CLIError('Updating storage iops is only capable for server created with Premium SSD v2.') -def _pg_microsoft_entra_validator(active_directory_auth, login, sid, principal_type): +def _pg_microsoft_entra_validator(active_directory_auth, admin_name, admin_id, admin_type): is_microsoft_entra = active_directory_auth is not None and active_directory_auth.lower() == 'enabled' - if not is_microsoft_entra and (login or sid or principal_type): - raise CLIError('To provide values for --object-id, --display-name, or --type ' + if not is_microsoft_entra and (admin_name or admin_id or admin_type): + raise CLIError('To provide values for --admin-object-id, --admin-display-name, or --admin-type ' 'please set --active-directory-auth to "Enable".') - if is_microsoft_entra and (bool(login is None) ^ bool(sid is None)): - raise CLIError('To add Microsoft Entra admin, please provide values for --object-id and --display-name') - if principal_type is not None and (bool(login is None) or bool(sid is None)): - raise CLIError('To set --admin-type for adding Microsoft Entra admin, please provide values for --object-id and --display-name') + if is_microsoft_entra and (bool(admin_name is None) ^ bool(admin_id is None)): + raise CLIError('To add Microsoft Entra admin, please provide values for --admin-object-id and --admin-display-name') + if admin_type is not None and (bool(admin_name is None) or bool(admin_id is None)): + raise CLIError('To set --admin-type for adding Microsoft Entra admin, please provide values for --admin-object-id and --admin-display-name') def check_resource_group(resource_group_name): From c087a40cdc445529b1005b6b23ff91812ffc8404 Mon Sep 17 00:00:00 2001 From: Naia Scott Date: Mon, 10 Mar 2025 17:25:52 -0400 Subject: [PATCH 07/12] fixes --- .../cli/command_modules/rdbms/_params.py | 2 +- .../rdbms/flexible_server_custom_postgres.py | 34 +++++++++---------- .../cli/command_modules/rdbms/validators.py | 13 +++---- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/_params.py b/src/azure-cli/azure/cli/command_modules/rdbms/_params.py index 22dbc010e4a..85bf05e742d 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/_params.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/_params.py @@ -596,7 +596,7 @@ def _flexible_server_params(command_group): c.argument('active_directory_auth', default='Disabled', arg_type=active_directory_auth_arg_type) c.argument('admin_id', options_list=['--admin-object-id', '-i'], help='The unique ID of the Microsoft Entra administrator.') c.argument('admin_name', options_list=['--admin-display-name', '-m'], help='Display name of the Microsoft Entra administrator user or group.') - c.argument('admin_type', options_list=['--admin-type', '-t'], default='User', + c.argument('admin_type', options_list=['--admin-type', '-t'], arg_type=get_enum_type(['User', 'Group', 'ServicePrincipal', 'Unknown']), help='Type of the Microsoft Entra administrator.') c.argument('password_auth', default='Enabled', arg_type=password_auth_arg_type) c.argument('auto_grow', default='Disabled', arg_type=auto_grow_arg_type) diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py index f820cce6351..2d19584f400 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py @@ -136,8 +136,8 @@ def flexible_server_create(cmd, client, high_availability = postgresql_flexibleservers.models.HighAvailability(mode=high_availability, standby_availability_zone=standby_availability_zone) - is_password_euth_enabled = True if (password_auth is not None and password_auth.lower() == 'enabled') else False - is_microsoft_entra_auth_enabled = True if (active_directory_auth is not None and active_directory_auth.lower() == 'enabled') else False + is_password_euth_enabled = bool(password_auth is not None and password_auth.lower() == 'enabled') + is_microsoft_entra_auth_enabled = bool(active_directory_auth is not None and active_directory_auth.lower() == 'enabled') if is_password_euth_enabled: administrator_login_password = generate_password(administrator_login_password) @@ -171,9 +171,9 @@ def flexible_server_create(cmd, client, # Add Microsoft Entra Admin if is_microsoft_entra_auth_enabled and admin_name is not None or admin_id is not None: - server_admin_client = cf_postgres_flexible_adadmin(cmd.cli_ctx, '_') - logger.warning("Add Microsoft Entra Admin '%s'.", admin_name) - _create_admin(server_admin_client, resource_group_name, server_name, admin_name, admin_id, admin_type) + server_admin_client = cf_postgres_flexible_adadmin(cmd.cli_ctx, '_') + logger.warning("Add Microsoft Entra Admin '%s'.", admin_name) + _create_admin(server_admin_client, resource_group_name, server_name, admin_name, admin_id, admin_type) # Adding firewall rule if start_ip != -1 and end_ip != -1: @@ -187,7 +187,7 @@ def flexible_server_create(cmd, client, db_name = POSTGRES_DB_NAME user = server_result.administrator_login - admin = admin_name + admin = admin_name if admin_name else '' server_id = server_result.id loc = server_result.location version = server_result.version @@ -197,8 +197,8 @@ def flexible_server_create(cmd, client, if is_password_euth_enabled: logger.warning('Make a note of your password. If you forget, you would have to ' - 'reset your password with "az postgres flexible-server update -n %s -g %s -p ".', - server_name, resource_group_name) + 'reset your password with "az postgres flexible-server update -n %s -g %s -p ".', + server_name, resource_group_name) logger.warning('Try using \'az postgres flexible-server connect\' command to test out connection.') _update_local_contexts(cmd, server_name, resource_group_name, db_name, location, user) @@ -1775,15 +1775,7 @@ def _create_postgresql_connection_strings(host, user, password, database, port): def _create_postgresql_connection_string(host, user, password, database, admin=''): - if password: - connection_kwargs = { - 'user': user, - 'host': host, - 'password': password, - 'database': database, - } - return 'postgresql://{user}:{password}@{host}/{database}?sslmode=require'.format(**connection_kwargs) - else: + if password is None: connection_kwargs = { 'user': admin, 'host': host, @@ -1791,6 +1783,14 @@ def _create_postgresql_connection_string(host, user, password, database, admin=' } return 'postgresql://{user}@{host}/{database}?sslmode=require'.format(**connection_kwargs) + connection_kwargs = { + 'user': user, + 'host': host, + 'password': password, + 'database': database, + } + return 'postgresql://{user}:{password}@{host}/{database}?sslmode=require'.format(**connection_kwargs) + def _form_response(username, sku, location, server_id, host, version, password, connection_string, database_name, firewall_id=None, subnet_id=None, password_auth=None, active_directory_auth=None, microsoft_admin=None): diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/validators.py b/src/azure-cli/azure/cli/command_modules/rdbms/validators.py index ee1021f1122..d336f4ac9b7 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/validators.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/validators.py @@ -923,15 +923,16 @@ def _pg_storage_type_validator(storage_type, auto_grow, high_availability, geo_r if iops is not None: raise CLIError('Updating storage iops is only capable for server created with Premium SSD v2.') + def _pg_microsoft_entra_validator(active_directory_auth, admin_name, admin_id, admin_type): is_microsoft_entra = active_directory_auth is not None and active_directory_auth.lower() == 'enabled' if not is_microsoft_entra and (admin_name or admin_id or admin_type): - raise CLIError('To provide values for --admin-object-id, --admin-display-name, or --admin-type ' - 'please set --active-directory-auth to "Enable".') - if is_microsoft_entra and (bool(admin_name is None) ^ bool(admin_id is None)): - raise CLIError('To add Microsoft Entra admin, please provide values for --admin-object-id and --admin-display-name') - if admin_type is not None and (bool(admin_name is None) or bool(admin_id is None)): - raise CLIError('To set --admin-type for adding Microsoft Entra admin, please provide values for --admin-object-id and --admin-display-name') + raise CLIError('To provide values for --admin-object-id, --admin-display-name, and --admin-type ' + 'please set --active-directory-auth to "Enable".') + if (admin_name is not None or admin_id is not None or admin_type is not None) and\ + not (admin_name is not None and admin_id is not None and admin_type is not None): + raise CLIError('To add Microsoft Entra admin, please provide values for --admin-object-id, ' + '--admin-display-name, and --admin-type.') def check_resource_group(resource_group_name): From e3ceab8a2ec0f7cb6cc05b35ecde2ccce9d77c38 Mon Sep 17 00:00:00 2001 From: Naia Scott Date: Mon, 10 Mar 2025 18:07:33 -0400 Subject: [PATCH 08/12] fix --- src/azure-cli/azure/cli/command_modules/rdbms/validators.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/validators.py b/src/azure-cli/azure/cli/command_modules/rdbms/validators.py index d336f4ac9b7..52d879e9a12 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/validators.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/validators.py @@ -928,7 +928,7 @@ def _pg_microsoft_entra_validator(active_directory_auth, admin_name, admin_id, a is_microsoft_entra = active_directory_auth is not None and active_directory_auth.lower() == 'enabled' if not is_microsoft_entra and (admin_name or admin_id or admin_type): raise CLIError('To provide values for --admin-object-id, --admin-display-name, and --admin-type ' - 'please set --active-directory-auth to "Enable".') + 'please set --active-directory-auth to "Enabled".') if (admin_name is not None or admin_id is not None or admin_type is not None) and\ not (admin_name is not None and admin_id is not None and admin_type is not None): raise CLIError('To add Microsoft Entra admin, please provide values for --admin-object-id, ' From 2c6ad36ef2ba2d33597b75248803a6db0d377d74 Mon Sep 17 00:00:00 2001 From: Naia Scott Date: Mon, 10 Mar 2025 20:37:46 -0400 Subject: [PATCH 09/12] PR comments --- .../rdbms/flexible_server_custom_postgres.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py index 2d19584f400..97f2eb09331 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py @@ -136,9 +136,9 @@ def flexible_server_create(cmd, client, high_availability = postgresql_flexibleservers.models.HighAvailability(mode=high_availability, standby_availability_zone=standby_availability_zone) - is_password_euth_enabled = bool(password_auth is not None and password_auth.lower() == 'enabled') + is_password_auth_enabled = bool(password_auth is not None and password_auth.lower() == 'enabled') is_microsoft_entra_auth_enabled = bool(active_directory_auth is not None and active_directory_auth.lower() == 'enabled') - if is_password_euth_enabled: + if is_password_auth_enabled: administrator_login_password = generate_password(administrator_login_password) identity, data_encryption = build_identity_and_data_encryption(db_engine='postgres', @@ -195,7 +195,7 @@ def flexible_server_create(cmd, client, host = server_result.fully_qualified_domain_name subnet_id = None if network is None else network.delegated_subnet_resource_id - if is_password_euth_enabled: + if is_password_auth_enabled: logger.warning('Make a note of your password. If you forget, you would have to ' 'reset your password with "az postgres flexible-server update -n %s -g %s -p ".', server_name, resource_group_name) @@ -1804,10 +1804,10 @@ def _form_response(username, sku, location, server_id, host, version, password, 'databaseName': database_name, 'connectionString': connection_string } - if password_auth is not None and password_auth != "Disabled": + if password_auth is not None and password_auth.lower() != "disabled": output['username'] = username output['password'] = password - if active_directory_auth is not None and active_directory_auth != "Disabled": + if active_directory_auth is not None and active_directory_auth.lower() != "disabled": output['admin'] = microsoft_admin if firewall_id is not None: output['firewallName'] = firewall_id From f814f53b1f5fa00098778274925cbae7c7eaf479 Mon Sep 17 00:00:00 2001 From: Naia Scott Date: Mon, 10 Mar 2025 22:55:30 -0400 Subject: [PATCH 10/12] PR comments --- .../rdbms/flexible_server_custom_postgres.py | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py index 97f2eb09331..65aeeee7c43 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py @@ -186,7 +186,8 @@ def flexible_server_create(cmd, client, else: db_name = POSTGRES_DB_NAME - user = server_result.administrator_login + user = server_result.administrator_login if is_password_auth_enabled else '' + password = administrator_login_password if is_password_auth_enabled else '' admin = admin_name if admin_name else '' server_id = server_result.id loc = server_result.location @@ -203,10 +204,10 @@ def flexible_server_create(cmd, client, _update_local_contexts(cmd, server_name, resource_group_name, db_name, location, user) - return _form_response(user, sku, loc, server_id, host, version, - administrator_login_password, - _create_postgresql_connection_string(host, user, administrator_login_password, db_name, admin), - db_name, firewall_id, subnet_id, password_auth, active_directory_auth, admin_name) + return _form_response(user, sku, loc, server_id, host, version, password, + _create_postgresql_connection_string(host, user, password, db_name), + db_name, firewall_id, subnet_id, is_password_auth_enabled, is_microsoft_entra_auth_enabled, admin_name, + _create_microsoft_entra_connection_string(host, db_name, admin)) # endregion create without args @@ -1774,29 +1775,31 @@ def _create_postgresql_connection_strings(host, user, password, database, port): return result -def _create_postgresql_connection_string(host, user, password, database, admin=''): - if password is None: - connection_kwargs = { - 'user': admin, - 'host': host, - 'database': database, - } - return 'postgresql://{user}@{host}/{database}?sslmode=require'.format(**connection_kwargs) - +def _create_postgresql_connection_string(host, user, password, database): connection_kwargs = { - 'user': user, + 'user': user if user is not None else '{user}', 'host': host, - 'password': password, + 'password': password if password is not None else '{password}', 'database': database, } return 'postgresql://{user}:{password}@{host}/{database}?sslmode=require'.format(**connection_kwargs) +def _create_microsoft_entra_connection_string(host, database, admin=''): + connection_kwargs = { + 'user': admin, + 'host': host, + 'database': database, + } + return 'postgresql://{user}@{host}/{database}?sslmode=require'.format(**connection_kwargs) + def _form_response(username, sku, location, server_id, host, version, password, connection_string, database_name, firewall_id=None, - subnet_id=None, password_auth=None, active_directory_auth=None, microsoft_admin=None): + subnet_id=None, is_password_auth=True, is_microsoft_entra_auth_enabled=False, microsoft_admin=None, connection_string_microsoft_entra=None): output = { 'host': host, + 'username': username if is_password_auth else None, + 'password': password if is_password_auth else None, 'skuname': sku, 'location': location, 'id': server_id, @@ -1804,11 +1807,9 @@ def _form_response(username, sku, location, server_id, host, version, password, 'databaseName': database_name, 'connectionString': connection_string } - if password_auth is not None and password_auth.lower() != "disabled": - output['username'] = username - output['password'] = password - if active_directory_auth is not None and active_directory_auth.lower() != "disabled": + if is_microsoft_entra_auth_enabled: output['admin'] = microsoft_admin + output['connectionStringMicrosoftEntra'] = connection_string_microsoft_entra if firewall_id is not None: output['firewallName'] = firewall_id if subnet_id is not None: From 04aa6a0adcee92db433434da3347552db5c56349 Mon Sep 17 00:00:00 2001 From: Naia Scott Date: Mon, 10 Mar 2025 23:07:01 -0400 Subject: [PATCH 11/12] lint fix --- .../cli/command_modules/rdbms/flexible_server_custom_postgres.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py index 65aeeee7c43..d37a1c3ea2c 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py @@ -1784,6 +1784,7 @@ def _create_postgresql_connection_string(host, user, password, database): } return 'postgresql://{user}:{password}@{host}/{database}?sslmode=require'.format(**connection_kwargs) + def _create_microsoft_entra_connection_string(host, database, admin=''): connection_kwargs = { 'user': admin, From c0c36b561fc9631e35cec8471ba62aba6ac9a2ae Mon Sep 17 00:00:00 2001 From: Naia Scott Date: Mon, 10 Mar 2025 23:40:59 -0400 Subject: [PATCH 12/12] Revert "Updates to not create password if pasword is disabled" This reverts commit 3b1d20b74be6e09cb85a8b5789492bab2e6bb0b5. --- .../rdbms/flexible_server_custom_postgres.py | 54 +++++++------------ 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py index c1b927c9d3b..876f436fb0d 100644 --- a/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py +++ b/src/azure-cli/azure/cli/command_modules/rdbms/flexible_server_custom_postgres.py @@ -42,7 +42,6 @@ logger = get_logger(__name__) DEFAULT_DB_NAME = 'flexibleserverdb' -POSTGRES_DB_NAME = 'postgres' DELEGATION_SERVICE_NAME = "Microsoft.DBforPostgreSQL/flexibleServers" RESOURCE_PROVIDER = 'Microsoft.DBforPostgreSQL' @@ -133,8 +132,7 @@ def flexible_server_create(cmd, client, high_availability = postgresql_flexibleservers.models.HighAvailability(mode=high_availability, standby_availability_zone=standby_availability_zone) - if password_auth is not None and password_auth.lower() != 'disabled': - administrator_login_password = generate_password(administrator_login_password) + administrator_login_password = generate_password(administrator_login_password) identity, data_encryption = build_identity_and_data_encryption(db_engine='postgres', byok_identity=byok_identity, @@ -168,14 +166,12 @@ def flexible_server_create(cmd, client, if start_ip != -1 and end_ip != -1: firewall_id = create_firewall_rule(db_context, cmd, resource_group_name, server_name, start_ip, end_ip) - # Create database if it does not exist + # Create mysql database if it does not exist if (database_name is not None or (create_default_db and create_default_db.lower() == 'enabled') and create_cluster != 'ElasticCluster'): db_name = database_name if database_name else DEFAULT_DB_NAME _create_database(db_context, cmd, resource_group_name, server_name, db_name) - else: - db_name = POSTGRES_DB_NAME - user = server_result.administrator_login if server_result.administrator_login else '' + user = server_result.administrator_login server_id = server_result.id loc = server_result.location version = server_result.version @@ -183,18 +179,17 @@ def flexible_server_create(cmd, client, host = server_result.fully_qualified_domain_name subnet_id = None if network is None else network.delegated_subnet_resource_id - if password_auth is not None and password_auth.lower() != 'disabled': - logger.warning('Make a note of your password. If you forget, you would have to ' - 'reset your password with "az postgres flexible-server update -n %s -g %s -p ".', - server_name, resource_group_name) + logger.warning('Make a note of your password. If you forget, you would have to ' + 'reset your password with "az postgres flexible-server update -n %s -g %s -p ".', + server_name, resource_group_name) logger.warning('Try using \'az postgres flexible-server connect\' command to test out connection.') - _update_local_contexts(cmd, server_name, resource_group_name, db_name, location, user) + _update_local_contexts(cmd, server_name, resource_group_name, database_name, location, user) return _form_response(user, sku, loc, server_id, host, version, - administrator_login_password, - _create_postgresql_connection_string(host, user, administrator_login_password, db_name), - db_name, firewall_id, subnet_id, password_auth) + administrator_login_password if administrator_login_password is not None else '*****', + _create_postgresql_connection_string(host, user, administrator_login_password, database_name), database_name, firewall_id, + subnet_id) # endregion create without args @@ -1758,28 +1753,22 @@ def _create_postgresql_connection_strings(host, user, password, database, port): def _create_postgresql_connection_string(host, user, password, database): - if password: - connection_kwargs = { - 'user': user, - 'host': host, - 'password': password, - 'database': database, - } - return 'postgresql://{user}:{password}@{host}/{database}?sslmode=require'.format(**connection_kwargs) - else: - connection_kwargs = { - 'user': user, - 'host': host, - 'database': database, - } - return 'postgresql://{user}@{host}/{database}?sslmode=require'.format(**connection_kwargs) + connection_kwargs = { + 'user': user, + 'host': host, + 'password': password if password is not None else '{password}', + 'database': database, + } + return 'postgresql://{user}:{password}@{host}/{database}?sslmode=require'.format(**connection_kwargs) def _form_response(username, sku, location, server_id, host, version, password, connection_string, database_name, firewall_id=None, - subnet_id=None, password_auth=None): + subnet_id=None): output = { 'host': host, + 'username': username, + 'password': password, 'skuname': sku, 'location': location, 'id': server_id, @@ -1787,9 +1776,6 @@ def _form_response(username, sku, location, server_id, host, version, password, 'databaseName': database_name, 'connectionString': connection_string } - if password_auth is not None and password_auth != "Disabled": - output['username'] = username - output['password'] = password if firewall_id is not None: output['firewallName'] = firewall_id if subnet_id is not None: