Bug 1117583 - Add an API endpoint that creates a new bug in Bugzilla.

This endpoint receives a http POST request from the UI containing information about the bug to be filed (product, component, summary, version, description), then formats it properly as a submission to Bugzilla's REST API, using a server-side Bugzilla API key, and adding a "treeherder" comment tag.

The API then passes back either the bug ID (if the submission was successful) or Bugzilla's failure response if something went wrong.
This commit is contained in:
Wes Kocher 2015-12-30 16:07:14 -08:00 коммит произвёл KWierso
Родитель 3b5f39b787
Коммит 371ec172de
6 изменённых файлов: 168 добавлений и 0 удалений

Просмотреть файл

@ -10,3 +10,7 @@ CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
# Reconfigure pulse to operate on default vhost of rabbitmq
PULSE_URI = BROKER_URL
PULSE_EXCHANGE_NAMESPACE = 'test'
# Set a fake api key for testing bug filing
BZ_API_KEY = "12345helloworld"
BZ_API_URL = "https://thisisnotbugzilla.org"

Просмотреть файл

@ -0,0 +1,108 @@
import json
import responses
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from rest_framework.test import APIClient
def test_create_bug(webapp, eleven_jobs_stored, activate_responses):
"""
test successfully creating a bug in bugzilla
"""
def request_callback(request):
headers = {}
requestdata = json.loads(request.body)
requestheaders = request.headers
print requestdata
print requestheaders
assert requestheaders['x-bugzilla-api-key'] == "12345helloworld"
assert requestdata['product'] == "Bugzilla"
assert requestdata['description'] == "Filed by: MyName\n\nIntermittent Description"
assert requestdata['component'] == "Administration"
assert requestdata['summary'] == "Intermittent summary"
assert requestdata['comment_tags'] == "treeherder"
assert requestdata['version'] == "4.0.17"
assert requestdata['keywords'] == "intermittent-failure"
resp_body = {"id": 323}
return(200, headers, json.dumps(resp_body))
responses.add_callback(
responses.POST, "https://thisisnotbugzilla.org/rest/bug",
callback=request_callback, match_querystring=False,
content_type="application/json",
)
client = APIClient()
user = User.objects.create(username="MyName", email="foo@bar.com")
client.force_authenticate(user=user)
resp = client.post(
reverse("bugzilla-create-bug"),
{
"product": "Bugzilla",
"component": "Administration",
"summary": "Intermittent summary",
"version": "4.0.17",
"description": "Intermittent Description",
"comment_tags": "treeherder",
"keywords": "intermittent-failure",
}
)
user.delete()
content = json.loads(resp.content)
print content
assert content['success'] == 323
def test_create_unauthenticated_bug(webapp, eleven_jobs_stored, activate_responses):
"""
test successfully creating a bug in bugzilla
"""
def request_callback(request):
headers = {}
requestdata = json.loads(request.body)
requestheaders = request.headers
print requestdata
print requestheaders
assert requestheaders['x-bugzilla-api-key'] == "12345helloworld"
assert requestdata['product'] == "Bugzilla"
assert requestdata['description'] == "Filed by: MyName\n\nIntermittent Description"
assert requestdata['component'] == "Administration"
assert requestdata['summary'] == "Intermittent summary"
assert requestdata['comment_tags'] == "treeherder"
assert requestdata['version'] == "4.0.17"
assert requestdata['keywords'] == "intermittent-failure"
resp_body = {"id": 323}
return(200, headers, json.dumps(resp_body))
responses.add_callback(
responses.POST, "https://thisisnotbugzilla.org/rest/bug",
callback=request_callback, match_querystring=False,
content_type="application/json",
)
client = APIClient()
resp = client.post(
reverse("bugzilla-create-bug"),
{
"product": "Bugzilla",
"component": "Administration",
"summary": "Intermittent summary",
"version": "4.0.17",
"description": "Intermittent Description",
"comment_tags": "treeherder",
"keywords": "intermittent-failure",
}
)
content = json.loads(resp.content)
print content
assert content['detail'] == "Authentication credentials were not provided."

Просмотреть файл

@ -327,6 +327,7 @@ PARSER_MAX_SUMMARY_LINES = 200
FAILURE_LINES_CUTOFF = 35
BZ_API_URL = "https://bugzilla.mozilla.org"
BZ_API_KEY = env("BUGZILLA_API_KEY", default=None)
ORANGEFACTOR_SUBMISSION_URL = "https://brasstacks.mozilla.com/orangefactor/api/saveclassification"
ORANGEFACTOR_HAWK_ID = "treeherder"

Просмотреть файл

@ -1,3 +1,6 @@
# Switch to using a different bugzilla instance
BZ_API_URL = "http://bugzilla-dev.allizom.org/"
# Applications useful for development, e.g. debug_toolbar, django_extensions.
# Always empty in production
LOCAL_APPS = []

Просмотреть файл

@ -0,0 +1,49 @@
import requests
from django.conf import settings
from rest_framework import (status,
viewsets)
from rest_framework.decorators import list_route
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.response import Response
from treeherder.etl.common import make_request
class BugzillaViewSet(viewsets.ViewSet):
permission_classes = (IsAuthenticatedOrReadOnly,)
@list_route(methods=['post'])
def create_bug(self, request):
"""
Create a bugzilla bug with passed params
"""
if settings.BZ_API_KEY is None:
return Response({"failure": "Bugzilla API key not defined. This shouldn't happen."}, status=status.HTTP_400_BAD_REQUEST)
else:
params = request.data
url = settings.BZ_API_URL + "/rest/bug"
headers = {
'x-bugzilla-api-key': settings.BZ_API_KEY
}
data = {
'product': params["product"],
'component': params["component"],
'summary': params["summary"],
'keywords': params["keywords"],
'version': params["version"],
'description': "Filed by: " + request.user.username + "\n\n" + params["description"],
'comment_tags': "treeherder",
}
try:
response = make_request(url, method='POST', headers=headers, json=data)
except requests.exceptions.HTTPError as e:
response = e.response
try:
rsperror = response.json()['message']
except:
rsperror = response
return Response({"failure": rsperror}, status=status.HTTP_400_BAD_REQUEST)
return Response({"success": response.json()["id"]})

Просмотреть файл

@ -4,6 +4,7 @@ from rest_framework import routers
from treeherder.webapp.api import (artifact,
bug,
bugzilla,
job_log_url,
jobs,
logslice,
@ -108,6 +109,8 @@ default_router.register(r'performance/alert',
default_router.register(r'performance/framework',
performance_data.PerformanceFrameworkViewSet,
base_name='performance-frameworks')
default_router.register(r'bugzilla', bugzilla.BugzillaViewSet,
base_name='bugzilla')
urlpatterns = [
url(r'^project/(?P<project>[\w-]{0,50})/',