diff --git a/balcony/custom_tf_import_configs/ec2.yaml b/balcony/custom_tf_import_configs/ec2.yaml index 3e41546..1d5dada 100644 --- a/balcony/custom_tf_import_configs/ec2.yaml +++ b/balcony/custom_tf_import_configs/ec2.yaml @@ -7,8 +7,6 @@ import_configurations: operation_name: DescribeInstances to_resource_type: aws_instance jmespath_query: "[].Reservations[].Instances[]" - to_resource_name_jinja2_template: | - {{ InstanceId }} - id_generator_jinja2_template: | - {{ InstanceId }} + to_resource_name_jinja2_template: "{{ name_tag or InstanceId }}" + id_generator_jinja2_template: "{{ InstanceId }}" \ No newline at end of file diff --git a/balcony/terraform_import/importer.py b/balcony/terraform_import/importer.py index 554af85..e957d03 100644 --- a/balcony/terraform_import/importer.py +++ b/balcony/terraform_import/importer.py @@ -1,6 +1,6 @@ import re import textwrap -from typing import List +from typing import List, Union import jmespath from terraform_import.parsers import parse_custom_tf_import_config from config import get_logger @@ -10,19 +10,39 @@ logger = get_logger(__name__) -def generate_import_id_list(data, id_generator_tpl): - template = Environment().from_string(id_generator_tpl) - rendered_output = template.render(data=data, **data).strip() - # import_id_list = [ro for ro in rendered_output.split("\n") if ro] - # return import_id_list - return rendered_output +def extract_name_tag(data: dict) -> Union[str, bool]]: + """_summary_ + Args: + data (dict): An AWS resource data -def generate_to_resource_name_list(data, resource_name_generator_tpl): - to_resource_node_template = Environment().from_string(resource_name_generator_tpl) - rendered_output = to_resource_node_template.render(data=data, **data).strip() - # to_resource_name_list = [ro for ro in rendered_output.split("\n") if ro] - # return to_resource_name_list + Returns: + _type_: _description_ + """ + tags = data.get("Tags", []) + if not tags: + return False + name_tag = list(filter(lambda tag: tag.get("Key") == "Name", tags)) + if name_tag and len(name_tag) >= 1: + found_tag = name_tag[0].get("Value", False) + return found_tag + return False + + +def render_jinja2_template_with_data(data, jinja2_template_str): + template = Environment().from_string(jinja2_template_str) + + kwargs = {"data": data} + # if the data is a dict, add the key-value pairs as kwargs + if isinstance(data, dict): + kwargs.update(data) + kwargs["data"] = data + # if there's a tag.Name, add it as name_tag variable + name_tag = extract_name_tag(data) + logger.debug(f"Found name tag: {name_tag}") + kwargs["name_tag"] = name_tag + + rendered_output = template.render(**kwargs).strip() return rendered_output @@ -36,19 +56,23 @@ def gen_resource_name_and_import_id_from_op_data_( list_of_resource_data = jmespath.search(jmespath_query, operation_data) logger.debug(f"Filtered data using jmespath query: {jmespath_query}") for a_resource_data in list_of_resource_data: - resource_name = generate_to_resource_name_list( + resource_name = render_jinja2_template_with_data( a_resource_data, to_resource_name_tpl ) - import_id = generate_import_id_list(a_resource_data, id_generator_tpl) + import_id = render_jinja2_template_with_data( + a_resource_data, id_generator_tpl + ) result.append((resource_name, import_id)) return result else: # no jmespath query given, use the whole operation data - resource_name_multiline = generate_to_resource_name_list( + resource_name_multiline = render_jinja2_template_with_data( a_resource_data, to_resource_name_tpl ) - import_id_multiline = generate_import_id_list(a_resource_data, id_generator_tpl) + import_id_multiline = render_jinja2_template_with_data( + a_resource_data, id_generator_tpl + ) # split them on newlines resource_name_list = [ro for ro in resource_name_multiline.split("\n") if ro] import_id_list = [ro for ro in import_id_multiline.split("\n") if ro] diff --git a/balcony/terraform_import/validators.py b/balcony/terraform_import/models.py similarity index 52% rename from balcony/terraform_import/validators.py rename to balcony/terraform_import/models.py index ef4c17e..97233b1 100644 --- a/balcony/terraform_import/validators.py +++ b/balcony/terraform_import/models.py @@ -1,7 +1,9 @@ from typing import List, Dict, Optional, Any from pydantic import BaseModel, validator - +from typing import Dict + + class TerraformImportConfig(BaseModel): service: str # ec2 resource_node: str # Instances @@ -11,15 +13,25 @@ class TerraformImportConfig(BaseModel): to_resource_name_jinja2_template: str # "{{ .InstanceId }}" id_generator_jinja2_template: str # "{{ .InstanceId }}" - # TODO: create validators + @validator('to_resource_name_jinja2_template') + def validate_to_resource_name_jinja2_template(cls, value): + # Add your validation logic here + # You can raise a ValueError if the value is invalid + return value + @validator('id_generator_jinja2_template') + def validate_id_generator_jinja2_template(cls, value): + # Add your validation logic here + # You can raise a ValueError if the value is invalid + return value class MaintainersBlock(BaseModel): + """List of maintainers for the terraform import config file.""" name: str github: Optional[str] email: Optional[str] class CustomTerraformImportConfigFile(BaseModel): - maintainers: Optional[MaintainersBlock] + maintainers: Optional[List[MaintainersBlock]] import_configurations: List[TerraformImportConfig] diff --git a/balcony/terraform_import/parsers.py b/balcony/terraform_import/parsers.py index b74b6cc..66f827d 100644 --- a/balcony/terraform_import/parsers.py +++ b/balcony/terraform_import/parsers.py @@ -5,7 +5,7 @@ USER_DEFINED_YAML_TF_IMPORT_CONFIGS_DIRECTORY, set_log_level_at_runtime, ) -from terraform_import.validators import ( +from terraform_import.models import ( CustomTerraformImportConfigFile, TerraformImportConfig, )