Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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