示例#1
0
def i_have_name_section_configured(step, name, type, radish_world=None):
    if radish_world is None:
        radish_world = world

    step.context.type = type
    step.context.name = name

    if type == "resource":
        if (name in resource_name.keys()):
            name = resource_name[name]

        found_resource = radish_world.config.terraform.resources(name)

        if hasattr(found_resource,
                   'resource_list') and found_resource.resource_list:
            step.context.resource_type = name
            step.context.defined_resource = name
            step.context.stash = radish_world.config.terraform.resources(name)
        else:
            skip_step(step, name)
    else:
        if type in radish_world.config.terraform.terraform_config:
            if name in radish_world.config.terraform.terraform_config[type]:
                step.context.stash = radish_world.config.terraform.terraform_config[
                    type][name]
            else:
                step.context.stash = radish_world.config.terraform.terraform_config[
                    type]

        else:
            skip_step(step, type)
def its_key_metadata_has_something(_step_obj, key, value, has_step=True):
    match = _step_obj.context.match

    if match.equals(key, 'values'):
        Error(
            _step_obj,
            'The key "values" is not metadata, please use the "When its property has something" step instead.'
        )

    found_list = []
    for resource in _step_obj.context.stash:
        # document this behavior
        key_metadata = match.get(resource, key, default={})
        if not isinstance(key_metadata, (list, dict, set)):
            key_metadata = [key_metadata]

        if has_step and not match.contains(key_metadata, value):
            continue
        elif not has_step and match.contains(key_metadata, value):
            continue

        found_list.append(resource)

    _step_obj.context.stash = found_list

    if not found_list:
        if has_step:
            skip_step(_step_obj,
                      message='Could not find "{}" in "{}" metadata.'.format(
                          value, key))
        if not has_step:
            skip_step(_step_obj,
                      message='Found "{}" in "{}" metadata for all resources.'.
                      format(value, key))
def its_key_is_not_value(_step_obj, key, value, dict_value=None, address=Null):
    orig_key = key
    if key == 'reference':
        if address is not Null:
            key = Defaults.r_mount_addr_ptr
        elif address is Null:
            key = Defaults.r_mount_addr_ptr_list

    key = str(key).lower()
    found_list = []
    for obj in _step_obj.context.stash:
        object_key = obj.get(key, Null)

        if object_key is Null:
            object_key = obj.get('values', {})
            if isinstance(object_key, list):
                object_keys = []
                for object_key_element in object_key:
                    if str(object_key_element.get(key, Null)).lower() != str(value).lower():
                        object_keys.append(object_key_element.get(key, Null))

                object_key = [keys for keys in object_keys if keys is not Null]
            else:
                object_key = object_key.get(key, Null)

        if address is not Null and isinstance(object_key, dict) and address in object_key:
            object_key = object_key.get(address, Null)

        if isinstance(object_key, str):
            if "[" in object_key:
                object_key = object_key.split('[')[0]

            if object_key != value:
                found_list.append(obj)

        elif isinstance(object_key, (int, bool)) and str(object_key).lower() != str(value).lower():
            found_list.append(obj)

        elif isinstance(object_key, list) and value not in object_key:
            found_list.append(obj)

        elif isinstance(object_key, dict):
            if value not in object_key.keys() or (dict_value is not None and (str(object_key[value]).lower() != str(dict_value).lower())):
                found_list.append(obj)

    if found_list != []:
        _step_obj.context.stash = found_list
        _step_obj.context.addresses = get_resource_address_list_from_stash(found_list)
    else:
        if dict_value is None:
            skip_step(_step_obj, message='Found {} {} in {}.'.format(value, orig_key,
                                                                     ', '.join(_step_obj.context.addresses)))
        else:
            skip_step(_step_obj, message='Found {}={} {} in {}.'.format(value, dict_value, orig_key,
                                                                        ', '.join(_step_obj.context.addresses)))
示例#4
0
def its_key_is_value(_step_obj, key, value):
    orig_key = key
    if key == 'reference':
        key = Defaults.address_pointer

    found_list = []
    for obj in _step_obj.context.stash:
        object_key = obj.get('values', {})
        if isinstance(object_key, list):
            object_keys = []
            for object_key_element in object_key:
                if isinstance(object_key_element, dict):
                    filtered_key = object_key_element.get(key)
                    filtered_key = str(filtered_key) if isinstance(
                        filtered_key, (int, bool)) else filtered_key

                    if isinstance(
                            filtered_key,
                            str) and filtered_key.lower() == value.lower():
                        found_list.append(object_key_element)
                else:
                    object_keys.append(object_key_element.get(key, Null))

            object_key = [keys for keys in object_keys if keys is not Null]
        else:
            object_key = object_key.get(key, Null)

        if object_key is Null:
            object_key = obj.get(key, Null)

        if isinstance(object_key, str):
            if "[" in object_key:
                object_key = object_key.split('[')[0]

            if object_key.lower() == value.lower():
                found_list.append(obj)

        elif isinstance(object_key, (int, bool)) and object_key == value:
            found_list.append(obj)

        elif isinstance(object_key, list) and value in object_key:
            found_list.append(obj)

        elif isinstance(object_key, dict) and (value in object_key.keys()):
            found_list.append(obj)

    if found_list != []:
        _step_obj.context.stash = found_list
        _step_obj.context.addresses = get_resource_address_list_from_stash(
            found_list)
    else:
        skip_step(_step_obj,
                  message='Can not find {} {} in {}.'.format(
                      value, orig_key, ', '.join(_step_obj.context.addresses)))
示例#5
0
def i_have_resource_defined(step, resource, radish_world=None):
    if radish_world is None:
        radish_world = world

    if (resource in resource_name.keys()):
        resource = resource_name[resource]

    found_resource = radish_world.config.terraform.resources(resource)

    if found_resource.resource_list:
        step.context.resource_type = resource
        step.context.defined_resource = resource
        step.context.stash = radish_world.config.terraform.resources(resource)
    else:
        skip_step(step, '{} resource'.format(resource))
