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)))
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)))
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))
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)
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)
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)
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)
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)
def test_skip_step(self, *args): step = MockedStep() skip_step(step) self.assertEqual(step.state, 'skipped')
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)
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)
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))
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
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)))
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))
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))
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))
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)))
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))