コード例 #1
0
def ovdc_compute_policy_update(request_data, tenant_auth_token):
    """Request handler for ovdc compute-policy update operation.

    Required data: ovdc_id, compute_policy_action, compute_policy_names

    :return: Dictionary with task href.
    """
    required = [
        RequestKey.OVDC_ID, RequestKey.COMPUTE_POLICY_ACTION,
        RequestKey.COMPUTE_POLICY_NAME
    ]
    req_utils.validate_payload(request_data, required)

    defaults = {
        RequestKey.REMOVE_COMPUTE_POLICY_FROM_VMS: False,
    }
    validated_data = {**defaults, **request_data}
    req_utils.validate_payload(request_data, required)

    action = validated_data[RequestKey.COMPUTE_POLICY_ACTION]
    cp_name = validated_data[RequestKey.COMPUTE_POLICY_NAME]
    ovdc_id = validated_data[RequestKey.OVDC_ID]
    remove_compute_policy_from_vms = validated_data[
        RequestKey.REMOVE_COMPUTE_POLICY_FROM_VMS]  # noqa: E501

    client, _ = vcd_utils.connect_vcd_user_via_token(tenant_auth_token)

    cpm = ComputePolicyManager(client)
    cp_href = None
    cp_id = None
    if cp_name == SYSTEM_DEFAULT_COMPUTE_POLICY_NAME:
        for _cp in cpm.list_compute_policies_on_vdc(ovdc_id):
            if _cp['name'] == cp_name:
                cp_href = _cp['href']
                cp_id = _cp['id']
    else:
        try:
            _cp = cpm.get_policy(cp_name)
            cp_href = _cp['href']
            cp_id = _cp['id']
        except EntityNotFoundException:
            pass

    if cp_href is None:
        raise BadRequestError(f"Compute policy '{cp_name}' not found.")

    if action == ComputePolicyAction.ADD:
        cpm.add_compute_policy_to_vdc(ovdc_id, cp_href)
        return f"Added compute policy '{cp_name}' ({cp_id}) to ovdc " \
               f"({ovdc_id})"

    if action == ComputePolicyAction.REMOVE:
        return cpm.remove_compute_policy_from_vdc(
            ovdc_id,
            cp_href,
            remove_compute_policy_from_vms=remove_compute_policy_from_vms)

    raise BadRequestError("Unsupported compute policy action")
コード例 #2
0
    def update_status(self, tenant_auth_token, is_jwt_token, request_data):
        tenant_client = connect_vcd_user_via_token(
            tenant_auth_token=tenant_auth_token,
            is_jwt_token=is_jwt_token)

        if not tenant_client.is_sysadmin():
            raise UnauthorizedRequestError(
                error_message='Unauthorized to update CSE')

        action = request_data.get(RequestKey.SERVER_ACTION)
        if self._state == ServerState.RUNNING:
            if action == ServerAction.ENABLE:
                raise BadRequestError(
                    error_message='CSE is already enabled and running.')
            elif action == ServerAction.DISABLE:
                self._state = ServerState.DISABLED
                message = 'CSE has been disabled.'
            elif action == ServerAction.STOP:
                raise BadRequestError(
                    error_message='Cannot stop CSE while it is enabled. '
                                  'Disable the service first')
        elif self._state == ServerState.DISABLED:
            if action == ServerAction.ENABLE:
                self._state = ServerState.RUNNING
                message = 'CSE has been enabled and is running.'
            elif action == ServerAction.DISABLE:
                raise BadRequestError(
                    error_message='CSE is already disabled.')
            elif action == 'stop':
                message = 'CSE graceful shutdown started.'
                n = self.active_requests_count()
                if n > 0:
                    message += f" CSE will finish processing {n} requests."
                self._state = ServerState.STOPPING
        elif self._state == ServerState.STOPPING:
            if action == ServerAction.ENABLE:
                raise BadRequestError(
                    error_message='Cannot enable CSE while it is being'
                                  'stopped.')
            elif action == ServerAction.DISABLE:
                raise BadRequestError(
                    error_message='Cannot disable CSE while it is being'
                                  ' stopped.')
            elif action == ServerAction.STOP:
                message = 'CSE graceful shutdown is in progress.'

        return message
コード例 #3
0
def process_request(body):
    from container_service_extension.service import Service
    LOGGER.debug(f"body: {json.dumps(body)}")
    url = body['requestUri']

    # url_data = _parse_request_url(method=body['method'], url=body['requestUri']) # noqa: E501
    url_data = _get_url_data(body['method'], url)
    operation = url_data[_OPERATION_KEY]

    # check if server is disabled
    if operation not in (CseOperation.SYSTEM_INFO, CseOperation.SYSTEM_UPDATE)\
            and not Service().is_running():
        raise BadRequestError(error_message='CSE service is disabled. Contact'
                              ' the System Administrator.')

    # create request data dict from request body data
    request_data = {}
    if len(body['body']) > 0:
        raw_body = base64.b64decode(body['body']).decode(
            sys.getfilesystemencoding())  # noqa: E501
        request_data = json.loads(raw_body)
        LOGGER.debug(f"request body: {request_data}")
    # update request data dict with query params data
    if body['queryString']:
        query_params = dict(parse_qsl(body['queryString']))
        request_data.update(query_params)
        LOGGER.debug(f"query parameters: {query_params}")
    # update request spec with operation specific data in the url
    request_data.update(url_data)
    # remove None values from request payload
    data = {k: v for k, v in request_data.items() if v is not None}

    # extract out the authorization token
    tenant_auth_token = body['headers'].get('x-vcloud-authorization')
    is_jwt_token = False
    auth_header = body['headers'].get('Authorization')
    if auth_header:
        tokens = auth_header.split(" ")
        if len(tokens) == 2 and tokens[0].lower() == 'bearer':
            tenant_auth_token = tokens[1]
            is_jwt_token = True

    # process the request
    body_content = \
        OPERATION_TO_HANDLER[operation](data, tenant_auth_token, is_jwt_token)

    if not (isinstance(body_content, (list, dict))):
        body_content = {RESPONSE_MESSAGE_KEY: str(body_content)}

    reply = {
        'status_code': operation.ideal_response_code,
        'body': body_content
    }
    LOGGER.debug(f"reply: {str(reply)}")
    return reply