示例#6
0
def its_key_is_value(_step_obj, key, value):
    search_key = str(key).lower()
    found_list = []
    for obj in _step_obj.context.stash:
        object_key = obj.get(key, Null)

        if object_key is not Null:
            object_key = object_key.split('[')[0]

        if object_key == value:
            found_list.append(obj)

    if found_list is not []:
        _step_obj.context.stash = found_list
    else:
        skip_step(_step_obj, value)
示例#7
0
def its_key_is_value(_step_obj, key, value):
    search_key = str(key).lower()
    found_list = []
    for obj in _step_obj.context.stash:
        object_key = obj.get(key, Null)

        if object_key is Null:
            object_key = obj.get('values', {})
            if type(object_key) is list:
                object_keys = []
                for object_key_element in object_key:
                    if type(object_key_element) is dict:
                        filtered_key = object_key_element.get(key)
                        if type(filtered_key) is str and filtered_key.lower() == value.lower():
                            found_list.append(object_key_element)
                    else:
                        object_keys.append(object_key_element.get(key, Null))

                object_key = [keys for keys in object_keys if keys is not Null]
            else:
                object_key = object_key.get(key, Null)

        if type(object_key) is str:
            if "[" in object_key:
                object_key = object_key.split('[')[0]

            if object_key.lower() == value.lower():
                found_list.append(obj)

        elif type(object_key) in (int, bool) and object_key == value:
            found_list.append(obj)

        elif type(object_key) is list and value in object_key:
            found_list.append(obj)

        elif type(object_key) is dict and (value in object_key.keys()):
            found_list.append(obj)

    if found_list != []:
        _step_obj.context.stash = found_list
        _step_obj.context.addresses = get_resource_address_list_from_stash(found_list)
    else:
        skip_step(_step_obj, value)
示例#8
0
def its_property_contains_key(step,
                              property,
                              key,
                              resourcelist=TerraformResourceList):
    if step.context.stash.__class__ is resourcelist:
        number_of_resources = len(step.context.stash.resource_list)
        step.context.stash = step.context.stash.find_property(
            property).find_property(key)
        if step.context.stash:
            if len(step.context.stash.properties) > 0:
                if number_of_resources > len(step.context.stash.properties):
                    write_stdout(
                        level='INFO',
                        message=
                        'Some of the resources does not have {} property defined within.\n'
                        'Removed {} resource (out of {}) from the test scope.\n\n'
                        .format(
                            property,
                            (number_of_resources -
                             len(step.context.stash.properties)),
                            number_of_resources,
                        ))
            else:
                skip_step(
                    step,
                    resource=str(property) + " with key " + str(key),
                    message='Can not find {resource} property in any resource.'
                )
        else:
            skip_step(
                step,
                resource=str(property) + " with key " + str(key),
                message='Can not find {resource} property in any resource.')
    else:
        skip_step(step)
示例#9
0
def its_key_is_not_value(_step_obj, key, value):
    search_key = str(key).lower()
    found_list = []
    for obj in _step_obj.context.stash:
        object_key = obj.get(key, Null)

        if object_key is Null:
            object_key = obj.get('values', {})
            if type(object_key) is list:
                object_keys = []
                for object_key_element in object_key:
                    if object_key_element.get(key, Null) != value:
                        object_keys.append(object_key_element.get(key, Null))

                object_key = [keys for keys in object_keys if keys is not Null]
            else:
                if object_key.get(key, Null) != value:
                    object_key = object_key.get(key, Null)

        if type(object_key) is str:
            if "[" in object_key:
                object_key = object_key.split('[')[0]

            if object_key != value:
                found_list.append(obj)

        elif type(object_key) in (int, bool) and object_key != value:
            found_list.append(obj)

        elif type(object_key) is list and value not in object_key:
            found_list.append(obj)

        elif type(object_key) is dict and (value in object_key.keys()):
            found_list.append(obj)

    if found_list is not []:
        _step_obj.context.stash = found_list
    else:
        skip_step(_step_obj, value)
示例#10
0
文件: terrain.py 项目: timgates42/cli
def exclude_resources(step):
    if not hasattr(step.context, 'resources_to_exclude') or not step.context.resources_to_exclude:
        return 

    if step.context_class != 'given' or not step.context.stash:
        return
    
    match = step.context.match
    resources_to_exclude = step.context.resources_to_exclude
    resources = []

    for resource in step.context.stash:
        address = resource.get('address', '')
        if match.regex_match(resources_to_exclude, address) is None:
            resources.append(resource)
    
    step.context.stash = resources

    # if stash is empty, skip
    # note that if the stash was empty from the Given step, this function will not run
    if not step.context.stash:
        skip_step(step, step.context.name)
示例#11
0
 def test_skip_step(self, *args):
     step = MockedStep()
     skip_step(step)
     self.assertEqual(step.state, 'skipped')
