def validate_importer_config(repo_obj, importer_type_id, config): """ Validates the importer configuration. :param repo_obj: repository object :type repo_obj: pulp.server.db.model.Repository :param importer_type_id: type of importer, must correspond to a plugin loaded at server startup :type importer_type_id: str :param config: configuration values for the importer :type config: dict :raises PulpCodedValidationException: if importer_type_id is invalid :raises exceptions.PulpDataException: if config is invalid. """ if not plugin_api.is_valid_importer(importer_type_id): raise exceptions.PulpCodedValidationException( error_code=error_codes.PLP1008, importer_type_id=importer_type_id) importer_instance, plugin_config = plugin_api.get_importer_by_id( importer_type_id) call_config = PluginCallConfiguration(plugin_config, config) transfer_repo = repo_obj.to_transfer_repo() result = importer_instance.validate_config(transfer_repo, call_config) # For backward compatibility with plugins that don't yet return the tuple if isinstance(result, bool): valid_config = result message = None else: valid_config, message = result if not valid_config: raise exceptions.PulpDataException(message)
def POST(self, repo_id): # Params params = self.params() query = params.get('criteria', {}) options = params.get('options', {}) timeout = params.get('timeout', 60) try: criteria = UnitAssociationCriteria.from_client_input(query) except: _LOG.error('Error parsing association criteria [%s]' % query) raise exceptions.PulpDataException(), None, sys.exc_info()[2] try: timeout = int(timeout) except ValueError: raise exceptions.InvalidValue(['timeout']), None, sys.exc_info()[2] # Coordinator configuration tags = [ resource_tag(dispatch_constants.RESOURCE_REPOSITORY_TYPE, repo_id), action_tag('resolve_dependencies') ] dependency_manager = manager_factory.dependency_manager() call_request = CallRequest( dependency_manager.resolve_dependencies_by_criteria, [repo_id, criteria, options], tags=tags, archive=True) call_request.reads_resource( dispatch_constants.RESOURCE_REPOSITORY_TYPE, repo_id) return execution.execute_sync_ok(self, call_request, timeout=timedelta(seconds=timeout))
def POST(self, repo_id): # Params params = self.params() query = params.get('criteria', None) repo_query_manager = manager_factory.repo_query_manager() repo = repo_query_manager.find_by_id(repo_id) if repo is None: raise exceptions.MissingResource(repo_id=repo_id) if query is None: raise exceptions.MissingValue(['criteria']) try: criteria = UnitAssociationCriteria.from_client_input(query) except: _logger.error('Error parsing association criteria [%s]' % query) raise exceptions.PulpDataException(), None, sys.exc_info()[2] # Data lookup manager = manager_factory.repo_unit_association_query_manager() if criteria.type_ids is not None and len(criteria.type_ids) == 1: type_id = criteria.type_ids[0] units = manager.get_units_by_type(repo_id, type_id, criteria=criteria) else: units = manager.get_units_across_types(repo_id, criteria=criteria) return self.ok(units)
def POST(self, repo_id): params = self.params() criteria = params.get('criteria', None) if criteria is not None: try: criteria = UnitAssociationCriteria.from_client_input(criteria) except: _logger.error('Error parsing unassociation criteria [%s]' % criteria) raise exceptions.PulpDataException(), None, sys.exc_info()[2] task_tags = [ tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, repo_id), tags.action_tag('unassociate') ] async_result = unassociate_by_criteria.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_TYPE, repo_id, [ repo_id, criteria, RepoContentUnit.OWNER_TYPE_USER, manager_factory.principal_manager().get_principal()['login'] ], tags=task_tags) raise exceptions.OperationPostponed(async_result)
def POST(self, repo_id): params = self.params() criteria = params.get('criteria', None) if criteria is not None: try: criteria = UnitAssociationCriteria.from_client_input(criteria) except: _LOG.error('Error parsing unassociation criteria [%s]' % criteria) raise exceptions.PulpDataException(), None, sys.exc_info()[2] association_manager = manager_factory.repo_unit_association_manager() tags = [ resource_tag(dispatch_constants.RESOURCE_REPOSITORY_TYPE, repo_id), action_tag('unassociate') ] call_request = CallRequest( association_manager.unassociate_by_criteria, [ repo_id, criteria, RepoContentUnit.OWNER_TYPE_USER, manager_factory.principal_manager().get_principal()['login'] ], tags=tags, archive=True) call_request.updates_resource( dispatch_constants.RESOURCE_REPOSITORY_TYPE, repo_id) return execution.execute_async(self, call_request)
def POST(self, dest_repo_id): # Params params = self.params() source_repo_id = params.get('source_repo_id', None) overrides = params.get('override_config', None) if source_repo_id is None: raise exceptions.MissingValue(['source_repo_id']) # A 404 only applies to things in the URL, so the destination repo # check allows the MissingResource to bubble up, but if the source # repo doesn't exist, it's considered bad data. repo_query_manager = manager_factory.repo_query_manager() repo_query_manager.get_repository(dest_repo_id) try: repo_query_manager.get_repository(source_repo_id) except exceptions.MissingResource: raise exceptions.InvalidValue(['source_repo_id']) criteria = params.get('criteria', None) if criteria is not None: try: criteria = UnitAssociationCriteria.from_client_input(criteria) except: _LOG.error('Error parsing association criteria [%s]' % criteria) raise exceptions.PulpDataException(), None, sys.exc_info()[2] association_manager = manager_factory.repo_unit_association_manager() tags = [ resource_tag(dispatch_constants.RESOURCE_REPOSITORY_TYPE, dest_repo_id), resource_tag(dispatch_constants.RESOURCE_REPOSITORY_TYPE, source_repo_id), action_tag('associate') ] call_request = CallRequest( association_manager.associate_from_repo, [source_repo_id, dest_repo_id], { 'criteria': criteria, 'import_config_override': overrides }, tags=tags, archive=True, kwarg_blacklist=['criteria', 'import_config_override']) call_request.reads_resource( dispatch_constants.RESOURCE_REPOSITORY_TYPE, source_repo_id) call_request.updates_resource( dispatch_constants.RESOURCE_REPOSITORY_TYPE, dest_repo_id) return execution.execute_async(self, call_request)
def POST(self, dest_repo_id): # Params params = self.params() source_repo_id = params.get('source_repo_id', None) overrides = params.get('override_config', None) if source_repo_id is None: raise exceptions.MissingValue(['source_repo_id']) # A 404 only applies to things in the URL, so the destination repo # check allows the MissingResource to bubble up, but if the source # repo doesn't exist, it's considered bad data. repo_query_manager = manager_factory.repo_query_manager() repo_query_manager.get_repository(dest_repo_id) try: repo_query_manager.get_repository(source_repo_id) except exceptions.MissingResource: raise exceptions.InvalidValue(['source_repo_id']) criteria = params.get('criteria', None) if criteria is not None: try: criteria = UnitAssociationCriteria.from_client_input(criteria) except: _logger.error('Error parsing association criteria [%s]' % criteria) raise exceptions.PulpDataException(), None, sys.exc_info()[2] task_tags = [ tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, dest_repo_id), tags.resource_tag(tags.RESOURCE_REPOSITORY_TYPE, source_repo_id), tags.action_tag('associate') ] async_result = associate_from_repo.apply_async_with_reservation( tags.RESOURCE_REPOSITORY_TYPE, dest_repo_id, [source_repo_id, dest_repo_id], { 'criteria': criteria, 'import_config_override': overrides }, tags=task_tags) raise exceptions.OperationPostponed(async_result)
def delete_user(login): """ Deletes the given user. Deletion of last superuser is not permitted. :param login: identifies the user being deleted :type login: str :raise pulp_exceptions.PulpDataException: if user is the last super user """ user = model.User.objects.get_or_404(login=login) if is_last_super_user(login): raise pulp_exceptions.PulpDataException( _("The last superuser [%s] cannot be deleted" % login)) # Revoke all permissions from the user permission_manager = manager_factory.permission_manager() permission_manager.revoke_all_permissions_from_user(login) user.delete()
def POST(self, repo_id): # Params params = self.params() query = params.get('criteria', {}) options = params.get('options', {}) timeout = params.get('timeout', 60) try: criteria = UnitAssociationCriteria.from_client_input(query) except: _logger.error('Error parsing association criteria [%s]' % query) raise exceptions.PulpDataException(), None, sys.exc_info()[2] try: timeout = int(timeout) except ValueError: raise exceptions.InvalidValue(['timeout']), None, sys.exc_info()[2] dependency_manager = manager_factory.dependency_manager() result = dependency_manager.resolve_dependencies_by_criteria( repo_id, criteria, options) return self.ok(result)
def is_last_super_user(login): """ Check to see if a user is the last super user :param user: login of user to check :type user: str :return: True if the user is the last super user, False otherwise :rtype: bool :raise PulpDataException: if no super users are found """ user = model.User.objects.get_or_404(login=login) if not user.is_superuser(): return False super_users = find_users_belonging_to_role(SUPER_USER_ROLE) if not super_users: raise pulp_exceptions.PulpDataException(_('no super users defined')) if len(super_users) > 1: return False return True
def add_distributor(repo_id, distributor_type_id, repo_plugin_config, auto_publish, distributor_id=None): """ Adds an association from the given repository to a distributor. The distributor_id is unique for a given repository. If distributor_id is not specified, one will be generated. If a distributor already exists on the repo for the given ID, the existing one will be removed and replaced with the newly configured one. :param repo_id: identifies the repo :type repo_id: basestring :param distributor_type_id: must correspond to a distributor type loaded at server startup :type distributor_type_id: basestring :param repo_plugin_config: configuration the repo will use with this distributor :type repo_plugin_config: dict or None :param auto_publish: if True, this distributor will be invoked at the end of every sync :type auto_publish: bool :param distributor_id: unique ID to refer to this distributor for this repo :type distributor_id: basestring :return: distributor object :rtype: pulp.server.db.model.Distributor :raise InvalidValue: if the distributor ID is provided and unacceptable :raise exceptions.PulpDataException: if the plugin returns that the config is invalid """ repo_obj = model.Repository.objects.get_repo_or_missing_resource(repo_id) if not plugin_api.is_valid_distributor(distributor_type_id): raise exceptions.InvalidValue(['distributor_type_id']) if distributor_id is None: distributor_id = str(uuid.uuid4()) distributor_instance, plugin_config = plugin_api.get_distributor_by_id(distributor_type_id) # Remove any keys whose values are explicitly set to None so the plugin will default them. if repo_plugin_config is not None: clean_config = dict([(k, v) for k, v in repo_plugin_config.items() if v is not None]) else: clean_config = None # Let the distributor plugin verify the configuration call_config = PluginCallConfiguration(plugin_config, clean_config) config_conduit = RepoConfigConduit(distributor_type_id) transfer_repo = repo_obj.to_transfer_repo() result = distributor_instance.validate_config(transfer_repo, call_config, config_conduit) # For backward compatibility with plugins that don't yet return the tuple if isinstance(result, bool): valid_config = result message = None else: valid_config, message = result if not valid_config: raise exceptions.PulpDataException(message) try: model.Distributor.objects.get_or_404(repo_id=repo_id, distributor_id=distributor_id) delete(repo_id, distributor_id) except exceptions.MissingResource: pass # if it didn't exist, no problem distributor_instance.distributor_added(transfer_repo, call_config) distributor = model.Distributor(repo_id, distributor_id, distributor_type_id, clean_config, auto_publish) distributor.save() return distributor
def update(repo_id, dist_id, config=None, delta=None): """ Update the distributor and (re)bind any bound consumers. :param distributor: distributor to be updated :type distributor: pulp.server.db.model.Distributor :param config: A configuration dictionary for a distributor instance. The contents of this dict depends on the type of distributor. Values of None will remove they key from the config. Keys ommited from this dictionary will remain unchanged. :type config: dict :param delta: A dictionary used to change conf values for a distributor instance. This currently only supports the 'auto_publish' keyword, which should have a value of type bool :type delta: dict or None :return: result containing any errors and tasks spawned :rtype pulp.server.async.tasks.TaskResult """ repo = model.Repository.objects.get_repo_or_missing_resource(repo_id) distributor = model.Distributor.objects.get_or_404(repo_id=repo_id, distributor_id=dist_id) for k, v in config.iteritems(): if v is None: distributor.config.pop(k) else: distributor.config[k] = v auto_publish = delta.get('auto_publish') if delta else None if isinstance(auto_publish, bool): distributor.auto_publish = auto_publish elif not isinstance(auto_publish, type(None)): raise exceptions.InvalidValue(['auto_publish']) # Let the distributor plugin verify the configuration distributor_instance, plugin_config = plugin_api.get_distributor_by_id( distributor.distributor_type_id) call_config = PluginCallConfiguration(plugin_config, distributor.config) transfer_repo = repo.to_transfer_repo() config_conduit = RepoConfigConduit(distributor.distributor_type_id) result = distributor_instance.validate_config(transfer_repo, call_config, config_conduit) # For backward compatibility with plugins that don't yet return the tuple if isinstance(result, bool): valid_config = result message = None else: valid_config, message = result if not valid_config: raise exceptions.PulpDataException(message) distributor.save() unbind_errors = [] additional_tasks = [] options = {} bind_manager = managers.consumer_bind_manager() for bind in bind_manager.find_by_distributor(distributor.repo_id, distributor.distributor_id): try: report = bind_manager.bind(bind['consumer_id'], bind['repo_id'], bind['distributor_id'], bind['notify_agent'], bind['binding_config'], options) if report: additional_tasks.extend(report.spawned_tasks) except Exception, e: unbind_errors.append(e)