def update(self, request, *args, **kwargs): data = request.data owners = data.pop('owners', []) instance = self.get_object() if data.get('provider_namespace'): try: provider_namespace = models.ProviderNamespace.objects.get( pk=data['provider_namespace']) except ObjectDoesNotExist: raise ValidationError( detail={'provider_namespace': 'Invalid value'}) else: provider_namespace = instance.provider_namespace check_name(data.get('name')) data['name'] = common.sanitize_content_name(data['name']) original_name = data.get('original_name', instance.original_name) if not request.user.is_staff: repo = get_repo(provider_namespace, request.user, original_name) if not repo: raise PermissionDenied( "User does not have access to {0}/{1} in " "GitHub".format(provider_namespace.name, original_name)) for field in GITHUB_REPO_FIELDS: data[field] = repo[field] serializer = self.get_serializer(instance, data=data) serializer.is_valid(raise_exception=True) try: # FIXME(cutwater): This code should be refactored. repository = models.Repository.objects.get(pk=instance.pk) for k in data: setattr(repository, k, data[k]) repository.save() except Exception as exc: raise APIException('Error updating repository: {0}'.format( exc.message)) for owner_pk in owners: try: owner = User.objects.get(pk=owner_pk) except ObjectDoesNotExist: pass else: owner.repositories.add(instance) if not request.user.repositories.filter(pk=instance.pk): request.user.repositories.add(instance) import_task = tasks.create_import_task(repository, request.user) serializer = self.get_serializer(instance=instance) data = serializer.data data['summary_fields']['latest_import'] = \ serializers.ImportTaskSerializer(import_task).data return Response(data)
def parse_name(self): fieldname = 'name' name = sanitize_content_name(self._get_key(fieldname)) if not re.match('^[a-z0-9_]+$', name): raise exc.APBContentLoadError( 'Invalid "{0}" value in metadata. Must contain only lowercase ' 'letters, digits, and underscore'.format(fieldname)) return name
def post(self, request, *args, **kwargs): data = request.data owners = data.pop('owners', []) if not data.get('provider_namespace'): raise ValidationError( detail={'provider_namespace': 'Value required'}) check_name(data.get('name')) try: provider_namespace = models.ProviderNamespace.objects.get( pk=data['provider_namespace']) except ObjectDoesNotExist: raise ValidationError( detail={'provider_namespace': 'Invalid value'}) original_name = data.get('original_name', data['name']) data['name'] = common.sanitize_content_name(data['original_name']) if not request.user.is_staff: repo = get_repo(provider_namespace, request.user, original_name) if not repo: raise PermissionDenied( "User does not have access to {0}/{1} in " "GitHub".format(provider_namespace.name, original_name)) for field in GITHUB_REPO_FIELDS: data[field] = repo[field] if not data.get('original_name'): data['original_name'] = original_name serializer = self.get_serializer(data=data) serializer.is_valid(raise_exception=True) data['provider_namespace'] = provider_namespace try: repository = models.Repository.objects.create(**data) except Exception as exc: raise APIException('Error creating repository: {0}' .format(exc.message)) for owner_pk in owners: try: owner = User.objects.get(pk=owner_pk) except ObjectDoesNotExist: pass else: owner.repositories.add(repository) import_task = tasks.create_import_task(repository, request.user) serializer = self.get_serializer(repository) data = serializer.data data['summary_fields']['latest_import'] = \ serializers.ImportTaskSerializer(import_task).data headers = self.get_success_headers(data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def post(self, request, *args, **kwargs): github_user = request.data.get('github_user') github_repo = request.data.get('github_repo') github_reference = request.data.get('github_reference', '') repository_id = request.data.get('repository_id') if not repository_id: # request received from old client if not github_user or not github_repo: raise ValidationError( dict( detail= "Invalid request. Expecting github_user and github_repo." )) namespace = models.ProviderNamespace.objects.get( provider__name=constants.PROVIDER_GITHUB, name=github_user) if not request.user.is_staff and \ not namespace.namespace.owners.filter(username=request.user.get_username()): # User is not an onwer of the Namespace raise PermissionDenied("You are not an owner of {0}".format( namespace.namespace.name)) try: repository = models.Repository.objects.get( provider_namespace=namespace, original_name=github_repo) except ObjectDoesNotExist: repository, created = models.Repository.objects.get_or_create( provider_namespace=namespace, name=sanitize_content_name(github_repo), defaults={ 'is_enabled': False, 'original_name': github_repo }) else: try: repository = models.Repository.objects.get(pk=repository_id) except ObjectDoesNotExist: raise ValidationError( dict(detail= "Repository {0} not found, or you do not have access". format(repository_id))) if not request.user.is_staff and \ not repository.provider_namespace.namespace.owners.filter(username=request.user.get_username()): # User is not an onwer of the Namespace raise PermissionDenied("You are not an owner of {0}".format( repository.name)) task = tasks.create_import_task(repository, request.user, import_branch=github_reference) serializer = self.get_serializer(instance=task) response = {'results': [serializer.data]} return Response(response, status=status.HTTP_201_CREATED, headers=self.get_success_headers(response))
def _get_metadata_role_name(self, galaxy_info): """Get role_name from repository role metadata, if it exists. Collections do not support role_name. Collections have self.name already set via directory path. """ name = self.name is_collection = bool(self.name) if is_collection: if galaxy_info.get('role_name'): self.log.warning("Role in collection gets name from directory," " ignoring the 'role_name' attribute") return name if galaxy_info.get('role_name'): name = sanitize_content_name(galaxy_info['role_name']) return name
def load(self): meta = self._load_metadata() meta_parser = RoleMetaParser(meta, logger=self.log) galaxy_info = meta_parser.metadata meta_parser.validate_strings() # TODO: Refactoring required data = {} data.update(self._load_string_attrs(galaxy_info)) container_yml_type, container_yml = self._load_container_yml() description = data.pop('description') data['role_type'] = self._get_role_type(galaxy_info, container_yml_type) data['tags'] = meta_parser.parse_tags() data['platforms'] = meta_parser.parse_platforms() data['cloud_platforms'] = meta_parser.parse_cloud_platforms() data['dependencies'] = meta_parser.parse_dependencies() data['video_links'] = meta_parser.parse_videos() readme = self._get_readme() name = self.name if galaxy_info.get('role_name'): name = sanitize_content_name(galaxy_info['role_name']) return models.Content( name=name, original_name=self.name, path=self.rel_path, content_type=self.content_type, description=description, role_meta=data, readme=readme, metadata={ 'container_meta': container_yml, } )
def _import_repository(import_task, logger): repository = import_task.repository repo_full_name = (repository.provider_namespace.name + "/" + repository.original_name) logger.info(u'Starting import: task_id={}, repository={}'.format( import_task.id, repo_full_name)) if import_task.import_branch: repository.import_branch = import_task.import_branch token = _get_social_token(import_task) gh_api = github.Github(token) gh_repo = gh_api.get_repo(repo_full_name) try: repo_info = i_repo.import_repository( repository.clone_url, branch=repository.import_branch, temp_dir=settings.CONTENT_DOWNLOAD_DIR, logger=logger) except i_exc.ImporterError as e: raise exc.TaskError(str(e)) if repository.import_branch is None: repository.import_branch = repo_info.branch repository.format = repo_info.format.value if repo_info.name: old_name = repository.name new_name = common.sanitize_content_name(repo_info.name) if old_name != new_name: logger.info( u'Updating repository name "{old_name}" -> "{new_name}"'. format(old_name=old_name, new_name=new_name)) repository.name = new_name context = utils.Context(repository=repository, github_token=token, github_client=gh_api, github_repo=gh_repo) new_content_objs = [] for content_info in repo_info.contents: content_logger = logutils.ContentTypeAdapter(logger, content_info.content_type, content_info.name) importer_cls = importers.get_importer(content_info.content_type) importer = importer_cls(context, content_info, logger=content_logger) issue_tracker_url = '' if (hasattr(content_info, 'role_meta') and getattr(content_info, 'role_meta') and content_info.role_meta.get('issue_tracker_url')): issue_tracker_url = content_info.role_meta['issue_tracker_url'] elif gh_repo.has_issues: issue_tracker_url = gh_repo.html_url + '/issues' repository.issue_tracker_url = issue_tracker_url content_obj = importer.do_import() new_content_objs.append(content_obj.id) for obj in repository.content_objects.exclude(id__in=new_content_objs): logger.info('Deleting Content instance: content_type={0}, ' 'namespace={1}, name={2}'.format(obj.content_type, obj.namespace, obj.name)) obj.delete() _update_readme(repository, repo_info.readme, gh_api, gh_repo) _update_repository_versions(repository, gh_repo, logger) _update_namespace(gh_repo) _update_repo_info(repository, gh_repo, repo_info.commit) repository.save() import_task.finish_success(u'Import completed')
def _get_name(self, galaxy_info): name = self.name if galaxy_info.get('role_name'): name = sanitize_content_name(galaxy_info['role_name']) return name
def update(self, request, *args, **kwargs): data = request.data owners = data.pop('owners', []) instance = self.get_object() if data.get('provider_namespace'): try: provider_namespace = models.ProviderNamespace.objects.get( pk=data['provider_namespace']) except ObjectDoesNotExist: raise ValidationError( detail={'provider_namespace': 'Invalid value'}) else: provider_namespace = instance.provider_namespace check_name(data.get('name')) data['name'] = common.sanitize_content_name(data['name']) original_name = data.get('original_name', instance.original_name) if not request.user.is_staff: repo = get_repo(provider_namespace, request.user, original_name) if not repo: raise PermissionDenied( "User does not have access to {0}/{1} in " "GitHub".format(provider_namespace.name, original_name)) for field in GITHUB_REPO_FIELDS: data[field] = repo[field] serializer = self.get_serializer(instance, data=data) serializer.is_valid(raise_exception=True) # Limit the attributes that get updated in the database to these to_update = ( 'original_name', 'description', 'is_enabled', 'deprecated', ) updated = [] try: # FIXME(cutwater): This code should be refactored. for k in to_update: if k in data and getattr(instance, k) != data[k]: setattr(instance, k, data[k]) updated.append(k) instance.save() except Exception as exc: raise APIException('Error updating repository: {0}'.format(exc)) for owner_pk in owners: try: owner = User.objects.get(pk=owner_pk) except ObjectDoesNotExist: pass else: owner.repositories.add(instance) if not request.user.repositories.filter(pk=instance.pk): request.user.repositories.add(instance) serializer = self.get_serializer(instance=instance) data = serializer.data # Don't create an import task if we're just updating the deprication # status if updated != ['deprecated']: import_task = tasks.create_import_task( instance, request.user, user_initiated=True ) data['summary_fields']['latest_import'] = \ serializers.ImportTaskDetailSerializer(import_task).data return Response(data)
def translate_content_name(self, name): return common.sanitize_content_name(name)