示例#12
0
def i_have_name_section_configured(_step_obj,
                                   name,
                                   type_name='resource',
                                   _terraform_config=world):
    '''
    Finds given resource or variable by name and returns it. Skips the step (and further steps) if it is not found.

    :param _step_obj: Internal, step object for radish.
    :param name: String of the name of the resource_type or variable.
    :param type_name: String of the type, either resource(s) or variable(s)
    :param _terraform_config: Internal, terraform configuration.
    :return:
    '''
    assert (type_name in ['resource', 'resources',
                          'variable', 'variables',
                          'output', 'outputs',
                          'provider', 'providers',
                          'data', 'datas']), \
        '{} configuration type does not exist or not implemented yet. ' \
        'Use resource(s), provider(s), variable(s), output(s) or data(s) instead.'.format(type_name)

    if type_name.endswith('s'):
        type_name = type_name[:-1]

    # Process the tags
    _step_obj = look_for_bdd_tags(_step_obj)

    if name in ('a resource', 'any resource', 'resources'):
        _step_obj.context.type = type_name
        _step_obj.context.name = name
        _step_obj.context.stash = recursive_jsonify([
            obj for key, obj in
            _terraform_config.config.terraform.resources_raw.items()
        ])
        _step_obj.context.addresses = get_resource_address_list_from_stash(
            _step_obj.context.stash)
        _step_obj.context.property_name = type_name
        return True

    elif name in ('an output', 'any output', 'outputs'):
        _step_obj.context.type = 'output'
        _step_obj.context.name = name
        _step_obj.context.stash = recursive_jsonify([
            obj for key, obj in _terraform_config.config.terraform.
            configuration['outputs'].items()
        ])
        _step_obj.context.addresses = get_resource_address_list_from_stash(
            _terraform_config.config.terraform.configuration['outputs'])
        _step_obj.context.property_name = 'output'
        return True

    elif name in ('a variable', 'any variable', 'variables'):
        _step_obj.context.type = 'variable'
        _step_obj.context.name = name
        _step_obj.context.stash = recursive_jsonify([
            obj for key, obj in _terraform_config.config.terraform.
            configuration['variables'].items()
        ])
        _step_obj.context.addresses = 'variable'
        _step_obj.context.property_name = 'variable'
        return True

    elif name.startswith('resource that supports'):
        filter_property = re.match(r'resource that supports (.*)',
                                   name).group(1)

        resource_types_supports_tags = find_root_by_key(
            _terraform_config.config.terraform.resources_raw,
            filter_property,
            return_key='type')
        resource_list = []
        for resource_type in resource_types_supports_tags:
            # Issue-168: Mounted resources causes problem on recursive searching for resources that supports tags
            #            We are removing all mounted resources here for future steps, since we don't need them for
            #            tags checking.
            found_resources = remove_mounted_resources(
                _terraform_config.config.terraform.find_resources_by_type(
                    resource_type))
            found_resources = transform_asg_style_tags(found_resources)
            resource_list.extend(found_resources)

        if resource_list:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = recursive_jsonify(resource_list)
            _step_obj.context.addresses = get_resource_address_list_from_stash(
                resource_list)
            _step_obj.context.property_name = type_name
            return True

    elif type_name == 'resource':
        name = convert_resource_type(name)
        resource_list = _terraform_config.config.terraform.find_resources_by_type(
            name)

        if resource_list:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = recursive_jsonify(resource_list)
            _step_obj.context.addresses = get_resource_address_list_from_stash(
                resource_list)
            _step_obj.context.property_name = type_name
            return True

    elif type_name == 'variable':
        found_variable = _terraform_config.config.terraform.variables.get(
            name, None)

        if found_variable:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = recursive_jsonify(found_variable)
            _step_obj.context.addresses = name
            _step_obj.context.property_name = type_name
            return True

    elif type_name == 'output':
        found_output = _terraform_config.config.terraform.outputs.get(
            name, None)

        if found_output:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = recursive_jsonify(found_output)
            _step_obj.context.addresses = name
            _step_obj.context.property_name = type_name
            return True

    elif type_name == 'provider':
        found_provider = _terraform_config.config.terraform.get_providers_from_configuration(
            name)

        if found_provider:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = recursive_jsonify(found_provider)
            _step_obj.context.addresses = name
            _step_obj.context.address = name
            _step_obj.context.property_name = type_name
            return True

    elif type_name == 'data':
        name = convert_resource_type(name)
        data_list = _terraform_config.config.terraform.find_data_by_type(name)

        if data_list:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = recursive_jsonify(data_list)
            _step_obj.context.addresses = name
            _step_obj.context.address = name
            _step_obj.context.property_name = type_name
            return True

    skip_step(_step_obj, name)
示例#13
0
def it_condition_contain_something(step_obj,
                                   something,
                                   propertylist=TerraformPropertyList,
                                   resourcelist=TerraformResourceList):

    if something in resource_name.keys():
        something = resource_name[something]

    step_can_skip = step_condition(step_obj) in ["given", "when"]

    if step_obj.context.stash.__class__ is propertylist:
        for prop in step_obj.context.stash.properties:
            value = parse_hcl_value(prop.property_value,
                                    world.config.terraform.terraform_config)

            if value is not None:
                assert (value == something or something.lower() in value), \
                    '{} property in {} can not be found in {} ({}). It is set to {} instead'.format(something,
                                                                                                    prop.property_name,
                                                                                                    prop.resource_name,
                                                                                                    prop.resource_type,
                                                                                                    value)
            else:
                write_stdout(
                    level='WARNING',
                    message='Can not get value of {} in {}/{}. '
                    'Might be set by an unknown source (module, etc. )\n'
                    'Value : {}'.format(something, prop.property_name,
                                        prop.resource_type,
                                        prop.property_value))
                step_obj.state = 'skipped'

    elif step_obj.context.stash.__class__ is resourcelist:
        if step_can_skip is False:
            step_obj.context.stash.should_have_properties(something)
            step_obj.context.stash = step_obj.context.stash.find_property(
                something)
            assert step_obj.context.stash.properties, \
                'No defined property/value found for {}.'.format(something)
            step_obj.context.stash = step_obj.context.stash.properties
        else:
            try:
                step_obj.context.stash.should_have_properties(something)
                number_of_resources = len(step_obj.context.stash.resource_list)
                step_obj.context.stash = step_obj.context.stash.find_property(
                    something)
                if step_obj.context.stash:
                    if number_of_resources > len(
                            step_obj.context.stash.properties):
                        write_stdout(
                            level='INFO',
                            message=
                            'Some of the resources does not have {} property defined within.\n'
                            'Removed {} resource (out of {}) from the test scope.\n'
                            '\n'.format(
                                something,
                                (number_of_resources -
                                 len(step_obj.context.stash.properties)),
                                number_of_resources,
                            ))
            except Exception as e:
                number_of_resources = len(step_obj.context.stash.resource_list)
                step_obj.context.stash = step_obj.context.stash.find_property(
                    something)
                if step_obj.context.stash:
                    write_stdout(
                        level='INFO',
                        message=
                        'Some of the resources does not have {} property defined within.\n'
                        'Removed {} resource (out of {}) from the test scope.\n\n'
                        'Due to : \n'
                        '{}'.format(something,
                                    (number_of_resources -
                                     len(step_obj.context.stash.properties)),
                                    number_of_resources, str(e)))
                else:
                    skip_step(
                        step_obj,
                        resource=something,
                        message=
                        'Can not find {resource} property in any resource.')

    elif step_obj.context.stash.__class__ is dict:
        if something in step_obj.context.stash:
            step_obj.context.stash = step_obj.context.stash[something]
        else:
            if step_can_skip:
                skip_step(
                    step_obj,
                    resource=something,
                    message=
                    'Can not find {resource} resource in terraform files.')
            else:
                assert False, '{} does not exist.'.format(something)
