Add support for pull credentials on builds and build triggers
This commit is contained in:
parent
1fc3c922a9
commit
2006917e03
17 changed files with 355 additions and 37 deletions
|
@ -33,6 +33,13 @@ def get_job_config(build_obj):
|
|||
|
||||
|
||||
def trigger_view(trigger):
|
||||
def user_view(user):
|
||||
return {
|
||||
'name': user.username,
|
||||
'kind': 'user',
|
||||
'is_robot': user.robot,
|
||||
}
|
||||
|
||||
if trigger and trigger.uuid:
|
||||
config_dict = get_trigger_config(trigger)
|
||||
build_trigger = BuildTrigger.get_trigger_for_service(trigger.service.name)
|
||||
|
@ -41,7 +48,8 @@ def trigger_view(trigger):
|
|||
'config': config_dict,
|
||||
'id': trigger.uuid,
|
||||
'connected_user': trigger.connected_user.username,
|
||||
'is_active': build_trigger.is_active(config_dict)
|
||||
'is_active': build_trigger.is_active(config_dict),
|
||||
'pull_user': user_view(trigger.pull_user) if trigger.pull_user else None
|
||||
}
|
||||
|
||||
return None
|
||||
|
@ -88,6 +96,29 @@ class RepositoryBuildList(RepositoryParamResource):
|
|||
'type': 'string',
|
||||
'description': 'Subdirectory in which the Dockerfile can be found',
|
||||
},
|
||||
'pull_credentials': {
|
||||
'type': 'object',
|
||||
'description': 'Credentials used by the builder when pulling images',
|
||||
'required': [
|
||||
'username',
|
||||
'password',
|
||||
'registry'
|
||||
],
|
||||
'properties': {
|
||||
'username': {
|
||||
'type': 'string',
|
||||
'description': 'The username for the pull'
|
||||
},
|
||||
'password': {
|
||||
'type': 'string',
|
||||
'description': 'The password for the pull'
|
||||
},
|
||||
'registry': {
|
||||
'type': 'string',
|
||||
'description': 'The registry hostname for the pull'
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -116,6 +147,7 @@ class RepositoryBuildList(RepositoryParamResource):
|
|||
|
||||
dockerfile_id = request_json['file_id']
|
||||
subdir = request_json['subdirectory'] if 'subdirectory' in request_json else ''
|
||||
pull_credentials = request_json.get('pull_credentials', None)
|
||||
|
||||
# Check if the dockerfile resource has already been used. If so, then it
|
||||
# can only be reused if the user has access to the repository for which it
|
||||
|
@ -130,7 +162,8 @@ class RepositoryBuildList(RepositoryParamResource):
|
|||
repo = model.get_repository(namespace, repository)
|
||||
display_name = user_files.get_file_checksum(dockerfile_id)
|
||||
|
||||
build_request = start_build(repo, dockerfile_id, ['latest'], display_name, subdir, True)
|
||||
build_request = start_build(repo, dockerfile_id, ['latest'], display_name, subdir, True,
|
||||
pull_credentials=pull_credentials)
|
||||
|
||||
resp = build_status_view(build_request, True)
|
||||
repo_string = '%s/%s' % (namespace, repository)
|
||||
|
|
|
@ -15,7 +15,8 @@ from endpoints.common import start_build
|
|||
from endpoints.trigger import (BuildTrigger as BuildTriggerBase, TriggerDeactivationException,
|
||||
TriggerActivationException, EmptyRepositoryException)
|
||||
from data import model
|
||||
from auth.permissions import UserAdminPermission
|
||||
from auth.permissions import UserAdminPermission, AdministerOrganizationPermission
|
||||
from util.names import parse_robot_username
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -133,7 +134,19 @@ class BuildTriggerActivate(RepositoryParamResource):
|
|||
'BuildTriggerActivateRequest': {
|
||||
'id': 'BuildTriggerActivateRequest',
|
||||
'type': 'object',
|
||||
'description': 'Arbitrary json.',
|
||||
'required': [
|
||||
'config'
|
||||
],
|
||||
'properties': {
|
||||
'config': {
|
||||
'type': 'object',
|
||||
'description': 'Arbitrary json.',
|
||||
},
|
||||
'pull_robot': {
|
||||
'type': 'string',
|
||||
'description': 'The name of the robot that will be used to pull images.'
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -154,7 +167,27 @@ class BuildTriggerActivate(RepositoryParamResource):
|
|||
|
||||
user_permission = UserAdminPermission(trigger.connected_user.username)
|
||||
if user_permission.can():
|
||||
new_config_dict = request.get_json()
|
||||
# Update the pull robot (if any).
|
||||
pull_robot_name = request.get_json().get('pull_robot', None)
|
||||
if pull_robot_name:
|
||||
pull_robot = model.lookup_robot(pull_robot_name)
|
||||
if not pull_robot:
|
||||
raise NotFound()
|
||||
|
||||
# Make sure the user has administer permissions for the robot's namespace.
|
||||
(robot_namespace, shortname) = parse_robot_username(pull_robot_name)
|
||||
if not AdministerOrganizationPermission(robot_namespace).can():
|
||||
raise Unauthorized()
|
||||
|
||||
# Make sure the namespace matches that of the trigger.
|
||||
if robot_namespace != namespace:
|
||||
raise Unauthorized()
|
||||
|
||||
# Set the pull robot.
|
||||
trigger.pull_user = pull_robot
|
||||
|
||||
# Update the config.
|
||||
new_config_dict = request.get_json()['config']
|
||||
|
||||
token_name = 'Build Trigger: %s' % trigger.service.name
|
||||
token = model.create_delegate_token(namespace, repository, token_name,
|
||||
|
@ -185,6 +218,7 @@ class BuildTriggerActivate(RepositoryParamResource):
|
|||
log_action('setup_repo_trigger', namespace,
|
||||
{'repo': repository, 'namespace': namespace,
|
||||
'trigger_id': trigger.uuid, 'service': trigger.service.name,
|
||||
'pull_user': trigger.pull_user.username if trigger.pull_user else None,
|
||||
'config': final_config}, repo=repo)
|
||||
|
||||
return trigger_view(trigger)
|
||||
|
@ -214,8 +248,10 @@ class ActivateBuildTrigger(RepositoryParamResource):
|
|||
dockerfile_id, tags, name, subdir = specs
|
||||
|
||||
repo = model.get_repository(namespace, repository)
|
||||
pull_credentials = model.get_pull_credentials(trigger)
|
||||
|
||||
build_request = start_build(repo, dockerfile_id, tags, name, subdir, True)
|
||||
build_request = start_build(repo, dockerfile_id, tags, name, subdir, True,
|
||||
pull_credentials=pull_credentials)
|
||||
|
||||
resp = build_status_view(build_request, True)
|
||||
repo_string = '%s/%s' % (namespace, repository)
|
||||
|
|
|
@ -100,7 +100,7 @@ def check_repository_usage(user_or_org, plan_found):
|
|||
|
||||
|
||||
def start_build(repository, dockerfile_id, tags, build_name, subdir, manual,
|
||||
trigger=None):
|
||||
trigger=None, pull_credentials=None):
|
||||
host = urlparse.urlparse(request.url).netloc
|
||||
repo_path = '%s/%s/%s' % (host, repository.namespace, repository.name)
|
||||
|
||||
|
@ -112,7 +112,9 @@ def start_build(repository, dockerfile_id, tags, build_name, subdir, manual,
|
|||
'docker_tags': tags,
|
||||
'repository': repo_path,
|
||||
'build_subdir': subdir,
|
||||
'pull_credentials': pull_credentials,
|
||||
}
|
||||
|
||||
build_request = model.create_repository_build(repository, token, job_config,
|
||||
dockerfile_id, build_name,
|
||||
trigger)
|
||||
|
|
|
@ -73,8 +73,10 @@ def build_trigger_webhook(namespace, repository, trigger_uuid):
|
|||
# This was just a validation request, we don't need to build anything
|
||||
return make_response('Okay')
|
||||
|
||||
pull_credentials = model.get_pull_credentials(trigger)
|
||||
repo = model.get_repository(namespace, repository)
|
||||
start_build(repo, dockerfile_id, tags, name, subdir, False, trigger)
|
||||
start_build(repo, dockerfile_id, tags, name, subdir, False, trigger,
|
||||
pull_credentials=pull_credentials)
|
||||
|
||||
return make_response('Okay')
|
||||
|
||||
|
|
Reference in a new issue