Submit
Path:
~
/
/
opt
/
psa
/
admin
/
plib
/
modules
/
site-import
/
backend
/
lib
/
python
/
parallels
/
plesk
/
source
/
expand
/
converter
/
File Content:
client.py
from parallels.core.logging import get_logger from parallels.core.logging import log_context from parallels.core import target_data_model from parallels.core.converter.business_objects.clients import ClientsConverter from parallels.core.converter.business_objects.common import format_contact, EntityConverter, SOURCE_TARGET from parallels.core.reports.model.issue import Issue from parallels.core.utils.common import format_multiline_list, group_by_id, group_by, all_str_equals_weak, optimize_values from parallels.plesk.source.expand import messages logger = get_logger(__name__) class ExpandToPleskClientsConverter(object): def convert_clients( self, source_plesk_servers, expand_data, target_panel_clients, clients_mapping, report, password_holder ): """ :type source_plesk_servers: list[parallels.core.global_context.SourceInfo] :type expand_data: parallels.plesk.source.expand.expand_data.model.Model :type target_panel_clients: dict :type clients_mapping: dict[str | unicode, str | unicode | None] :type report: parallels.core.reports.model.report.Report :type password_holder: parallels.core.converter.business_objects.password_holder.PasswordHolderBase """ logger.debug(messages.DEBUG_CONVERT_CLIENTS) plain_converted_clients = self._convert_clients_plain( clients_mapping, expand_data, password_holder, report, source_plesk_servers, target_panel_clients ) clients_by_logins = group_by(plain_converted_clients, lambda c: c.login) merged_clients = self._merge_clients(clients_by_logins, report) self._check_all_clients_from_mapping_are_presented(clients_by_logins, clients_mapping, report) return merged_clients def _convert_clients_plain( self, clients_mapping, expand_data, password_holder, report, source_plesk_servers, target_panel_clients ): """Convert clients from target and source to target model and put them in a plain list :type clients_mapping: dict[str | unicode, str | unicode | None] :type expand_data: parallels.plesk.source.expand.expand_data.model.Model :type report: parallels.core.reports.model.report.Report :type password_holder: parallels.core.converter.business_objects.password_holder.PasswordHolderBase :type source_plesk_servers: list[parallels.core.global_context.SourceInfo] :type target_panel_clients: dict :rtype: list[parallels.core.target_data_model.Client] """ converted_target_clients = self._convert_clients_from_target_panel( clients_mapping, target_panel_clients ) converted_expand_clients = self._convert_expand_clients_from_source( clients_mapping, expand_data ) converted_plesk_clients = self._convert_clients_from_source_plesks( expand_data, clients_mapping, password_holder, report, source_plesk_servers ) converted_clients = sum([ converted_target_clients, converted_expand_clients, converted_plesk_clients ], []) return converted_clients @staticmethod def _convert_clients_from_target_panel(clients_mapping, target_panel_clients): """Convert clients from target panel existing objects model to target model clients :type clients_mapping: dict[str | unicode, str | unicode | None] :type target_panel_clients: dict :rtype: list[parallels.core.target_data_model.Client] """ logger.debug(messages.LOG_CONVERT_CLIENTS_FROM_TARGET_PANEL) converted_clients = [] for client in optimize_values(target_panel_clients): if clients_mapping is None or client.username in clients_mapping: target_model_client = ClientsConverter.create_client_stub_from_existing_client(client) converted_clients.append(target_model_client) return converted_clients @classmethod def _convert_expand_clients_from_source(cls, clients_mapping, expand_data): """Convert Expand clients to target model clients :type clients_mapping: dict[str | unicode, str | unicode | None] :type expand_data: parallels.plesk.source.expand.expand_data.model.Model :rtype: list[parallels.core.target_data_model.Client] """ logger.debug(messages.DEBUG_CONVERT_EXPAND_CLIENTS) converted_clients = [] for expand_client in expand_data.expand_clients: expand_client_login = expand_client.info['login'] if clients_mapping is None or expand_client_login in clients_mapping: converted_client = cls._convert_expand_client(expand_client) converted_clients.append(converted_client) return converted_clients @staticmethod def _convert_clients_from_source_plesks( expand_data, clients_mapping, password_holder, report, source_plesk_servers ): """Convert Plesk clients to target model clients :type expand_data: parallels.plesk.source.expand.expand_data.model.Model :type clients_mapping: dict[str | unicode, str | unicode | None] :type report: parallels.core.reports.model.report.Report :type password_holder: parallels.core.converter.business_objects.password_holder.PasswordHolderBase :type source_plesk_servers: list[parallels.core.global_context.SourceInfo] :rtype: list[parallels.core.target_data_model.Client] """ logger.debug(messages.DEBUG_CONVERT_PLESK_CLIENTS) converted_clients = [] entity_converter = EntityConverter(None) expand_clients_by_id = group_by_id(expand_data.expand_clients, lambda c: c.id) plesk_to_expand_client = dict() for plesk_client in expand_data.plesk_clients: if plesk_client.expand_client_id in expand_clients_by_id: plesk_to_expand_client[( plesk_client.plesk_id, plesk_client.login )] = expand_clients_by_id[plesk_client.expand_client_id] for source_panel_info in source_plesk_servers: backup = source_panel_info.load_raw_dump() for client in backup.iter_all_clients(): if clients_mapping is None or client.login in clients_mapping: if (source_panel_info.id, client.login) not in plesk_to_expand_client: converted_client = entity_converter.create_client_from_plesk_backup_client( client, None, source_panel_info.id, report, password_holder ) converted_clients.append(converted_client) return converted_clients def _merge_clients(self, clients_by_logins, report): """Merge clients - perform conflict resolution when multiple clients have the same login Logic is simple - if they all have the same contact name (first name plus last name) and e-mail, then clients are considered the same single client. Otherwise an error is reported. :type report: parallels.core.reports.model.report.Report :type clients_by_logins: dict[str | unicode, list[parallels.core.target_data_model.Client]] :rtype: list[parallels.core.target_data_model.Client] """ merged_clients = [] logger.debug(messages.DEBUG_MERGE_CLIENTS) for login, clients in clients_by_logins.items(): with log_context(login): if len(clients) == 1: pass # client login is unique, go ahead elif len(clients) > 1: emails = [client.personal_info.email for client in clients] contacts = [format_contact(client.personal_info) for client in clients] differences = [] if not all_str_equals_weak(emails): differences.append(messages.CLIENT_DIFFERENCE_EMAIL) if not all_str_equals_weak(contacts): differences.append(messages.CLIENT_DIFFERENCE_CONTACT) clients_info = dict( login=login, info_list=format_multiline_list([self._format_client(r) for r in clients]) ) if len(differences) > 0: report.add_issue( 'duplicate_client_name_with_another_contact_data', Issue.SEVERITY_ERROR, messages.CLIENT_WITH_SAME_USERNAME_EXISTS.format( difference=u" and ".join(differences), **clients_info ), messages.SOLUTION_REMOVE_DIFFERENCE_BETWEEN_CLIENTS) else: # seems to be same clients pass else: assert False merged_clients.append(clients[0]) return merged_clients @staticmethod def _check_all_clients_from_mapping_are_presented(clients_by_logins, clients_mapping, report): """Check that all clients listed in mapping (migration list) actually exist on source or on target :type clients_by_logins: dict[str | unicode, list[parallels.core.target_data_model.Client]] :type clients_mapping: dict[str | unicode, str | unicode | None] :type report: parallels.core.reports.model.report.Report :rtype: None """ if clients_mapping is not None: for login in clients_mapping: if login not in clients_by_logins: report.add_issue( 'client_is_not_presented_on_panels', Issue.SEVERITY_ERROR, messages.CLIENT_DOES_NOT_EXIST.format( login=login ), messages.SOLUTION_FIX_MIGRATION_LIST ) @staticmethod def _convert_expand_client(expand_client): """Convert Expand model client to target model client :type expand_client: parallels.plesk.source.expand.expand_data.model.ExpandClient :rtype: parallels.core.target_data_model.Client """ locale = expand_client.personal_info.get('locale', None) return target_data_model.Client( login=expand_client.info.get('login'), password=expand_client.info.get('passwd'), company=expand_client.personal_info.get('company'), personal_info=target_data_model.PersonalInfo( first_name=expand_client.personal_info.get('pname'), email=expand_client.personal_info.get('email'), address=expand_client.personal_info.get('address'), city=expand_client.personal_info.get('city'), state=expand_client.personal_info.get('state'), postal_code=expand_client.personal_info.get('zip'), language_code=locale[0:2] if locale is not None else None, locale=locale, country_code=expand_client.personal_info.get('country', 'US'), primary_phone=expand_client.personal_info.get('phone'), fax=expand_client.personal_info.get('fax'), ), is_enabled=expand_client.info.get('status', '1') == '0', source='expand' ) @staticmethod def _format_client(client): """Format information about converted client as a string to put into report :type client: parallels.core.target_data_model.Client :rtype: str | unicode """ if client.source == 'expand': client_type = messages.EXPAND_CLIENT_ON_SOURCE_EXPAND_SERVER elif client.source == SOURCE_TARGET: client_type = messages.CLIENT_ON_TARGET_SERVER else: client_type = messages.PLESK_CLIENT_ON_SOURCE_PLESK_SERVER % client.source return messages.CLIENT_FORMAT % ( client_type, client.login, format_contact(client.personal_info), client.personal_info.email, )
Edit
Rename
Chmod
Delete
FILE
FOLDER
INFO
Name
Size
Permission
Action
__init__.py
0 bytes
0644
client.py
12293 bytes
0644
clients_subscriptions.py
2602 bytes
0644
reseller.py
2747 bytes
0644
subscription.py
4166 bytes
0644
N4ST4R_ID | Naxtarrr