示例#14
0
def it_condition_contain_something(_step_obj,
                                   something,
                                   inherited_values=Null):
    prop_list = []

    _step_obj.context.stash = inherited_values if inherited_values is not Null else _step_obj.context.stash

    if _step_obj.context.type in ('resource', 'data'):
        for resource in _step_obj.context.stash:
            if not isinstance(resource, dict) \
                    or 'values' not in resource \
                    or 'address' not in resource \
                    or 'type' not in resource:
                resource = {
                    'values': resource,
                    'address': resource,
                    'type': _step_obj.context.name
                }

            values = resource.get('values', resource.get('expressions', {}))
            if not values:
                values = seek_key_in_dict(resource, something)

            found_value = Null
            found_key = Null
            if isinstance(values, dict):
                found_key = values.get(something,
                                       seek_key_in_dict(values, something))
                if not isinstance(found_key, list):
                    found_key = [{something: found_key}]

                if len(found_key):
                    found_key = found_key[0] if len(
                        found_key
                    ) == 1 and something in found_key[0] else found_key

                    if isinstance(found_key, dict):
                        found_value = jsonify(
                            found_key.get(something, found_key))
                    else:
                        found_value = found_key
            elif isinstance(values, list):
                found_value = []

                for value in values:

                    if isinstance(value, dict):
                        # First search in the keys
                        found_key = seek_key_in_dict(value, something)

                        # Then search in the values with 'key'
                        if not found_key:
                            found_key = seek_regex_key_in_dict_values(
                                value, 'key', something)

                            if found_key:
                                found_key = found_key[0]
                                found_value = value.get('value')
                                break
                    elif isinstance(value, list):
                        found_key, found_value = it_condition_contain_something(
                            _step_obj, something, value)

                    if found_key is not Null and len(found_key):
                        found_key = found_key[0] if len(
                            found_key) == 1 else found_key

                        if isinstance(found_key, dict):
                            found_value.append(
                                jsonify(found_key.get(something, found_key)))

            if isinstance(found_value,
                          dict) and 'constant_value' in found_value:
                found_value = found_value['constant_value']

            if found_value is not Null and found_value != [] and found_value != '' and found_value != {}:
                prop_list.append({
                    'address': resource['address'],
                    'values': found_value,
                    'type': _step_obj.context.name
                })

            elif 'must' in _step_obj.context_sensitive_sentence:
                Error(
                    _step_obj, '{} ({}) does not have {} property.'.format(
                        resource['address'], resource.get('type', ''),
                        something))

        if prop_list:
            _step_obj.context.stash = prop_list
            _step_obj.context.property_name = something
            return something, prop_list

        if _step_obj.state != Step.State.FAILED:
            skip_step(
                _step_obj,
                resource=_step_obj.context.name,
                message='Can not find any {} property for {} resource in '
                'terraform plan.'.format(something, _step_obj.context.name))

    elif _step_obj.context.type == 'provider':
        for provider_data in _step_obj.context.stash:
            values = seek_key_in_dict(provider_data, something)

            if values:
                _step_obj.context.stash = values
                _step_obj.context.property_name = something
                _step_obj.context.address = '{}.{}'.format(
                    provider_data.get('name', _step_obj.context.addresses),
                    provider_data.get('alias', "\b"))
                return True
            elif 'must' in _step_obj.context_sensitive_sentence:
                Error(
                    _step_obj, '{} {} does not have {} property.'.format(
                        _step_obj.context.addresses, _step_obj.context.type,
                        something))
        if 'must' in _step_obj.context_sensitive_sentence:
            Error(
                _step_obj, '{} {} does not have {} property.'.format(
                    _step_obj.context.addresses, _step_obj.context.type,
                    something))
    if _step_obj.state != Step.State.FAILED:
        skip_step(
            _step_obj,
            resource=_step_obj.context.name,
            message='Skipping the step since {} type does not have {} property.'
            .format(_step_obj.context.type, something))
示例#15
0
def i_have_name_section_configured(_step_obj, name, type_name='resource', _terraform_config=world):
    '''
    Finds given resource or variable by name and returns it. Skips the step (and further steps) if it is not found.

    :param _step_obj: Internal, step object for radish.
    :param name: String of the name of the resource_type or variable.
    :param type_name: String of the type, either resource(s) or variable(s)
    :param _terraform_config: Internal, terraform configuration.
    :return:
    '''
    assert (type_name in ['resource', 'resources',
                          'variable', 'variables',
                          'provider', 'providers',
                          'data', 'datas']), \
        '{} configuration type does not exist or not implemented yet. ' \
        'Use resource(s), provider(s), variable(s) or data(s) instead.'.format(type_name)

    if type_name.endswith('s'):
        type_name = type_name[:-1]

    if name in ('a resource', 'any resource', 'a', 'any', 'anything'):
        _step_obj.context.type = type_name
        _step_obj.context.name = name
        _step_obj.context.stash = [obj for key, obj in _terraform_config.config.terraform.resources_raw.items()]
        _step_obj.context.addresses = get_resource_address_list_from_stash(_step_obj.context.stash)
        return True

    elif name == 'resource that supports tags':
        resource_types_supports_tags = find_root_by_key(_terraform_config.config.terraform.resources_raw,
                                                        'tags',
                                                        return_key='type')
        resource_list = []
        for resource_type in resource_types_supports_tags:
            # Issue-168: Mounted resources causes problem on recursive searching for resources that supports tags
            #            We are removing all mounted resources here for future steps, since we don't need them for
            #            tags checking.
            found_resources = remove_mounted_resources(_terraform_config.config.terraform.find_resources_by_type(resource_type))
            resource_list.extend(found_resources)

        if resource_list:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = resource_list
            _step_obj.context.addresses = get_resource_address_list_from_stash(resource_list)
            return True

    elif type_name == 'resource':
        name = convert_resource_type(name)
        resource_list = _terraform_config.config.terraform.find_resources_by_type(name)

        if resource_list:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = resource_list
            _step_obj.context.addresses = get_resource_address_list_from_stash(resource_list)
            return True

    elif type_name == 'variable':
        found_variable = _terraform_config.config.terraform.variables.get(name, None)

        if found_variable:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = found_variable
            _step_obj.context.addresses = name
            return True

    elif type_name == 'provider':
        found_provider = _terraform_config.config.terraform.get_providers_from_configuration(name)

        if found_provider:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = found_provider
            _step_obj.context.addresses = name
            return True

    elif type_name == 'data':
        name = convert_resource_type(name)
        data_list = _terraform_config.config.terraform.find_data_by_type(name)

        if data_list:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = data_list
            _step_obj.context.addresses = name
            return True

    skip_step(_step_obj, name)