コード例 #4
0
def cluster_upgrade(request_data, tenant_auth_token, is_jwt_token):
    """Request handler for cluster upgrade operation.

    data validation handled in broker

    :return: Dict
    """
    _, broker = broker_manager.get_cluster_info(request_data,
                                                tenant_auth_token,
                                                is_jwt_token)
    if isinstance(broker, vcdbroker.VcdBroker):
        return broker.upgrade_cluster(request_data)

    raise BadRequestError(
        error_message="'cluster upgrade' operation is not supported by non "
        "native clusters.")
コード例 #5
0
def cluster_upgrade_plan(request_data, tenant_auth_token, is_jwt_token):
    """Request handler for cluster upgrade-plan operation.

    data validation handled in broker

    :return: List[Tuple(str, str)]
    """
    _, broker = broker_manager.get_cluster_info(request_data,
                                                tenant_auth_token,
                                                is_jwt_token)
    if isinstance(broker, vcdbroker.VcdBroker):
        return broker.get_cluster_upgrade_plan(request_data)

    raise BadRequestError(
        error_message="'cluster upgrade-plan' operation is not supported by "
        "non native clusters.")
コード例 #6
0
def node_delete(request_data, tenant_auth_token, is_jwt_token):
    """Request handler for node delete operation.

    Required data: cluster_name, node_names_list
    Optional data and default values: org_name=None, ovdc_name=None

    (data validation handled in brokers)

    :return: Dict
    """
    _, broker = broker_manager.get_cluster_info(request_data,
                                                tenant_auth_token,
                                                is_jwt_token)
    if isinstance(broker, vcdbroker.VcdBroker):
        return broker.delete_nodes(request_data)

    raise BadRequestError(
        error_message="'node delete' operation is not supported by non native "
        "clusters.")
コード例 #7
0
def validate_payload(payload, required_keys):
    """Validate a given payload is good for a particular request.

    Raise appropriate error if keys are missing or if the corresponding value
    in the payload is None. Otherwise return True.

    :param dict payload:
    :param list required_keys:

    :return: True, if payload is valid
    :rtype: bool
    """
    valid = True
    minor_error_code = None

    required = set(required_keys)
    if not required.issubset(payload.keys()):
        missing_keys = list(required.difference(payload.keys()))
        error_message = \
            f"Missing required keys in request payload: {missing_keys}"
        valid = False
        key = RequestKey(missing_keys[0])
        if key in MISSING_KEY_TO_MINOR_ERROR_CODE_MAPPING:
            minor_error_code = MISSING_KEY_TO_MINOR_ERROR_CODE_MAPPING[key]
    else:
        keys_with_none_value = [
            k for k, v in payload.items() if k in required and v is None
        ]  # noqa: E501
        if len(keys_with_none_value) > 0:
            error_message = f"Following keys in request payloads have None as value: {keys_with_none_value}"  # noqa: E501
            valid = False
            key = RequestKey(keys_with_none_value[0])
            if key in INVALID_VALUE_TO_MINOR_ERROR_CODE_MAPPING:
                minor_error_code = INVALID_VALUE_TO_MINOR_ERROR_CODE_MAPPING[
                    key]  # noqa: E501

    if not valid:
        raise BadRequestError(error_message, minor_error_code)

    return valid
コード例 #8
0
def validate_request_payload(input_spec: dict, reference_spec: dict,
                             exclude_fields=[]):
    """Validate the desired spec with the current spec.

    :param dict input_spec: input spec
    :param dict reference_spec: reference spec to validate the desired spec
    :param list exclude_fields: exclude the list of given flattened-keys from validation  # noqa: E501
    :return: true on successful validation
    :rtype: bool
    :raises: BadRequestError on encountering invalid payload value
    """
    input_dict = utils.flatten_dictionary(input_spec)
    reference_dict = utils.flatten_dictionary(reference_spec)
    exclude_key_set = set(exclude_fields)
    key_set_for_validation = set(input_dict.keys()) - exclude_key_set
    keys_with_invalid_value = [key for key in key_set_for_validation
                               if input_dict.get(key) != reference_dict.get(key)]  # noqa: E501
    if len(keys_with_invalid_value) > 0:
        error_msg = f"Invalid input values found in {sorted(keys_with_invalid_value)}"  # noqa: E501
        raise BadRequestError(error_msg)

    return True
コード例 #9
0
def node_create(request_data, tenant_auth_token, is_jwt_token):
    """Request handler for node create operation.

    Required data: cluster_name, network_name
    Optional data and default values: org_name=None, ovdc_name=None,
        num_nodes=1, num_cpu=None, mb_memory=None, storage_profile_name=None,
        template_name=default, template_revision=default,
        ssh_key=None, rollback=True, enable_nfs=False,

    (data validation handled in brokers)

    :return: Dict
    """
    # Currently node create is a vCD only operation.
    # Different from resize because this can create nfs nodes
    _, broker = broker_manager.get_cluster_info(request_data,
                                                tenant_auth_token,
                                                is_jwt_token)
    if isinstance(broker, vcdbroker.VcdBroker):
        return broker.create_nodes(request_data)

    raise BadRequestError(
        error_message="'node create' operation is not supported by non native "
        "clusters.")