def volume_claim_clone(): """ Create Kube PVC clone This method is in place of snapshotting a source volume. Volume clones will be used instead of snapshots until Trident supports snapshot creation --- tags: - volumeclaim parameters: - in: body name: pvc_clone_name required: true description: name of the Kube PVC being created (cloned) type: string - in: body name: pvc_source_name required: true description: name of the Kube PVC that is being cloned from type: string - in: body name: build_status required: false description: specifies whether this clone is of a successful or failed build type: string responses: 200: description: PVC Clone was created successfully """ # TODO: document jenkins_build in docstring # TODO: do we need volume name? _validate_input_form_params(request.form, [ 'pvc_clone_name', 'pvc_source_name', 'build_status', 'jenkins_build', 'volume_name' ]) config_document = helpers.get_db_config() if not config_document: raise GenericException(500, GenericException.DB_CONFIG_DOC_NOT_FOUND, "Database Exception") build_status = request.form['build_status'] or 'N/A' if build_status not in ["passed", "failed", "N/A"]: raise GenericException( 406, "Invalid build_status type parameter: accepted values - 'passed', 'failed', 'N/A'" ) # TODO: this name should be created in KubernetesAPI, but currently will impact create_pvc_and_pod() kube = KubernetesAPI() pvc_clone_name = kube.get_kube_resource_name( request.form['pvc_clone_name'], 'pvc') status = kube.create_pvc_clone_resource( clone=pvc_clone_name, source=request.form['pvc_source_name']) # record snapshot in db db_connect = helpers.connect_db() if not db_connect: raise GenericException(500, GenericException.DB_CONNECTION_ERROR, "Database Exception") # TODO: Replace Snapshot doc with Clone document # TODO: Do we need volume or pvc_source_name? snapshot_doc = Snapshot( name=request.form['pvc_clone_name'], pvc_name=pvc_clone_name, # TODO: Why do we need volume? Also, this is not the clone volume name, # but the parent pipeline volume name which we use later for only querying. # Reflect key-name appropriately # If we dont need volume_name, we can replace this with parent_pipeline_pvc_name volume=request.form['volume_name'], jenkins_build=request.form['jenkins_build'], build_status=build_status) snapshot_doc.store(db_connect) return jsonify(status)
def pipeline_create(): """ Setup a pipeline for an SCM project with a specific branch This endpoint is used by the DevOps admin At the end of successful execution, a Jenkins pipeline for the SCM project is created with required build parameters --- tags: - pipeline parameters: - in: path name: scm-url required: true description: SCM url for this project type: string - in: path name: scm-branch required: true description: SCM branch for this project type: string - in: path name: export-policy required: false description: export-policy for this project type: string responses: 200: description: Pipeline has been created successfully """ ##### # 1. Validate input form parameters # 2. Get config document for setting up the pipeline details # 3. Gather storage details for creating PVC for this pipeline # 4. Create a Kube PVC (Trident creates a PV and an ONTAP volume, maps it to this PVC. We manage only the PVCs) # 5. Create Jenkins job # 6. Setup Jenkins purge job for this pipeline # 7. Record all pipeline details in database ##### # Validate input web form parameters from the application _validate_input_form_params(request.form, ['scm-branch', 'scm-url']) connect, config = _get_config_from_db() # Gather storage details for creating PVC scm_project_url = helpers.sanitize_scm_url(request.form['scm-url']) if scm_project_url is None: raise GenericException(406, "Invalid SCM URL provided") pipeline = { 'name': '-'.join([ 'pipeline', helpers.extract_name_from_git_url(request.form['scm-url']), request.form['scm-branch'] ]), 'export_policy': request.form.get( 'export-policy', 'default'), # set default export policy if not specified 'scm_url': scm_project_url } # Create PVC. Once we create a Kube PVC, Trident creates an ONTAP volume and a PV for this PVC kube = KubernetesAPI() vol_size = "10000" # set default vol size to 10Gig, 10000 in MB storage_class = config.get( 'storage_class', 'basic') # set default storage class if not specified pvc_response = kube.create_pvc_resource(vol_name=pipeline['name'], vol_size=vol_size, storage_class=storage_class) if not helpers.verify_successful_response(pvc_response): raise GenericException(500, "Kubernetes PVC creation error") # setup params for Jenkins pipeline job pipeline_job = helpers.set_jenkins_job_params('ci-pipeline') pipeline_job['volume_claim_name'] = pvc_response['name'] pipeline_job['scm_url'] = request.form['scm-url'] pipeline_job['scm_branch'] = request.form['scm-branch'] # TODO: should this volume_name be populated as part of pvc_response? - # but might want to handle if PVC creation has failed in KubernetesAPI.py pipeline_job['volume_name'] = kube.get_volume_name_from_pvc( pvc_response['name']) # Get associated volume with PVC # TODO: This cannot be None. # Validate after bootstrapping, PVCs for all services to be part of the config document. # Remove this after including validation if config.get('scm_pvc_name') is None: pipeline_job['scm_volume_claim'] = kube.get_kube_resource_name( config['scm_volume'], 'pvc') purge_job = helpers.set_jenkins_job_params( 'trigger-purge') # setup params for Jenkins purge job # Create Jenkins CI and purge jobs for this pipeline try: jenkins = JenkinsAPI(config['jenkins_url'], config['jenkins_user'], config['jenkins_pass']) except Exception as exc: raise GenericException(500, "Jenkins connection error: %s" % str(exc)) try: jenkins_job_url = jenkins.create_job(job_name=pipeline['name'], params=pipeline_job, form_fields=request.form) jenkins.create_job(job_name='purge_policy_enforcer', params=purge_job, form_fields=None) except Exception as exc: raise GenericException(500, "Jenkins Job Creation Error: %s" % str(exc)) # Complete gathering pipeline details pipeline['pvc'] = pvc_response['name'] pipeline['volume'] = pipeline_job['volume_name'] pipeline['jenkins_url'] = jenkins_job_url # Record new pipeline in database # TODO: type=pipeline document try: new_pipeline_document = Pipeline(**pipeline) new_pipeline_document.store(connect) except Exception as exc: raise GenericException( 500, "Error recording new project in the DB, please contact your administrator", "Database Exception" + str(exc)) # TODO: Can we do a better in-page rendering instead of navigating to a raw JSON msg? return jsonify({'project_name': pipeline['name']}), 200