def its_key_is_value(_step_obj, key, value, dict_value=None, address=Null):
    def to_lower_key(d):
        return {str(k).lower(): v for k, v in d.items()}

    orig_key = key
    if key == 'reference':
        if address is not Null:
            key = Defaults.r_mount_addr_ptr
        elif address is Null:
            key = Defaults.r_mount_addr_ptr_list
    else:
        key = str(key).lower()

    found_list = []
    for obj in _step_obj.context.stash:
        obj = to_lower_key(obj)
        object_key = obj.get('values', {})
        if isinstance(object_key, list):
            for el in object_key:
                if isinstance(el, dict):
                    el = to_lower_key(el)
                    filtered_key = el.get(key)
                    if isinstance(filtered_key, (str, int, bool)) and str(filtered_key).lower() == str(value).lower():
                        found_list.append(el)
        else:
            object_key = to_lower_key(object_key)
            object_key = object_key.get(key, Null)

        if object_key is Null:
            object_key = obj.get(key, Null)
            if address is not Null and isinstance(object_key, dict) and address in object_key:
                object_key = object_key.get(address, Null)

        if isinstance(object_key, str):
            if "[" in object_key:
                object_key = object_key.split('[')[0]

            if object_key.lower() == value.lower():
                found_list.append(obj)

        elif isinstance(object_key, (int, bool)) and str(object_key).lower() == str(value).lower():
            found_list.append(obj)

        elif isinstance(object_key, list):
            object_key = [str(v).lower() for v in object_key]
            if str(value).lower() in object_key:
                found_list.append(obj)

        elif isinstance(object_key, dict):
            object_key = to_lower_key(object_key)
            candidate_value = object_key.get(str(value).lower())
            if candidate_value is not None and (
                    dict_value is None or (
                    str(candidate_value).lower() == str(dict_value).lower())
            ):
                found_list.append(obj)

    if found_list != []:
        _step_obj.context.stash = found_list
        _step_obj.context.addresses = get_resource_address_list_from_stash(found_list)
    else:
        if dict_value is None:
            skip_step(_step_obj, message='Can not find {} {} in {}.'.format(value, orig_key,
                                                                            ', '.join(_step_obj.context.addresses)))
        else:
            skip_step(_step_obj, message='Can not find {}={} {} in {}.'.format(value, dict_value, orig_key,
                                                                               ', '.join(_step_obj.context.addresses)))
def it_does_not_have_something(_step_obj, something, inherited_values=Null):
    match = _step_obj.context.match
    seek_key_in_dict = match.seek_key_in_dict
    seek_regex_key_in_dict_values = match.seek_regex_key_in_dict_values

    prop_list = []

    _step_obj.context.stash = inherited_values if inherited_values is not Null else _step_obj.context.stash

    if _step_obj.context.type in ('resource', 'data'):
        for resource in _step_obj.context.stash:
            if not isinstance(resource, dict) \
                    or 'values' not in resource \
                    or 'address' not in resource \
                    or 'type' not in resource:
                resource = {
                    'values': resource,
                    'address': resource,
                    'type': _step_obj.context.name
                }

            values = resource.get('values', resource.get('expressions', {}))
            if not values:
                values = seek_key_in_dict(resource, something)

            found_value = Null
            found_key = Null
            if isinstance(values, dict):
                found_key = match.get(values, something,
                                      seek_key_in_dict(values, something))
                if not isinstance(found_key, list):
                    found_key = [{something: found_key}]

                if len(found_key):
                    found_key = found_key[0] if len(
                        found_key) == 1 and match.contains(
                            found_key[0], something) else found_key

                    if isinstance(found_key, dict):
                        found_value = match.get(found_key, something,
                                                found_key)
                    else:
                        found_value = found_key
            elif isinstance(values, list):
                found_value = []

                for value in values:

                    if isinstance(value, dict):
                        # First search in the keys
                        found_key = seek_key_in_dict(value, something)

                        # Then search in the values with 'key'
                        if not found_key:
                            found_key = seek_regex_key_in_dict_values(
                                value, 'key', something)

                            if found_key:
                                found_key = found_key[0]
                                found_value = value.get('value')
                                break
                    elif isinstance(value, list):
                        found_key, found_value = it_has_something(
                            _step_obj, something, value)

                    if found_key is not Null and len(found_key):
                        found_key = found_key[0] if len(
                            found_key) == 1 else found_key

                        if isinstance(found_key, dict):
                            found_value.append(
                                match.get(found_key, something, found_key))

            if isinstance(found_value,
                          dict) and 'constant_value' in found_value:
                found_value = found_value['constant_value']

            if found_value is not Null and found_value != [] and found_value != '' and found_value != {}:
                prop_list.append(resource['address'])

        prop_list = [
            resource for resource in _step_obj.context.stash
            if resource['address'] not in prop_list
        ]
        _step_obj.context.property_name = something

        if prop_list:
            _step_obj.context.stash = prop_list
            return something, prop_list

        if _step_obj.state != Step.State.FAILED:
            skip_step(
                _step_obj,
                resource=_step_obj.context.name,
                message='All objects ({}) coming from previous step has {} '
                'property.'.format(_step_obj.context.name, something))

    elif _step_obj.context.type == 'provider':
        stash = []
        for provider_data in _step_obj.context.stash:
            values = seek_key_in_dict(provider_data, something)

            if values:
                return False
            else:
                stash.append(provider_data)

        if stash:
            _step_obj.context.stash = stash
            _step_obj.context.property_name = something
            return True

    return True
