Skip to content

Cluster Configuration idempotency must be working bi-directionnal #292

@Warkdev

Description

@Warkdev

Hello,

The following code part is checking nicely idempotency of cluster configuration:

https://github.com/IBM-Security/ibmsecurity/blob/master/ibmsecurity/isam/base/cluster/configuration.py#L185

However, if you have missing keys in the input data compared to the existing data, it doesn't check it. I recommended updating the method with the keys to do a bi-directionnal check, see below:

def _check(isamAppliance, cluster_json, ignore_password_for_idempotency):
    """
    Check if provided json values match the configuration on appliance

    :param isamAppliance:
    :param cluster_json:
    :return:
    """

    check_obj = {'value': True, 'warnings':""}

    ret_obj = get(isamAppliance)
    check_obj['warnings'] = ret_obj['warnings']
    sorted_ret_obj = tools.json_sort(ret_obj['data'])
    ret_obj_keys = ret_obj['data'].keys()
    sorted_json_data = tools.json_sort(cluster_json)
    logger.debug("Sorted Existing Data:{0}".format(sorted_ret_obj))
    logger.debug("Sorted Desired  Data:{0}".format(sorted_json_data))

    if ignore_password_for_idempotency:
        temp = copy.deepcopy(
            cluster_json)  # deep copy neccessary: otherwise password parameter would be removed from desired config dict 'cluster_json'. Comparison is done with temp<>ret_obj object
        for idx, x in enumerate(cluster_json):
            if "password" in x:
                logger.debug("Ignoring JSON password entry: '{0}' to satisfy idempotency.".format(x))
                del temp[x]
        logger.debug("Passwordless JSON to Apply: {0}".format(temp))
    else:
        temp = cluster_json

    for key, value in temp.items():
        try:
            if isinstance(value, list):
                if ibmsecurity.utilities.tools.json_sort(
                        ret_obj['data'][key]) != ibmsecurity.utilities.tools.json_sort(value):
                    logger.debug(
                        "For key: {0}, values: {1} and {2} do not match.".format(key, value, ret_obj['data'][key]))
                    check_obj['value']=False
                    return check_obj
            else:
                if ret_obj['data'][key] != value:
                    logger.debug(
                        "For key: {0}, values: {1} and {2} do not match.".format(key, value, ret_obj['data'][key]))
                    check_obj['value']=False
                    return check_obj
            ret_obj_keys.remove(key)
        except:  # In case there is an error looking up the key in existing configuration (missing)
            logger.debug("Exception processing Key: {0} Value: {1} - missing key in current config?".format(key, value))
            check_obj['value']=False
            return check_obj

    if ret_obj_keys != []:
        logger.debug('Some keys are not present in the input anymore: {0}'.format(ret_obj_keys))
        check_obj['value']=False
        return check_obj

    logger.debug("JSON provided already is contained in current appliance configuration.")
    check_obj['value']=True
    return check_obj

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions