Example #1
0
def images_check_impl(request_inputs, image_records):
    user_auth = request_inputs['auth']
    method = request_inputs['method']
    bodycontent = request_inputs['bodycontent']
    params = request_inputs['params']

    return_object = []
    httpcode = 500
    userId, pw = user_auth

    try:
        if 'policyId' in params and params['policyId']:
            bundle_records = catalog.get_policy(user_auth, policyId=params['policyId'])
            policyId = params['policyId']
        else:
            bundle_records = catalog.get_active_policy(user_auth)
            policyId = None
        if not bundle_records:
            httpcode = 404
            raise Exception("user has no active policy to evalute: " + str(user_auth))

        # this is to check that we got at least one evaluation in the response, otherwise routine should throw a 404
        atleastone = False

        if image_records:
            for image_record in image_records:
                imageDigest = image_record['imageDigest']
                return_object_el = {}
                return_object_el[imageDigest] = {}

                tags = []
                if params and 'tag' in params and params['tag']:
                    image_info = anchore_engine.services.common.get_image_info(userId, "docker", params['tag'], registry_lookup=False,
                                                                registry_creds=[])
                    if 'fulltag' in image_info and image_info['fulltag']:
                        params['tag'] = image_info['fulltag']
                    tags.append(params['tag'])

                else:
                    for image_detail in image_record['image_detail']:
                        fulltag = image_detail['registry'] + "/" + image_detail['repo'] + ":" + image_detail['tag']
                        tags.append(fulltag)

                for tag in tags:
                    if tag not in return_object_el[imageDigest]:
                        return_object_el[imageDigest][tag] = []

                    try:
                        if params and 'history' in params and params['history']:
                            results = catalog.get_eval(user_auth, imageDigest=imageDigest, tag=tag,
                                                               policyId=policyId)
                        else:
                            results = [catalog.get_eval_latest(user_auth, imageDigest=imageDigest, tag=tag,
                                                                       policyId=policyId)]
                    except Exception as err:
                        results = []

                    httpcode = 200
                    for result in results:
                        fresult = make_response_policyeval(user_auth, result, params)
                        return_object_el[imageDigest][tag].append(fresult[tag])
                        atleastone = True

                if return_object_el:
                    return_object.append(return_object_el)
        else:
            httpcode = 404
            raise Exception("could not find image record(s) input imageDigest(s)")

        if not atleastone:
            httpcode = 404
            raise Exception("could not find any evaluations for input images")

    except Exception as err:
        logger.debug("operation exception: " + str(err))
        return_object = anchore_engine.services.common.make_response_error(err, in_httpcode=httpcode)
        httpcode = return_object['httpcode']

    return (return_object, httpcode)
Example #2
0
def imagepolicywebhook(bodycontent):

    # TODO - while the image policy webhook feature is in k8s beta, we've decided to make any errors that occur during check still respond with 'allowed: True'.  This should be reverted to default to 'False' on any error, once the k8s feature is further along

    return_object = {
        "apiVersion": "imagepolicy.k8s.io/v1alpha1",
        "kind": "ImageReview",
        "status": {
            "allowed": True,
            "reason": "all images passed anchore policy evaluation"
        }
    }
    httpcode = 200

    try:
        request_inputs = anchore_engine.services.common.do_request_prep(
            connexion.request, default_params={})

        user_auth = request_inputs['auth']
        method = request_inputs['method']
        params = request_inputs['params']
        userId = request_inputs['userId']

        try:

            final_allowed = True
            reason = "unset"

            try:
                try:
                    #incoming = json.loads(bodycontent)
                    incoming = bodycontent
                    logger.debug("incoming post data: " +
                                 json.dumps(incoming, indent=4))
                except Exception as err:
                    raise Exception("could not load post data as json: " +
                                    str(err))

                try:
                    requestUserId = None
                    requestPolicyId = None
                    # see if the request from k8s contains an anchore policy and/or whitelist name
                    if 'annotations' in incoming['spec']:
                        logger.debug(
                            "incoming request contains annotations: " +
                            json.dumps(incoming['spec']['annotations'],
                                       indent=4))
                        requestUserId = incoming['spec']['annotations'].pop(
                            "anchore.image-policy.k8s.io/userId", None)
                        requestPolicyId = incoming['spec']['annotations'].pop(
                            "anchore.image-policy.k8s.io/policyBundleId", None)
                except Exception as err:
                    raise Exception("could not parse out annotations: " +
                                    str(err))

                if not requestUserId:
                    raise Exception(
                        "need to specify an anchore.image-policy.k8s.io/userId annotation with a valid anchore service username as a value"
                    )

                # TODO - get anchore system uber cred to access
                # this data on behalf of user?  tough...maybe see
                # if kuber can make request as anchore-system so
                # that we can switch roles?
                localconfig = anchore_engine.configuration.localconfig.get_config(
                )
                system_user_auth = localconfig['system_user_auth']
                user_record = catalog.get_user(system_user_auth, requestUserId)
                request_user_auth = (user_record['userId'],
                                     user_record['password'])

                reason = "all images passed anchore policy checks"
                final_action = False
                for el in incoming['spec']['containers']:
                    image = el['image']
                    logger.debug("found image in request: " + str(image))
                    image_records = catalog.get_image(request_user_auth,
                                                      tag=image)
                    if not image_records:
                        raise Exception("could not find requested image (" +
                                        str(image) + ") in anchore service DB")

                    for image_record in image_records:
                        imageDigest = image_record['imageDigest']

                        for image_detail in image_record['image_detail']:
                            fulltag = image_detail[
                                'registry'] + "/" + image_detail[
                                    'repo'] + ':' + image_detail['tag']
                            result = catalog.get_eval_latest(
                                request_user_auth,
                                tag=fulltag,
                                imageDigest=imageDigest,
                                policyId=requestPolicyId)
                            if result:
                                httpcode = 200
                                if result['final_action'].upper() not in [
                                        'GO', 'WARN'
                                ]:
                                    final_action = False
                                    raise Exception(
                                        "image failed anchore policy check: " +
                                        json.dumps(result, indent=4))
                                else:
                                    final_action = True

                            else:
                                httpcode = 404
                                final_action = False
                                raise Exception(
                                    "no anchore evaluation available for image: "
                                    + str(image))

                final_allowed = final_action

            except Exception as err:
                reason = str(err)
                final_allowed = False
                httpcode = 200

            return_object['status']['allowed'] = final_allowed
            return_object['status']['reason'] = reason

            anchore_engine.subsys.metrics.counter_inc(
                "anchore_image_policy_webhooks_evaluation_total",
                allowed=final_allowed)

            #logger.debug("final return: " + json.dumps(return_object, indent=4))
            httpcode = 200
        except Exception as err:
            return_object['reason'] = str(err)
            httpcode = 500

    except Exception as err:
        return_object['reason'] = str(err)
        httpcode = 500

    return (return_object, httpcode)