示例#18
0
def its_key_is_value(_step_obj, key, value, dict_value=None, address=Null):
    match = _step_obj.context.match

    orig_key = key
    if key == 'reference':
        if address is not Null:
            key = Defaults.r_mount_addr_ptr
        elif address is Null:
            key = Defaults.r_mount_addr_ptr_list

    found_list = []
    for obj in _step_obj.context.stash:
        object_key = obj.get('values', {})
        if isinstance(object_key, list):
            for el in object_key:
                if isinstance(el, dict):
                    filtered_key = match.get(el, key)
                    if isinstance(filtered_key,
                                  (str, int, bool)) and match.equals(
                                      filtered_key, value):
                        found_list.append(el)
        else:
            object_key = match.get(object_key, key, Null)

        if object_key is Null:
            object_key = match.get(obj, key, Null)
            if address is not Null and isinstance(
                    object_key, dict) and match.contains(object_key, address):
                object_key = match.get(object_key, address, Null)

        if isinstance(object_key, str):
            if "[" in object_key:
                object_key = object_key.split('[')[0]

            if match.equals(object_key, value):
                found_list.append(obj)

        elif isinstance(object_key,
                        (int, bool)) and match.equals(object_key, value):
            found_list.append(obj)

        elif isinstance(object_key, list):
            object_key = [str(v) for v in object_key]
            if match.contains(object_key, value):
                found_list.append(obj)

        elif isinstance(object_key, dict):
            candidate_value = match.get(object_key, value)
            if candidate_value is not None and (
                    dict_value is None or
                (match.equals(candidate_value, dict_value))):
                found_list.append(obj)

    if found_list != []:
        _step_obj.context.stash = found_list
        _step_obj.context.addresses = get_resource_address_list_from_stash(
            found_list)
    else:
        if object_key is Null:
            skip_step(_step_obj,
                      message='Could not find {} in {}.'.format(
                          key, ', '.join(_step_obj.context.addresses)))
        elif dict_value is None:
            skip_step(_step_obj,
                      message='Can not find {} {} in {}.'.format(
                          value, orig_key,
                          ', '.join(_step_obj.context.addresses)))
        else:
            skip_step(_step_obj,
                      message='Can not find {}={} {} in {}.'.format(
                          value, dict_value, orig_key,
                          ', '.join(_step_obj.context.addresses)))
示例#19
0
def it_condition_contain_something(_step_obj, something):
    prop_list = []

    if _step_obj.context.type in ('resource', 'data'):
        for resource in _step_obj.context.stash:
            if type(resource) is not dict:
                resource = {
                    'values': resource,
                    'address': resource,
                    'type': _step_obj.context.name
                }

            values = resource.get('values', resource.get('expressions', {}))

            found_value = Null
            found_key = Null
            if type(values) is dict:
                found_key = values.get(something,
                                       seek_key_in_dict(values, something))
                if type(found_key) is not list:
                    found_key = [{something: found_key}]

                if len(found_key):
                    found_key = found_key[0] if len(
                        found_key) == 1 else found_key

                    if type(found_key) is dict:
                        found_value = jsonify(
                            found_key.get(something, found_key))
                    else:
                        found_value = found_key
            elif type(values) is list:
                found_value = []

                for value in values:

                    if type(value) is dict:
                        # First search in the keys
                        found_key = seek_key_in_dict(value, something)

                        # Then search in the values with 'key'
                        if not found_key:
                            found_key = seek_regex_key_in_dict_values(
                                value, 'key', something)

                            if found_key:
                                found_key = found_key[0]
                                found_value = value.get('value')
                                break

                    if found_key is not Null and len(found_key):
                        found_key = found_key[0] if len(
                            found_key) == 1 else found_key

                        if type(found_key) is dict:
                            found_value.append(
                                jsonify(found_key.get(something, found_key)))

            if type(found_value) is dict and 'constant_value' in found_value:
                found_value = found_value['constant_value']

            if found_value is not Null and found_value != [] and found_value != '' and found_value != {}:
                prop_list.append({
                    'address': resource['address'],
                    'values': found_value,
                    'type': _step_obj.context.name
                })

            elif 'must' in _step_obj.context_sensitive_sentence:
                raise Failure('{} ({}) does not have {} property.'.format(
                    resource['address'], resource.get('type', ''), something))

        if prop_list:
            _step_obj.context.stash = prop_list
            _step_obj.context.property_name = something
            return True

        skip_step(_step_obj,
                  resource=_step_obj.context.name,
                  message='Can not find any {} property for {} resource in '
                  'terraform plan.'.format(something, _step_obj.context.name))

    elif _step_obj.context.type == 'provider':
        values = seek_key_in_dict(_step_obj.context.stash, something)

        if values:
            _step_obj.context.stash = values
            _step_obj.context.property_name = something
            return True

    skip_step(
        _step_obj,
        resource=_step_obj.context.name,
        message='Skipping the step since {} type does not have {} property.'.
        format(_step_obj.context.type, something))
