Last active
July 24, 2025 18:36
-
-
Save mkanoor/3502730d4c0a95715d789058d77aafe8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| Settings migrator. | |
| This module handles the migration of AWX settings to Gateway. | |
| """ | |
| from django.conf import settings | |
| from base_migrator import BaseAuthenticatorMigrator | |
| class SettingsMigrator(BaseAuthenticatorMigrator): | |
| """ | |
| Handles the migration of AWX settings to Gateway. | |
| """ | |
| def __init__(self, *args, **kwargs): | |
| super().__init__(*args, **kwargs) | |
| # Define transformer functions for each setting | |
| self.setting_transformers = { | |
| 'SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL': self._transform_social_auth_username_is_full_email, | |
| 'ALLOW_OAUTH2_FOR_EXTERNAL_USERS': self._transform_allow_oauth2_for_external_users, | |
| } | |
| def _convert_setting_name(self, setting): | |
| keys = { | |
| "CUSTOM_LOGIN_INFO": "custom_login_info", | |
| "CUSTOM_LOGO": "custom_logo", | |
| } | |
| return keys.get(setting, setting) | |
| def _transform_social_auth_username_is_full_email(self, value): | |
| # SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL is a boolean and does not need to be transformed | |
| return value | |
| def _transform_allow_oauth2_for_external_users(self, value): | |
| # ALLOW_OAUTH2_FOR_EXTERNAL_USERS is a boolean and does not need to be transformed | |
| return value | |
| def get_authenticator_type(self): | |
| """Get the human-readable authenticator type name.""" | |
| return "Settings" | |
| def get_controller_config(self): | |
| """ | |
| Export relevant AWX settings that need to be migrated to Gateway. | |
| Returns: | |
| list: List of configured settings that need to be migrated | |
| """ | |
| # Define settings that should be migrated from AWX to Gateway | |
| settings_to_migrate = [ | |
| "CUSTOM_LOGIN_INFO", | |
| "CUSTOM_LOGO", | |
| "SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL", | |
| "SESSION_COOKIE_AGE", | |
| "DEFAULT_PAGE_SIZE", | |
| "MAX_PAGE_SIZE", | |
| "ALLOW_OAUTH2_FOR_EXTERNAL_USERS", | |
| "INSIGHTS_TRACKING_STATE", | |
| "REDHAT_USERNAME", | |
| "REDHAT_PASSWORD", | |
| "SUBSCRIPTIONS_USERNAME", | |
| "SUBSCRIPTIONS_PASSWORD", | |
| "AUTOMATION_ANALYTICS_GATHER_INTERVAL", | |
| ] | |
| # Add LOGIN_REDIRECT_OVERRIDE to the list if no authenticator migrator has handled it | |
| if not BaseAuthenticatorMigrator.login_redirect_override_set_by_migrator: | |
| settings_to_migrate.append("LOGIN_REDIRECT_OVERRIDE") | |
| found_configs = [] | |
| for setting_name in settings_to_migrate: | |
| setting_value = getattr(settings, setting_name, None) | |
| # Only include settings that have non-None and non-empty values | |
| if setting_value is not None and setting_value != "": | |
| # Apply transformer function if available | |
| transformer = self.setting_transformers.get(setting_name) | |
| if transformer: | |
| setting_value = transformer(setting_value) | |
| # Skip migration if transformer returned None or empty string | |
| if setting_value is not None and setting_value != "": | |
| found_configs.append( | |
| { | |
| 'category': 'global-settings', | |
| 'setting_name': setting_name, | |
| 'setting_value': setting_value, | |
| 'org_mappers': [], # Settings don't have mappers | |
| 'team_mappers': [], # Settings don't have mappers | |
| 'role_mappers': [], # Settings don't have mappers | |
| 'allow_mappers': [], # Settings don't have mappers | |
| } | |
| ) | |
| else: | |
| self._write_output(f'\nIgnoring {setting_name} because it is None or empty after transformation') | |
| else: | |
| self._write_output(f'\nIgnoring {setting_name} because it is None or empty') | |
| return found_configs | |
| def create_gateway_authenticator(self, config): | |
| """ | |
| Migrate AWX settings to Gateway. | |
| Note: This doesn't create authenticators, but updates Gateway settings. | |
| """ | |
| setting_name = config['setting_name'] | |
| setting_value = config['setting_value'] | |
| self._write_output(f'\n--- Migrating setting: {setting_name} ---') | |
| self._write_output(f'New value: {setting_value}') | |
| try: | |
| gateway_setting_name = self._convert_setting_name(setting_name) | |
| # Use the new update_gateway_setting method | |
| self.gateway_client.update_gateway_setting(gateway_setting_name, setting_value) | |
| self._write_output(f'‚úì Successfully migrated setting: {setting_name}', 'success') | |
| # Return success result in the expected format | |
| return {'success': True, 'action': 'updated', 'error': None} | |
| except Exception as e: | |
| self._write_output(f'‚úó Failed to migrate setting {setting_name}: {str(e)}', 'error') | |
| return {'success': False, 'action': 'failed', 'error': str(e)} | |
| def migrate(self): | |
| """ | |
| Main entry point - orchestrates the settings migration process. | |
| Returns: | |
| dict: Summary of migration results | |
| """ | |
| # Get settings from AWX/Controller | |
| configs = self.get_controller_config() | |
| if not configs: | |
| self._write_output('No settings found to migrate.', 'warning') | |
| return { | |
| 'created': 0, | |
| 'updated': 0, | |
| 'unchanged': 0, | |
| 'failed': 0, | |
| 'mappers_created': 0, | |
| 'mappers_updated': 0, | |
| 'mappers_failed': 0, | |
| 'settings_created': 0, | |
| 'settings_updated': 0, | |
| 'settings_unchanged': 0, | |
| 'settings_failed': 0, | |
| } | |
| self._write_output(f'Found {len(configs)} setting(s) to migrate.', 'success') | |
| # Process each setting | |
| created_settings = [] | |
| updated_settings = [] | |
| unchanged_settings = [] | |
| failed_settings = [] | |
| for config in configs: | |
| result = self.create_gateway_authenticator(config) | |
| if result['success']: | |
| if result['action'] == 'created': | |
| created_settings.append(config) | |
| elif result['action'] == 'updated': | |
| updated_settings.append(config) | |
| elif result['action'] == 'skipped': | |
| unchanged_settings.append(config) | |
| else: | |
| failed_settings.append(config) | |
| # Settings don't have mappers, or authenticators, so authenticator and mapper counts are always 0 | |
| return { | |
| 'created': 0, | |
| 'updated': 0, | |
| 'unchanged': 0, | |
| 'failed': 0, | |
| 'mappers_created': 0, | |
| 'mappers_updated': 0, | |
| 'mappers_failed': 0, | |
| 'settings_created': len(created_settings), | |
| 'settings_updated': len(updated_settings), | |
| 'settings_unchanged': len(unchanged_settings), | |
| 'settings_failed': len(failed_settings), | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment