| # Copyright (C) 2018-2019 Apple Inc. All rights reserved. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions |
| # are met: |
| # 1. Redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer. |
| # 2. Redistributions in binary form must reproduce the above copyright |
| # notice, this list of conditions and the following disclaimer in the |
| # documentation and/or other materials provided with the distribution. |
| # |
| # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND |
| # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR |
| # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| from __future__ import unicode_literals |
| |
| import json |
| import logging |
| import os |
| |
| from django.http import HttpResponse |
| from django.shortcuts import render |
| from django.views import View |
| from django.views.decorators.csrf import csrf_exempt |
| from django.utils.decorators import method_decorator |
| |
| from ews.models.build import Build |
| from ews.models.step import Step |
| |
| _log = logging.getLogger(__name__) |
| |
| |
| @method_decorator(csrf_exempt, name='dispatch') |
| class Results(View): |
| def post(self, request): |
| data = json.loads(request.body) |
| |
| if data.get('EWS_API_KEY') != os.getenv('EWS_API_KEY', None): |
| _log.error('Incorrect API Key {}. Host: {}. Ignoring data.'.format(data.get('EWS_API_KEY'), data.get('hostname'))) |
| return HttpResponse('Incorrect API Key received') |
| |
| if data.get('type') == u'ews-build': |
| return self.build_event(data) |
| |
| if data.get('type') == u'ews-step': |
| return self.step_event(data) |
| |
| _log.error('Unexpected data type received: {}'.format(data.get('type'))) |
| return HttpResponse('Unexpected data type received: {}'.format(data.get('type'))) |
| |
| def build_event(self, data): |
| if not self.is_valid_result(data): |
| return HttpResponse("Incomplete data.") |
| |
| patch_id = data['patch_id'] |
| if not patch_id or patch_id < 1: |
| return HttpResponse("Invalid patch id: {}.".format(patch_id)) |
| |
| Build.save_build(patch_id=int(patch_id), hostname=data['hostname'], build_id=data['build_id'], builder_id=data['builder_id'], builder_name=data['builder_name'], |
| builder_display_name=data['builder_display_name'], number=data['number'], result=data['result'], |
| state_string=data['state_string'], started_at=data['started_at'], complete_at=data['complete_at']) |
| return HttpResponse("Saved data for patch: {}.\n".format(patch_id)) |
| |
| def step_event(self, data): |
| if not self.is_valid_result(data): |
| return HttpResponse("Incomplete data.") |
| |
| Step.save_step(hostname=data['hostname'], step_id=data['step_id'], build_id=data['build_id'], result=data['result'], |
| state_string=data['state_string'], started_at=data['started_at'], complete_at=data['complete_at']) |
| return HttpResponse("Saved data for step: {}.\n".format(data['step_id'])) |
| |
| def is_valid_result(self, data): |
| if data['type'] not in [u'ews-build', u'ews-step']: |
| _log.error("Invalid data type: {}".format(data['type'])) |
| return False |
| |
| required_keys = {u'ews-build': ['hostname', 'patch_id', 'build_id', 'builder_id', 'builder_name', 'builder_display_name', |
| 'number', 'result', 'state_string', 'started_at', 'complete_at'], |
| u'ews-step': ['hostname', 'step_id', 'build_id', 'result', 'state_string', 'started_at', 'complete_at']} |
| |
| for key in required_keys.get(data.get('type')): |
| if key not in data: |
| _log.warn('Data is missing {}'.format(key)) |
| return False |
| return True |