示例#20
0
def it_has_something(_step_obj, something, inherited_values=Null):
    match = _step_obj.context.match
    seek_key_in_dict = match.seek_key_in_dict
    seek_regex_key_in_dict_values = match.seek_regex_key_in_dict_values

    prop_list = []

    _step_obj.context.stash = inherited_values if inherited_values is not Null else _step_obj.context.stash

    if _step_obj.context.type in ('resource', 'data'):
        for resource in _step_obj.context.stash:
            if not isinstance(resource, dict) \
                    or 'values' not in resource \
                    or 'address' not in resource \
                    or 'type' not in resource:
                resource = {
                    'values': resource,
                    'address': resource,
                    'type': _step_obj.context.name
                }

            values = resource.get('values', resource.get('expressions', {}))
            if not values:
                values = seek_key_in_dict(resource, something)

            found_value = Null
            found_key = Null
            if isinstance(values, dict):
                found_key = match.get(values, something, Null)
                if found_key is not Null:
                    found_key = [{something: found_key}]
                else:
                    found_key = seek_key_in_dict(values, something)

                if len(found_key):
                    found_key = found_key[0] if len(
                        found_key) == 1 and match.contains(
                            found_key[0], something) else found_key

                    if isinstance(found_key, dict):
                        found_value = match.get(found_key, something,
                                                found_key)
                    else:
                        found_value = found_key
            elif isinstance(values, list):
                found_value = []

                for value in values:

                    if isinstance(value, dict):
                        # First search in the keys
                        found_key = seek_key_in_dict(value, something)

                        # Then search in the values with 'key'
                        if not found_key:
                            found_key = seek_regex_key_in_dict_values(
                                value, 'key', something)

                            if found_key:
                                found_key = found_key[0]
                                found_value = value.get('value')
                                break
                    elif isinstance(value, list):
                        found_key, found_value = it_has_something(
                            _step_obj, something, value)
                    elif isinstance(value,
                                    (str, bool, int, float)) and match.equals(
                                        value, something):
                        found_key = value
                        found_value.append(found_key)

                    if found_key is not Null and len(found_key):
                        found_key = found_key[0] if len(
                            found_key) == 1 else found_key

                        if isinstance(found_key, dict):
                            found_value.append(
                                match.get(found_key, something, found_key))

            if isinstance(found_value,
                          dict) and 'constant_value' in found_value:
                found_value = found_value['constant_value']

            if found_value not in (Null, [], '', {}):
                prop_list.append(resource)

        if prop_list:
            _step_obj.context.stash = prop_list
            _step_obj.context.property_name = something

            return something, prop_list

        if _step_obj.state != Step.State.FAILED:
            skip_step(
                _step_obj,
                resource=_step_obj.context.name,
                message='Can not find any {} property for {} resource in '
                'terraform plan.'.format(something, _step_obj.context.name))

    elif _step_obj.context.type == 'provider':
        _step_obj.context.stash = []
        for provider_data in _step_obj.context.stash:
            values = seek_key_in_dict(provider_data, something)

            if values:
                _step_obj.context.stash.append(provider_data)
                _step_obj.context.property_name = something
                _step_obj.context.address = '{}.{}'.format(
                    provider_data.get('name', _step_obj.context.addresses),
                    provider_data.get('alias', "\b"))
                return True

    if _step_obj.state != Step.State.FAILED:
        skip_step(
            _step_obj,
            resource=_step_obj.context.name,
            message='Skipping the step since {} type does not have {} property.'
            .format(_step_obj.context.type, something))
示例#21
0
def it_condition_contain_something(_step_obj, something):
    prop_list = []

    if _step_obj.context.type == 'resource':
        for resource in _step_obj.context.stash:
            if type(resource) is not dict:
                resource = {
                    'values': resource,
                    'address': resource,
                    'type': _step_obj.context.name
                }

            values = resource.get('values', {})

            found_value = None
            found_key = None
            if type(values) is dict:
                found_key = seek_key_in_dict(values, something)
                if len(found_key):
                    found_key = found_key[0]

                    if type(found_key) is dict:
                        found_value = jsonify(found_key[something])
            elif type(values) is list:
                for value in values:

                    if type(value) is dict:
                        # First search in the keys
                        found_key = seek_key_in_dict(value, something)

                        # Then search in the values with 'key'
                        if not found_key:
                            found_key = seek_regex_key_in_dict_values(
                                value, 'key', something)

                            if found_key:
                                found_key = found_key[0]
                                found_value = value.get('value')
                                break
                    else:
                        raise TerraformComplianceInternalFailure(
                            'Unexpected value type {}. {}'.format(
                                type(value), value))

            if found_key:
                prop_list.append({
                    'address': resource['address'],
                    'values': found_value,
                    'type': _step_obj.context.name
                })

            elif 'must' in _step_obj.context_sensitive_sentence:
                raise Failure('{} ({}) does not have {} property.'.format(
                    resource['address'], resource.get('type', ''), something))

        if prop_list:
            _step_obj.context.stash = prop_list
            _step_obj.context.property_name = something
            return True

        skip_step(_step_obj,
                  resource=_step_obj.context.name,
                  message='Can not find any {} property for {} resource in '
                  'terraform plan.'.format(something, _step_obj.context.name))

    elif _step_obj.context.type == 'provider':
        values = seek_key_in_dict(_step_obj.context.stash, something)

        if values:
            _step_obj.context.stash = values
            _step_obj.context.property_name = something
            return True

    skip_step(
        _step_obj,
        resource=_step_obj.context.name,
        message='Skipping the step since {} type does not have {} property.'.
        format(_step_obj.context.type, something))
示例#22
0
def its_key_is_not_value(_step_obj, key, value, dict_value=None, address=Null):
    match = _step_obj.context.match

    orig_key = key
    if key == 'reference':
        if address is not Null:
            key = Defaults.r_mount_addr_ptr
        elif address is Null:
            key = Defaults.r_mount_addr_ptr_list

    found_list = []
    for obj in _step_obj.context.stash:
        object_key = obj.get(key, Null)

        if object_key is Null:
            object_key = obj.get('values', {})
            if isinstance(object_key, list):
                object_keys = []
                for object_key_element in object_key:
                    if not match.equals(
                            match.get(object_key_element, key, Null), value):
                        object_keys.append(
                            match.get(object_key_element, key, Null))

                object_key = [keys for keys in object_keys if keys is not Null]
            else:
                object_key = match.get(object_key, key, Null)

        if address is not Null and isinstance(
                object_key, dict) and match.contains(object_key, address):
            object_key = match.get(object_key, address, Null)

        if isinstance(object_key, str):
            if "[" in object_key:
                object_key = object_key.split('[')[0]

            if not match.equals(object_key, value):
                found_list.append(obj)

        elif isinstance(object_key,
                        (int, bool)) and not match.equals(object_key, value):
            found_list.append(obj)

        elif isinstance(object_key,
                        list) and not match.contains(object_key, value):
            found_list.append(obj)

        elif isinstance(object_key, dict):
            if not match.contains(object_key, value) or (
                    dict_value is not None and not match.equals(
                        str(match.get(object_key, value)), dict_value)):
                found_list.append(obj)

        elif object_key is None and not match.equals('None', value):
            found_list.append(obj)

    if found_list != []:
        _step_obj.context.stash = found_list
        _step_obj.context.addresses = get_resource_address_list_from_stash(
            found_list)
    else:
        if object_key is Null:
            skip_step(_step_obj,
                      message='Could not find {} in {}.'.format(
                          key, ', '.join(_step_obj.context.addresses)))
        elif dict_value is None:
            skip_step(_step_obj,
                      message='Found {} {} in {}.'.format(
                          value, orig_key,
                          ', '.join(_step_obj.context.addresses)))
        else:
            skip_step(_step_obj,
                      message='Found {}={} {} in {}.'.format(
                          value, dict_value, orig_key,
                          ', '.join(_step_obj.context.addresses)))
