Adding Azure AD export command (#7010)

This commit is contained in:
John Westcott IV
2025-07-11 11:24:34 -04:00
committed by thedoubl3j
parent 512857c2a9
commit 6b2e9a66d5
2 changed files with 64 additions and 21 deletions

View File

@@ -2,6 +2,7 @@ import sys
import os import os
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from awx.sso.utils.azure_ad_migrator import AzureADMigrator
from awx.sso.utils.github_migrator import GitHubMigrator from awx.sso.utils.github_migrator import GitHubMigrator
from awx.sso.utils.oidc_migrator import OIDCMigrator from awx.sso.utils.oidc_migrator import OIDCMigrator
from awx.sso.utils.saml_migrator import SAMLMigrator from awx.sso.utils.saml_migrator import SAMLMigrator
@@ -14,6 +15,7 @@ class Command(BaseCommand):
def add_arguments(self, parser): def add_arguments(self, parser):
parser.add_argument('--skip-oidc', action='store_true', help='Skip importing GitHub and generic OIDC authenticators') parser.add_argument('--skip-oidc', action='store_true', help='Skip importing GitHub and generic OIDC authenticators')
parser.add_argument('--skip-ldap', action='store_true', help='Skip importing LDAP authenticators') parser.add_argument('--skip-ldap', action='store_true', help='Skip importing LDAP authenticators')
parser.add_argument('--skip-ad', action='store_true', help='Skip importing Azure AD authenticator')
def handle(self, *args, **options): def handle(self, *args, **options):
# Read Gateway connection parameters from environment variables # Read Gateway connection parameters from environment variables
@@ -24,6 +26,7 @@ class Command(BaseCommand):
skip_oidc = options['skip_oidc'] skip_oidc = options['skip_oidc']
# skip_ldap = options['skip_ldap'] # skip_ldap = options['skip_ldap']
skip_ad = options['skip_ad']
# If the management command isn't called with all parameters needed to talk to Gateway, consider # If the management command isn't called with all parameters needed to talk to Gateway, consider
# it a dry-run and exit cleanly # it a dry-run and exit cleanly
@@ -56,6 +59,8 @@ class Command(BaseCommand):
migrators.append(SAMLMigrator(gateway_client, self)) migrators.append(SAMLMigrator(gateway_client, self))
# if not skip_ldap: # if not skip_ldap:
# migrators.append(LDAPMigrator(gateway_client, self)) # migrators.append(LDAPMigrator(gateway_client, self))
if not skip_ad:
migrators.append(AzureADMigrator(gateway_client, self))
# Run migrations # Run migrations
total_results = { total_results = {

View File

@@ -4,6 +4,8 @@ Azure AD authenticator migrator.
This module handles the migration of Azure AD authenticators from AWX to Gateway. This module handles the migration of Azure AD authenticators from AWX to Gateway.
""" """
from django.conf import settings
from awx.main.utils.gateway_mapping import org_map_to_gateway_format, team_map_to_gateway_format
from awx.sso.utils.base_migrator import BaseAuthenticatorMigrator from awx.sso.utils.base_migrator import BaseAuthenticatorMigrator
@@ -24,27 +26,63 @@ class AzureADMigrator(BaseAuthenticatorMigrator):
Returns: Returns:
list: List of configured Azure AD authentication providers with their settings list: List of configured Azure AD authentication providers with their settings
""" """
# TODO: Implement Azure AD configuration retrieval key_value = getattr(settings, 'SOCIAL_AUTH_AZUREAD_OAUTH2_KEY', None)
# Azure AD settings typically include: secret_value = getattr(settings, 'SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET', None)
# - SOCIAL_AUTH_AZUREAD_OAUTH2_KEY
# - SOCIAL_AUTH_AZUREAD_OAUTH2_SECRET # Skip this category if OIDC Key and/or Secret are not configured
# - SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_KEY if not key_value or not secret_value:
# - SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_SECRET return []
# - SOCIAL_AUTH_AZUREAD_TENANT_OAUTH2_TENANT_ID
# - SOCIAL_AUTH_AZUREAD_OAUTH2_ORGANIZATION_MAP # If we have both key and secret, collect all settings
# - SOCIAL_AUTH_AZUREAD_OAUTH2_TEAM_MAP org_map_value = getattr(settings, 'SOCIAL_AUTH_AZUREAD_OAUTH2_ORGANIZATION_MAP', None)
found_configs = [] team_map_value = getattr(settings, 'SOCIAL_AUTH_AZUREAD_OAUTH2_TEAM_MAP', None)
return found_configs
# Convert GitHub org and team mappings from AWX to the Gateway format
# Start with order 1 and maintain sequence across both org and team mappers
org_mappers, next_order = org_map_to_gateway_format(org_map_value, start_order=1)
team_mappers, _ = team_map_to_gateway_format(team_map_value, start_order=next_order)
category = 'AzureAD'
# Generate authenticator name and slug
authenticator_name = "Controller Azure AD"
authenticator_slug = self._generate_authenticator_slug("azure_ad", category, key_value)
return [
{
'category': category,
'settings': {
"name": authenticator_name,
"slug": authenticator_slug,
"type": "ansible_base.authentication.authenticator_plugins.azuread",
"enabled": False,
"create_objects": True,
"remove_users": False,
"configuration": {
"KEY": key_value,
"SECRET": secret_value,
},
},
'org_mappers': org_mappers,
'team_mappers': team_mappers,
}
]
def create_gateway_authenticator(self, config): def create_gateway_authenticator(self, config):
"""Create an Azure AD authenticator in Gateway.""" """Create an Azure AD authenticator in Gateway."""
# TODO: Implement Azure AD authenticator creation
# When implementing, use this pattern for slug generation: category = config["category"]
# client_id = settings.get('SOCIAL_AUTH_AZUREAD_OAUTH2_KEY', 'azure') gateway_config = config["settings"]
# authenticator_slug = self._generate_authenticator_slug('azure_ad', category, client_id)
# Azure AD requires: self._write_output(f"\n--- Processing {category} authenticator ---")
# - Application ID and secret self._write_output(f"Name: {gateway_config['name']}")
# - Tenant ID (for tenant-specific auth) self._write_output(f"Slug: {gateway_config['slug']}")
# - Proper OAuth2 endpoints for Azure self._write_output(f"Type: {gateway_config['type']}")
self._write_output('Azure AD authenticator creation not yet implemented', 'warning')
return False # CALLBACK_URL - automatically created by Gateway
# GROUPS_CLAIM - Not an AWX feature
# ADDITIONAL_UNVERIFIED_ARGS - Not an AWX feature
ignore_keys = ["CALLBACK_URL", "GROUPS_CLAIM"]
# Submit the authenticator (create or update as needed)
return self.submit_authenticator(gateway_config, ignore_keys, config)