Implement new create and manager trigger UI

Implements the new trigger setup user interface, which is now a linear workflow found on its own page, rather than a tiny modal dialog

Fixes #1187
This commit is contained in:
Joseph Schorr 2016-09-27 16:52:34 +02:00
parent 21b09a7451
commit 8e863b8cf5
47 changed files with 1835 additions and 1068 deletions

View file

@ -127,7 +127,7 @@ class BuildTriggerSubdirs(RepositoryParamResource):
try:
subdirs = handler.list_build_subdirs()
return {
'subdir': subdirs,
'subdir': ['/' + subdir for subdir in subdirs],
'status': 'success'
}
except EmptyRepositoryException as exc:
@ -288,8 +288,9 @@ class BuildTriggerAnalyze(RepositoryParamResource):
contents = handler.load_dockerfile_contents()
if not contents:
return {
'status': 'error',
'message': 'Could not read the Dockerfile for the trigger'
'status': 'warning',
'message': 'Specified Dockerfile path for the trigger was not found on the main ' +
'branch. This trigger may fail.',
}
# Parse the contents of the Dockerfile.
@ -341,42 +342,40 @@ class BuildTriggerAnalyze(RepositoryParamResource):
'message': 'Repository "%s" referenced by the Dockerfile was not found' % (base_image)
}
# Check to see if the repository is public. If not, we suggest the
# usage of a robot account to conduct the pull.
read_robots = []
# If the base image is public, mark it as such.
if found_repository.visibility.name == 'public':
return {
'status': 'publicbase'
}
# Otherwise, retrieve the list of robots and mark whether they have read access already.
robots = []
if AdministerOrganizationPermission(base_namespace).can():
perm_query = model.user.get_all_repo_users_transitive(base_namespace, base_repository)
user_ids_with_permission = set([user.id for user in perm_query])
def robot_view(robot):
return {
'name': robot.username,
'kind': 'user',
'is_robot': True
'is_robot': True,
'can_read': robot.id in user_ids_with_permission,
}
def is_valid_robot(user):
# Make sure the user is a robot.
if not user.robot:
return False
# Make sure the current user can see/administer the robot.
(robot_namespace, shortname) = parse_robot_username(user.username)
return AdministerOrganizationPermission(robot_namespace).can()
repo_users = list(model.user.get_all_repo_users_transitive(base_namespace, base_repository))
read_robots = [robot_view(user) for user in repo_users if is_valid_robot(user)]
robots = [robot_view(robot) for robot in model.user.list_namespace_robots(base_namespace)]
return {
'namespace': base_namespace,
'name': base_repository,
'is_public': found_repository.visibility.name == 'public',
'robots': read_robots,
'status': 'analyzed'
'robots': robots,
'status': 'requiresrobot',
'is_admin': AdministerOrganizationPermission(base_namespace).can(),
}
except RepositoryReadException as rre:
return {
'status': 'error',
'message': rre.message
'message': 'Could not analyze the repository: %s' % rre.message,
}
except NotImplementedError:
return {
@ -502,8 +501,54 @@ class BuildTriggerFieldValues(RepositoryParamResource):
@internal_only
class BuildTriggerSources(RepositoryParamResource):
""" Custom verb to fetch the list of build sources for the trigger config. """
schemas = {
'BuildTriggerSourcesRequest': {
'type': 'object',
'description': 'Specifies the namespace under which to fetch sources',
'properties': {
'namespace': {
'type': 'string',
'description': 'The namespace for which to fetch sources'
},
},
}
}
@require_repo_admin
@nickname('listTriggerBuildSources')
@validate_json_request('BuildTriggerSourcesRequest')
def post(self, namespace_name, repo_name, trigger_uuid):
""" List the build sources for the trigger configuration thus far. """
namespace = request.get_json()['namespace']
try:
trigger = model.build.get_build_trigger(trigger_uuid)
except model.InvalidBuildTriggerException:
raise NotFound()
user_permission = UserAdminPermission(trigger.connected_user.username)
if user_permission.can():
handler = BuildTriggerHandler.get_handler(trigger)
try:
return {
'sources': handler.list_build_sources_for_namespace(namespace)
}
except RepositoryReadException as rre:
raise InvalidRequest(rre.message)
else:
raise Unauthorized()
@resource('/v1/repository/<apirepopath:repository>/trigger/<trigger_uuid>/namespaces')
@path_param('repository', 'The full path of the repository. e.g. namespace/name')
@path_param('trigger_uuid', 'The UUID of the build trigger')
@internal_only
class BuildTriggerSourceNamespaces(RepositoryParamResource):
""" Custom verb to fetch the list of namespaces (orgs, projects, etc) for the trigger config. """
@require_repo_admin
@nickname('listTriggerBuildSourceNamespaces')
def get(self, namespace_name, repo_name, trigger_uuid):
""" List the build sources for the trigger configuration thus far. """
try:
@ -517,7 +562,7 @@ class BuildTriggerSources(RepositoryParamResource):
try:
return {
'sources': handler.list_build_sources()
'namespaces': handler.list_build_source_namespaces()
}
except RepositoryReadException as rre:
raise InvalidRequest(rre.message)