示例#23
0
def i_have_name_section_configured(_step_obj,
                                   name,
                                   type_name='resource',
                                   _terraform_config=world):
    '''
    Finds given resource or variable by name and returns it. Skips the step (and further steps) if it is not found.

    :param _step_obj: Internal, step object for radish.
    :param name: String of the name of the resource_type or variable.
    :param type_name: String of the type, either resource(s) or variable(s)
    :param _terraform_config: Internal, terraform configuration.
    :return:
    '''
    assert (type_name in ['resource', 'resources',
                          'variable', 'variables',
                          'provider', 'providers',
                          'data', 'datas']), \
        '{} configuration type does not exist or not implemented yet. ' \
        'Use resource(s), provider(s), variable(s) or data(s) instead.'.format(type_name)

    if type_name.endswith('s'):
        type_name = type_name[:-1]

    if name == 'resource that supports tags':
        resource_types_supports_tags = find_root_by_key(
            _terraform_config.config.terraform.resources_raw,
            'tags',
            return_key='type')
        resource_list = []
        for resource_type in resource_types_supports_tags:
            resource_list.extend(
                _terraform_config.config.terraform.find_resources_by_type(
                    resource_type))

        if resource_list:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = resource_list
            return True

    elif type_name == 'resource':
        name = convert_resource_type(name)
        resource_list = _terraform_config.config.terraform.find_resources_by_type(
            name)

        if resource_list:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = resource_list
            return True

    elif type_name == 'variable':
        found_variable = _terraform_config.config.terraform.variables.get(
            name, None)

        if found_variable:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = found_variable
            return True

    elif type_name == 'provider':
        found_provider = _terraform_config.config.terraform.configuration.get(
            'providers', {}).get(name, None)

        if found_provider:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = found_provider
            return True

    elif type_name == 'data':
        name = convert_resource_type(name)
        data_list = _terraform_config.config.terraform.find_data_by_type(name)

        if data_list:
            _step_obj.context.type = type_name
            _step_obj.context.name = name
            _step_obj.context.stash = data_list
            return True

    skip_step(_step_obj, name)
def it_contains_something_old(_step_obj, something, inherited_values=Null):
    console_write("\t{} {}: {}".format(
        Defaults().warning_icon,
        Defaults().warning_colour('WARNING'),
        Defaults().info_colour(
            '"When it contains {}" step functionality will be changed'
            ' on future versions and the functionality will be same '
            'as "When it has {}" step. Please use the '
            'latter.'.format(something, something))))
    match = _step_obj.context.match
    seek_key_in_dict = match.seek_key_in_dict
    seek_regex_key_in_dict_values = match.seek_regex_key_in_dict_values

    prop_list = []

    _step_obj.context.stash = inherited_values if inherited_values is not Null else _step_obj.context.stash

    if _step_obj.context.type in ('resource', 'data'):
        for resource in _step_obj.context.stash:
            if not isinstance(resource, dict) \
                    or 'values' not in resource \
                    or 'address' not in resource \
                    or 'type' not in resource:
                resource = {
                    'values': resource,
                    'address': resource,
                    'type': _step_obj.context.name
                }

            values = resource.get('values', resource.get('expressions', {}))
            if not values:
                values = seek_key_in_dict(resource, something)

            found_value = Null
            found_key = Null
            if isinstance(values, dict):
                found_key = match.get(values, something,
                                      seek_key_in_dict(values, something))
                if not isinstance(found_key, list):
                    found_key = [{something: found_key}]

                if len(found_key):
                    found_key = found_key[0] if len(
                        found_key) == 1 and match.contains(
                            found_key[0], something) else found_key

                    if isinstance(found_key, dict):
                        found_value = match.get(found_key, something,
                                                found_key)
                    else:
                        found_value = found_key
            elif isinstance(values, list):
                found_value = []

                for value in values:

                    if isinstance(value, dict):
                        # First search in the keys
                        found_key = seek_key_in_dict(value, something)

                        # Then search in the values with 'key'
                        if not found_key:
                            found_key = seek_regex_key_in_dict_values(
                                value, 'key', something)

                            if found_key:
                                found_key = found_key[0]
                                found_value = value.get('value')
                                break
                    elif isinstance(value, list):
                        found_key, found_value = it_contains_something_old(
                            _step_obj, something, value)

                    if found_key is not Null and len(found_key):
                        found_key = found_key[0] if len(
                            found_key) == 1 else found_key

                        if isinstance(found_key, dict):
                            found_value.append(
                                match.get(found_key, something, found_key))

            if isinstance(found_value,
                          dict) and 'constant_value' in found_value:
                found_value = found_value['constant_value']

            if found_value is not Null and found_value != [] and found_value != '' and found_value != {}:
                prop_list.append({
                    'address': resource['address'],
                    'values': found_value,
                    'type': _step_obj.context.name
                })

        if prop_list:
            _step_obj.context.stash = prop_list
            _step_obj.context.property_name = something

            return something, prop_list

        if _step_obj.state != Step.State.FAILED:
            skip_step(
                _step_obj,
                resource=_step_obj.context.name,
                message='Can not find any {} property for {} resource in '
                'terraform plan.'.format(something, _step_obj.context.name))

    elif _step_obj.context.type == 'provider':
        for provider_data in _step_obj.context.stash:
            values = seek_key_in_dict(provider_data, something)

            if values:
                _step_obj.context.stash = values
                _step_obj.context.property_name = something
                _step_obj.context.address = '{}.{}'.format(
                    provider_data.get('name', _step_obj.context.addresses),
                    provider_data.get('alias', "\b"))
                return True

    if _step_obj.state != Step.State.FAILED:
        skip_step(
            _step_obj,
            resource=_step_obj.context.name,
            message='Skipping the step since {} type does not have {} property.'
            .format(_step_obj.context.type, something))