-module(caffeine_lang@codegen@datadog). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/caffeine_lang/codegen/datadog.gleam"). -export([terraform_settings/0, provider/0, variables/0, window_to_timeframe/1, ir_to_terraform_resource/1, generate_resources/1, generate_terraform/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -file("src/caffeine_lang/codegen/datadog.gleam", 59). ?DOC(false). -spec terraform_settings() -> terra_madre@terraform:terraform_settings(). terraform_settings() -> caffeine_lang@codegen@generator_utils:build_terraform_settings( <<"datadog"/utf8>>, <<"DataDog/datadog"/utf8>>, <<"~> 3.0"/utf8>> ). -file("src/caffeine_lang/codegen/datadog.gleam", 69). ?DOC(false). -spec provider() -> terra_madre@terraform:provider(). provider() -> caffeine_lang@codegen@generator_utils:build_provider( <<"datadog"/utf8>>, [{<<"api_key"/utf8>>, terra_madre@hcl:ref(<<"var.datadog_api_key"/utf8>>)}, {<<"app_key"/utf8>>, terra_madre@hcl:ref(<<"var.datadog_app_key"/utf8>>)}] ). -file("src/caffeine_lang/codegen/datadog.gleam", 78). ?DOC(false). -spec variables() -> list(terra_madre@terraform:variable()). variables() -> [{variable, <<"datadog_api_key"/utf8>>, {some, {identifier, <<"string"/utf8>>}}, none, {some, <<"Datadog API key"/utf8>>}, {some, true}, none, []}, {variable, <<"datadog_app_key"/utf8>>, {some, {identifier, <<"string"/utf8>>}}, none, {some, <<"Datadog Application key"/utf8>>}, {some, true}, none, []}]. -file("src/caffeine_lang/codegen/datadog.gleam", 240). ?DOC( " Build dependency relation tag pairs from the relations dict.\n" " Generates pairs like #(\"soft_dependency\", \"target1,target2\").\n" ). -spec build_dependency_tags( gleam@dict:dict(caffeine_lang@linker@artifacts:dependency_relation_type(), list(binary())) ) -> list({binary(), binary()}). build_dependency_tags(Relations) -> _pipe = Relations, _pipe@1 = maps:to_list(_pipe), _pipe@2 = gleam@list:sort( _pipe@1, fun(A, B) -> gleam@string:compare( caffeine_lang@linker@artifacts:relation_type_to_string( erlang:element(1, A) ), caffeine_lang@linker@artifacts:relation_type_to_string( erlang:element(1, B) ) ) end ), gleam@list:map( _pipe@2, fun(Pair) -> {Relation_type, Targets} = Pair, Sorted_targets = begin _pipe@3 = Targets, gleam@list:sort(_pipe@3, fun gleam@string:compare/2) end, {<<(caffeine_lang@linker@artifacts:relation_type_to_string( Relation_type ))/binary, "_dependency"/utf8>>, gleam@string:join(Sorted_targets, <<","/utf8>>)} end ). -file("src/caffeine_lang/codegen/datadog.gleam", 264). ?DOC(false). -spec window_to_timeframe(integer()) -> {ok, binary()} | {error, caffeine_lang@errors:compilation_error()}. window_to_timeframe(Days) -> Days_string = erlang:integer_to_binary(Days), case Days of 7 -> {ok, <>}; 30 -> {ok, <>}; 90 -> {ok, <>}; _ -> {error, caffeine_lang@codegen@generator_utils:resolution_error( <<"datadog"/utf8>>, <<<<"Illegal window_in_days value: "/utf8, Days_string/binary>>/binary, ". Accepted values are 7, 30, or 90."/utf8>> )} end. -file("src/caffeine_lang/codegen/datadog.gleam", 104). ?DOC(false). -spec ir_to_terraform_resource( caffeine_lang@linker@ir:intermediate_representation(caffeine_lang@linker@ir:resolved()) ) -> {ok, {terra_madre@terraform:resource(), list(binary())}} | {error, caffeine_lang@errors:compilation_error()}. ir_to_terraform_resource(Ir) -> Resource_name = terra_madre@common:sanitize_terraform_identifier( erlang:element(3, Ir) ), gleam@result:'try'( caffeine_lang@codegen@generator_utils:require_slo_fields( Ir, <<"datadog"/utf8>> ), fun(Slo) -> Threshold = erlang:element(2, Slo), Window_in_days = erlang:element(4, Slo), Indicators = erlang:element(3, Slo), Evaluation_expr = begin _pipe = erlang:element(5, Slo), gleam@option:unwrap(_pipe, <<"numerator / denominator"/utf8>>) end, Runbook = erlang:element(7, Slo), gleam@result:'try'( begin _pipe@1 = caffeine_query_language@generator:resolve_slo_to_hcl( Evaluation_expr, Indicators ), gleam@result:map_error( _pipe@1, fun(Err) -> caffeine_lang@errors:generator_slo_query_resolution_error( <<<<<<"expectation '"/utf8, (caffeine_lang@linker@ir:ir_to_identifier( Ir ))/binary>>/binary, "' - failed to resolve SLO query: "/utf8>>/binary, Err/binary>> ) end ) end, fun(_use0) -> {resolved_slo_hcl, Slo_type, Slo_blocks} = _use0, Dependency_tags = case caffeine_lang@linker@ir:get_dependency_fields( erlang:element(6, Ir) ) of {some, Dep} -> build_dependency_tags(erlang:element(2, Dep)); none -> [] end, User_tag_pairs = erlang:element(6, Slo), System_tag_pairs = begin _pipe@2 = caffeine_lang@helpers:build_system_tag_pairs( erlang:element(3, erlang:element(2, Ir)), erlang:element(6, erlang:element(2, Ir)), erlang:element(4, erlang:element(2, Ir)), erlang:element(5, erlang:element(2, Ir)), erlang:element(2, erlang:element(2, Ir)), erlang:element(4, Ir), erlang:element(7, erlang:element(2, Ir)) ), lists:append(_pipe@2, Dependency_tags) end, System_tag_keys = begin _pipe@3 = System_tag_pairs, _pipe@4 = gleam@list:map( _pipe@3, fun(Pair) -> erlang:element(1, Pair) end ), gleam@set:from_list(_pipe@4) end, User_tag_keys = begin _pipe@5 = User_tag_pairs, _pipe@6 = gleam@list:map( _pipe@5, fun(Pair@1) -> erlang:element(1, Pair@1) end ), gleam@set:from_list(_pipe@6) end, Overlapping_keys = gleam@set:intersection( System_tag_keys, User_tag_keys ), {Final_system_tag_pairs, Warnings} = case gleam@set:size( Overlapping_keys ) > 0 of true -> Warn_msgs = begin _pipe@7 = Overlapping_keys, _pipe@8 = gleam@set:to_list(_pipe@7), _pipe@9 = gleam@list:sort( _pipe@8, fun gleam@string:compare/2 ), gleam@list:map( _pipe@9, fun(Key) -> <<<<<<(caffeine_lang@linker@ir:ir_to_identifier( Ir ))/binary, " - user tag '"/utf8>>/binary, Key/binary>>/binary, "' overshadows system tag"/utf8>> end ) end, Filtered = begin _pipe@10 = System_tag_pairs, gleam@list:filter( _pipe@10, fun(Pair@2) -> not gleam@set:contains( Overlapping_keys, erlang:element(1, Pair@2) ) end ) end, {Filtered, Warn_msgs}; false -> {System_tag_pairs, []} end, Tags = begin _pipe@11 = lists:append( Final_system_tag_pairs, User_tag_pairs ), _pipe@12 = gleam@list:map( _pipe@11, fun(Pair@3) -> {string_literal, <<<<(erlang:element(1, Pair@3))/binary, ":"/utf8>>/binary, (erlang:element(2, Pair@3))/binary>>} end ), {list_expr, _pipe@12} end, Identifier = caffeine_lang@linker@ir:ir_to_identifier(Ir), gleam@result:'try'( begin _pipe@13 = window_to_timeframe(Window_in_days), gleam@result:map_error( _pipe@13, fun(Err@1) -> caffeine_lang@errors:prefix_error( Err@1, Identifier ) end ) end, fun(Window_in_days_string) -> Thresholds_block = terra_madre@hcl:simple_block( <<"thresholds"/utf8>>, [{<<"timeframe"/utf8>>, {string_literal, Window_in_days_string}}, {<<"target"/utf8>>, {float_literal, Threshold}}] ), Type_str = case Slo_type of time_slice_slo -> <<"time_slice"/utf8>>; metric_slo -> <<"metric"/utf8>> end, Base_attributes = [{<<"name"/utf8>>, {string_literal, erlang:element( 2, erlang:element( 2, erlang:element(2, Ir) ) )}}, {<<"type"/utf8>>, {string_literal, Type_str}}, {<<"tags"/utf8>>, Tags}], Attributes = case Runbook of {some, Url} -> [{<<"description"/utf8>>, {string_literal, <<<<"[Runbook]("/utf8, Url/binary>>/binary, ")"/utf8>>}} | Base_attributes]; none -> Base_attributes end, {ok, {{resource, <<"datadog_service_level_objective"/utf8>>, Resource_name, maps:from_list(Attributes), lists:append( Slo_blocks, [Thresholds_block] ), terra_madre@hcl:empty_meta(), none}, Warnings}} end ) end ) end ). -file("src/caffeine_lang/codegen/datadog.gleam", 45). ?DOC(false). -spec generate_resources( list(caffeine_lang@linker@ir:intermediate_representation(caffeine_lang@linker@ir:resolved())) ) -> {ok, {list(terra_madre@terraform:resource()), list(binary())}} | {error, caffeine_lang@errors:compilation_error()}. generate_resources(Irs) -> _pipe = Irs, _pipe@1 = gleam@list:try_fold( _pipe, {[], []}, fun(Acc, Ir) -> {Resources, Warnings} = Acc, gleam@result:'try'( ir_to_terraform_resource(Ir), fun(_use0) -> {Resource, Ir_warnings} = _use0, {ok, {[Resource | Resources], lists:append(Ir_warnings, Warnings)}} end ) end ), gleam@result:map( _pipe@1, fun(Pair) -> {lists:reverse(erlang:element(1, Pair)), lists:reverse(erlang:element(2, Pair))} end ). -file("src/caffeine_lang/codegen/datadog.gleam", 28). ?DOC( " Generate Terraform HCL from a list of Datadog IntermediateRepresentations.\n" " Includes provider configuration and variables.\n" " Note: Datadog does not use generator_utils.generate_terraform because it\n" " returns warnings alongside the HCL string.\n" ). -spec generate_terraform( list(caffeine_lang@linker@ir:intermediate_representation(caffeine_lang@linker@ir:resolved())) ) -> {ok, {binary(), list(binary())}} | {error, caffeine_lang@errors:compilation_error()}. generate_terraform(Irs) -> gleam@result:'try'( generate_resources(Irs), fun(_use0) -> {Resources, Warnings} = _use0, {ok, {caffeine_lang@codegen@generator_utils:render_terraform_config( Resources, terraform_settings(), [provider()], variables() ), Warnings}} end ).