def test_app_get(self, mock_registry): mock_registry.App.get_by_uuid.return_value = {} handler = app_handler.AppHandler(self.ctx) res = handler.get('test_id') self.assertIsNotNone(res) get_by_uuid = mock_registry.App.get_by_uuid get_by_uuid.assert_called_once_with(self.ctx, 'test_id')
def post(self, data): """Create a new app.""" request.check_request_for_https() if not data: raise exception.BadRequest(reason='No data.') self._validate(data) handler = app_handler.AppHandler(pecan.request.security_context) app_data = data.as_dict(app.App) try: raw_content = yamlutils.load(pecan.request.body) except ValueError: try: raw_content = json.loads(pecan.request.body) except ValueError as exp: LOG.exception(exp) raise exception.BadRequest(reason='Invalid app data.') app_data['raw_content'] = json.dumps(raw_content) new_app = handler.create(app_data) created_app = app.App.from_db_model(new_app, pecan.request.host_url) return created_app
def get(self): """Return this app.""" request.check_request_for_https() handler = app_handler.AppHandler(pecan.request.security_context) app_model = handler.get(self._id) app_model = app.App.from_db_model(app_model, pecan.request.host_url) return app_model
def get_all(self): """Return all apps, based on the query provided.""" request.check_request_for_https() handler = app_handler.AppHandler(pecan.request.security_context) all_apps = [app.App.from_db_model(obj, pecan.request.host_url) for obj in handler.get_all()] return all_apps
def post(self, data): """Create a new workflow.""" request.check_request_for_https() if not data: raise exception.BadRequest(reason='No data.') ahandler = app_handler.AppHandler(pecan.request.security_context) app_model = ahandler.get(self.app_id) handler = wf_handler.WorkflowHandler(pecan.request.security_context) data.app_id = app_model.id data.config = app_model.workflow_config data.source = app_model.source wf_data = data.as_dict(workflow.Workflow) du_id = None if data.du_id: du_id = data.du_id self._verify_du_exists(pecan.request.security_context, du_id) return workflow.Workflow.from_db_model( handler.create(wf_data, commit_sha='', status_url='', du_id=du_id), pecan.request.host_url)
def test_app_create_invalid_repo_url(self, mock_kc, mock_registry): invalid_urls_list = list() invalid_urls_list.append('http://github.com/skdhfskjhdks') invalid_urls_list.append('github.com/abc/xyz') invalid_urls_list.append('xyz://github.com/abc/xyz.git') invalid_urls_list.append('xyz://github.com/abc/xyz') invalid_urls_list.append('abc') invalid_urls_list.append('http') invalid_urls_list.append('git') for invalid_url in invalid_urls_list: data = { 'name': 'fakeapp', 'description': 'fake app for testing', 'source': { 'repository': invalid_url, 'revision': 'master' } } raw_content = {'a': 'b'} data['raw_content'] = json.dumps(raw_content) self.ctx.password = '******' db_obj = fakes.FakeApp() mock_registry.App.return_value = db_obj handler = app_handler.AppHandler(self.ctx) self.assertRaises(exc.BadRequest, handler.create, data) assert not db_obj.create.called, 'db_obj.create called'
def _validate(self, app_data): # check max apps created for given tenant handler = app_handler.AppHandler(pecan.request.security_context) if len(handler.get_all()) >= cfg.CONF.api.max_apps_per_tenant: msg = "Cannot create application as maximum allowed limit reached." raise exception.ResourceLimitExceeded(reason=msg) if not app_data.languagepack: raise exception.BadRequest(reason="Languagepack not specified.") if not app_data.name: raise exception.BadRequest(reason='App name cannot be empty.') msg = ("Application name must be 1-100 characters long, only contain " "a-z,0-9,-,_ and start with an alphabet character.") # check if app name contains any invalid characters if not app_data.name or not app_data.name[0].isalpha(): raise exception.BadRequest(reason=msg) try: re.match(r'^([a-z0-9-_]{1,100})$', app_data.name).group(0) except AttributeError: raise exception.BadRequest(reason=msg) # check if languagepack exists or not if str(app_data.languagepack).lower() != "false": try: objects.registry.Image.get_lp_by_name_or_uuid( pecan.request.security_context, app_data.languagepack, include_operators_lp=True) except exception.ResourceNotFound: raise exception.ObjectNotFound(name="Languagepack", id=app_data.languagepack)
def get(self): """Return this app.""" request.check_request_for_https() handler = app_handler.AppHandler(pecan.request.security_context) app_model = handler.get(self._id) host_url = pecan.request.application_url.rstrip('/') app_model = app.App.from_db_model(app_model, host_url) return app_model
def test_app_create(self, mock_kc, mock_registry): data = {'name': 'fakeapp', 'description': 'fake app for testing'} db_obj = fakes.FakeApp() mock_registry.App.return_value = db_obj handler = app_handler.AppHandler(self.ctx) res = handler.create(data) db_obj.create.assert_called_once_with(self.ctx) self.assertEqual(db_obj, res)
def post(self, trigger_id): """Trigger a new event on Solum.""" policy.check('create_trigger', pecan.request.security_context) commit_sha = '' status_url = None collab_url = None try: query = query_dict(pecan.request.query_string) workflow = self._get_workflow(query) body = json.loads(pecan.request.body) if ('sender' in body and 'url' in body['sender'] and 'api.github.com' in body['sender']['url']): action = body.get('action', None) if 'comment' in body: # Process a request for rebuilding commit_sha, collab_url = self._process_request(body) elif 'pull_request' in body: # Process a GitHub pull request commit_sha = body['pull_request']['head']['sha'] else: raise exception.NotImplemented() # An example of Github statuses_url # https://api.github.com/repos/:user/:repo/statuses/{sha} if commit_sha: status_url = body['repository']['statuses_url'].format( sha=commit_sha) else: # Request NOT from a Github repo raise exception.NotImplemented() except Exception as exc: if isinstance(exc, exception.SolumException): raise info_msg = "Expected fields not found in request body." LOG.info(info_msg) raise exception.BadRequest(reason=info_msg) try: # Trigger workflow only on PR create and on rebuild request if action in [ 'created', 'opened', 'edited', 'reopened', 'synchronize', 'closed' ]: handler = app_handler.AppHandler(None) handler.trigger_workflow(trigger_id, commit_sha, status_url, collab_url, workflow=workflow) except exception.ResourceNotFound: LOG.error("Incorrect trigger url.") raise pecan.response.status = 202
def patch(self, data): """Modify this app.""" request.check_request_for_https() handler = app_handler.AppHandler(pecan.request.security_context) handler.get(self._id) if not data: raise exception.BadRequest(reason="No body detected") updated_app = handler.patch(self._id, data) updated_app = app.App.from_db_model(updated_app, pecan.request.host_url) return updated_app
def test_app_create(self, mock_kc, mock_registry): data = { 'name': 'fakeapp', 'description': 'fake app for testing', 'source': { 'repository': 'https://github.com/example/a.git', 'revision': 'master' } } db_obj = fakes.FakeApp() mock_registry.App.return_value = db_obj handler = app_handler.AppHandler(self.ctx) res = handler.create(data) db_obj.create.assert_called_once_with(self.ctx) self.assertEqual(db_obj, res)
def post(self, data): """Create a new app.""" request.check_request_for_https() if not data: raise exception.BadRequest(reason='No data.') self._validate(data) handler = app_handler.AppHandler(pecan.request.security_context) app_data = data.as_dict(app.App) new_app = handler.create(app_data) created_app = app.App.from_db_model(new_app, pecan.request.host_url) return created_app
def _validate(self, app_data): # check max apps created for given tenant handler = app_handler.AppHandler(pecan.request.security_context) if len(handler.get_all()) >= cfg.CONF.api.max_apps_per_tenant: msg = "Cannot create application as maximum allowed limit reached." raise exception.ResourceLimitExceeded(reason=msg) if not app_data.languagepack: raise exception.BadRequest(reason="Languagepack not specified.") if not app_data.name: raise exception.BadRequest(reason='App name cannot be empty.') # check if languagepack exists or not try: objects.registry.Image.get_lp_by_name_or_uuid( pecan.request.security_context, app_data.languagepack, include_operators_lp=True) except exception.ResourceNotFound: raise exception.ObjectNotFound(name="Languagepack", id=app_data.languagepack)
def test_app_patch(self, mock_registry): mock_registry.App.side_effect = [mock.MagicMock(), mock.MagicMock()] db_obj = objects.registry.App() # Without this, I'd just get a mocked function call. # I want real data so I can track that it's being updated. a = fakes.FakeApp().as_dict() db_obj.as_dict.return_value = a mock_registry.App.get_by_uuid.return_value = db_obj # I'm not saving anything anyway, I just want to make sure # that I'm sending the right data to update_and_save. mock_registry.App.update_and_save = ( lambda context, obj_id, data_dict: data_dict) # Build a phony app whose as_dict returns this dict below. to_update_data = { 'name': 'newfakeapp', 'workflow_config': { 'run_cmd': 'newruncommand', }, 'source': { 'revision': 'experimental', }, 'repo_token': 'abc' } handler = app_handler.AppHandler(self.ctx) new_app = objects.registry.App() new_app.as_dict.return_value = to_update_data # The actual call to handler.patch updated = handler.patch('test_id', new_app) self.assertEqual('newfakeapp', updated['name']) self.assertEqual('newruncommand', updated['workflow_config']['run_cmd']) self.assertEqual('python ./tests.py', updated['workflow_config']['test_cmd']) self.assertEqual('http://github.com/example/a.git', updated['source']['repository']) self.assertEqual('experimental', updated['source']['revision'])
def delete(self): """Delete this app.""" handler = app_handler.AppHandler(pecan.request.security_context) handler.delete(self._id)
def post(self, trigger_id): """Trigger a new event on Solum.""" commit_sha = '' status_url = None collab_url = None workflow = None try: query = query_dict(pecan.request.query_string) if 'workflow' in query: valid_stages = ['unittest', 'build', 'deploy'] workflow = query['workflow'].replace('+', ' ').split(' ') workflow = filter(lambda x: x in valid_stages, workflow) if not workflow: workflow = None body = json.loads(pecan.request.body) if ('sender' in body and 'url' in body['sender'] and 'api.github.com' in body['sender']['url']): if 'comment' in body: # Process a request for rebuilding phrase = body['comment']['body'] commenter = body['comment']['user']['login'] private_repo = body['repository']['private'] # An example of collab_url # https://api.github.com/repos/:user/:repo/collaborators{/collaborator} if not private_repo: # Only verify collaborator for public repos collab_url = ( body['repository']['collaborators_url'].format( **{'/collaborator': '/' + commenter})) if (phrase.strip('. ').lower() != CONF.api.rebuild_phrase.lower()): err_msg = 'Rebuild phrase does not match' raise exception.RequestForbidden(reason=err_msg) else: commit_sha = body['comment']['commit_id'] elif 'pull_request' in body: # Process a GitHub pull request commit_sha = body['pull_request']['head']['sha'] else: raise exception.NotImplemented() # An example of Github statuses_url # https://api.github.com/repos/:user/:repo/statuses/{sha} if commit_sha: status_url = body['repository']['statuses_url'].format( sha=commit_sha) else: # Request NOT from a Github repo raise exception.NotImplemented() except Exception as exc: if isinstance(exc, exception.SolumException): raise info_msg = "Expected fields not found in request body." LOG.info(info_msg) raise exception.BadRequest(reason=info_msg) try: handler = app_handler.AppHandler(None) handler.trigger_workflow(trigger_id, commit_sha, status_url, collab_url, workflow=workflow) except exception.ResourceNotFound as e: LOG.error("Incorrect trigger url.") raise e pecan.response.status = 202
def test_app_get_all(self, mock_registry): mock_registry.App.get_all.return_value = {} handler = app_handler.AppHandler(self.ctx) res = handler.get_all() self.assertIsNotNone(res) mock_registry.AppList.get_all.assert_called_once_with(self.ctx)
def test_app_delete(self, mock_destroy, mock_registry): handler = app_handler.AppHandler(self.ctx) handler.delete('test_id') mock_destroy.assert_called_once_with('test_id')