!
{% if interface is defined and interface is not none %}
{%   for iface, iface_config in interface.items() %}
interface {{ iface }} {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
{%     if iface_config.authentication is defined and iface_config.authentication is not none %}
{%       if iface_config.authentication.plaintext_password is defined and iface_config.authentication.plaintext_password is not none %}
 ip ospf authentication-key {{ iface_config.authentication.plaintext_password }}
{%       elif iface_config.authentication.md5 is defined %}
 ip ospf authentication message-digest
{%         if iface_config.authentication.md5.key_id is defined and iface_config.authentication.md5.key_id is not none %}
{%           for key, key_config in iface_config.authentication.md5.key_id.items() %}
 ip ospf message-digest-key {{ key }} md5 {{ key_config.md5_key }}
{%           endfor %}
{%         endif %}
{%       endif %}
{%     endif %}
{%     if iface_config.area is defined and iface_config.area is not none %}
 ip ospf area {{ iface_config.area }}
{%     endif %}
{%     if iface_config.bandwidth is defined and iface_config.bandwidth is not none %}
 bandwidth {{ iface_config.bandwidth }}
{%     endif %}
{%     if iface_config.cost is defined and iface_config.cost is not none %}
 ip ospf cost {{ iface_config.cost }}
{%     endif %}
{%     if iface_config.priority is defined and iface_config.priority is not none %}
 ip ospf priority {{ iface_config.priority }}
{%     endif %}
{%     if iface_config.hello_interval is defined and iface_config.hello_interval is not none %}
 ip ospf hello-interval {{ iface_config.hello_interval }}
{%     endif %}
{%     if iface_config.retransmit_interval is defined and iface_config.retransmit_interval is not none %}
 ip ospf retransmit-interval {{ iface_config.retransmit_interval }}
{%     endif %}
{%     if iface_config.transmit_delay is defined and iface_config.transmit_delay is not none %}
 ip ospf transmit-delay {{ iface_config.transmit_delay }}
{%     endif %}
{%     if iface_config.dead_interval is defined and iface_config.dead_interval is not none %}
 ip ospf dead-interval {{ iface_config.dead_interval }}
{%     elif iface_config.hello_multiplier is defined and iface_config.hello_multiplier is not none %}
 ip ospf dead-interval minimal hello-multiplier {{ iface_config.hello_multiplier }}
{%     endif %}
{%     if iface_config.bfd is defined %}
 ip ospf bfd
{%     endif %}
{%     if iface_config.mtu_ignore is defined %}
 ip ospf mtu-ignore
{%     endif %}
{%     if iface_config.network is defined and iface_config.network is not none %}
 ip ospf network {{ iface_config.network }}
{%     endif %}
!
{%   endfor %}
{% endif %}
!
router ospf {{ 'vrf ' + vrf if vrf is defined and vrf is not none }}
{% if access_list is defined and access_list is not none %}
{%   for acl, acl_config in access_list.items() %}
{%     for protocol in acl_config.export if acl_config.export is defined %}
 distribute-list {{ acl }} out {{ protocol }}
{%     endfor %}
{%   endfor %}
{% endif %}
{% if area is defined and area is not none %}
{%   for area_id, area_config in area.items() %}
{%     if area_config.area_type is defined and area_config.area_type is not none %}
{%       for type, type_config in area_config.area_type.items() if type != 'normal' %}
 area {{ area_id }} {{ type }} {{ 'no-summary' if type_config.no_summary is defined }}
{%         if type_config.default_cost is defined and type_config.default_cost is not none %}
 area {{ area_id }} default-cost {{ type_config.default_cost }}
{%         endif %}
{%       endfor %}
{%     endif %}
{%     if area_config.authentication is defined and area_config.authentication is not none %}
 area {{ area_id }} authentication {{ 'message-digest' if area_config.authentication == 'md5' }}
{%     endif %}
{%     for network in area_config.network if area_config.network is defined %}
 network {{ network }} area {{ area_id }}
{%     endfor %}
{%     if area_config.range is defined and area_config.range is not none %}
{%       for range, range_config in area_config.range.items() %}
{%         if range_config.cost is defined and range_config.cost is not none %}
 area {{ area_id }} range {{ range }} cost {{ range_config.cost }}
{%         endif %}
{%         if range_config.not_advertise is defined %}
 area {{ area_id }} range {{ range }} not-advertise
{%         endif %}
{%         if range_config.substitute is defined and range_config.substitute is not none %}
 area {{ area_id }} range {{ range }} substitute {{ range_config.substitute }}
{%         endif %}
{%       endfor %}
{%     endif %}
{%     if area_config.shortcut is defined and area_config.shortcut is not none %}
 area {{ area_id }} shortcut {{ area_config.shortcut }}
{%     endif %}
{%     if area_config.virtual_link is defined and area_config.virtual_link is not none %}
{%       for link, link_config in area_config.virtual_link.items() %}
{%         if link_config.authentication is defined and link_config.authentication is not none %}
{%           if link_config.authentication.plaintext_password is defined and link_config.authentication.plaintext_password is not none %}
 area {{ area_id }} virtual-link {{ link }} authentication-key {{ link_config.authentication.plaintext_password }}
{%           elif link_config.authentication.md5 is defined and link_config.authentication.md5.key_id is defined and link_config.authentication.md5.key_id is not none %}
{%             for key, key_config in link_config.authentication.md5.key_id.items() %}
 area {{ area_id }} virtual-link {{ link }} message-digest-key {{ key }} md5 {{ key_config.md5_key }}
{%             endfor %}
{%           endif %}
{%         endif %}
{#         The following values are default values #}
 area {{ area_id }} virtual-link {{ link }} hello-interval {{ link_config.hello_interval }} retransmit-interval {{ link_config.retransmit_interval }} transmit-delay {{ link_config.transmit_delay }} dead-interval {{ link_config.dead_interval }}
{%       endfor %}
{%     endif %}
{%   endfor %}
{% endif %}
{% if auto_cost is defined and auto_cost.reference_bandwidth is defined and auto_cost.reference_bandwidth is not none %}
 auto-cost reference-bandwidth {{ auto_cost.reference_bandwidth }}
{% endif %}
{% if default_information is defined and default_information.originate is defined and default_information.originate is not none %}
 default-information originate {{ 'always' if default_information.originate.always is defined }} {{ 'metric ' + default_information.originate.metric if default_information.originate.metric is defined }} {{ 'metric-type ' + default_information.originate.metric_type if default_information.originate.metric_type is defined }} {{ 'route-map ' + default_information.originate.route_map if default_information.originate.route_map is defined }}
{% endif %}
{% if default_metric is defined and default_metric is not none %}
 default-metric {{ default_metric }}
{% endif %}
{% if distance is defined and distance is not none %}
{%   if distance.global is defined and distance.global is not none %}
 distance {{ distance.global }}
{%   endif %}
{%   if distance.ospf is defined and distance.ospf is not none %}
 distance ospf {{ 'intra-area ' + distance.ospf.intra_area if distance.ospf.intra_area is defined }} {{ 'inter-area ' + distance.ospf.inter_area if distance.ospf.inter_area is defined }} {{ 'external ' + distance.ospf.external if distance.ospf.external is defined }}
{%   endif %}
{% endif %}
{% if log_adjacency_changes is defined %}
 log-adjacency-changes {{ "detail" if log_adjacency_changes.detail is defined }}
{% endif %}
{% if max_metric is defined and max_metric.router_lsa is defined and max_metric.router_lsa is not none %}
{%   if max_metric.router_lsa.administrative is defined %}
 max-metric router-lsa administrative
{%   endif %}
{%   if max_metric.router_lsa.on_shutdown is defined and max_metric.router_lsa.on_shutdown is not none %}
 max-metric router-lsa on-shutdown {{ max_metric.router_lsa.on_shutdown }}
{%   endif %}
{%   if max_metric.router_lsa.on_startup is defined and max_metric.router_lsa.on_startup is not none %}
 max-metric router-lsa on-startup {{ max_metric.router_lsa.on_startup }}
{%   endif %}
{% endif %}
{% if mpls_te is defined and mpls_te.enable is defined %}
 mpls-te on
 mpls-te router-address {{ mpls_te.router_address }}
{% endif %}
{% if neighbor is defined and neighbor is not none%}
{%   for address, address_config in neighbor.items() %}
 neighbor {{ address }} {{ 'priority ' + address_config.priority if address_config.priority is defined }} {{ 'poll-interval ' + address_config.poll_interval if address_config.poll_interval is defined }}
{%   endfor %}
{% endif %}
{% if parameters is defined and parameters is not none %}
{%   if parameters.abr_type is defined and parameters.abr_type is not none %}
 ospf abr-type {{ parameters.abr_type }}
{%   endif %}
{%   if parameters.router_id is defined and parameters.router_id is not none %}
 ospf router-id {{ parameters.router_id }}
{%   endif %}
{% endif %}
{% if passive_interface is defined and passive_interface is not none %}
{%   for interface in passive_interface %}
 passive-interface {{ interface }}
{%   endfor %}
{% endif %}
{% if passive_interface_exclude is defined and passive_interface_exclude is not none %}
{%   for interface in passive_interface_exclude if passive_interface_exclude is defined %}
{%     if interface.startswith('vlink') %}
{%     set interface = interface.upper() %}
{%     endif %}
 no passive-interface {{ interface }}
{%   endfor %}
{% endif %}
{% if redistribute is defined and redistribute is not none %}
{%   for protocol, protocols_options in redistribute.items() %}
{%     if protocol == 'table' %}
{%       for table, table_options in protocols_options.items() %}
 redistribute {{ protocol }} {{ table }} {{ 'metric ' + table_options.metric if table_options.metric is defined }} {{ 'metric-type ' + table_options.metric_type if table_options.metric_type is defined }} {{ 'route-map ' + table_options.route_map if table_options.route_map is defined }}
{%       endfor %}
{%     else %}
 redistribute {{ protocol }} {{ 'metric ' + protocols_options.metric if protocols_options.metric is defined }} {{ 'metric-type ' + protocols_options.metric_type if protocols_options.metric_type is defined }} {{ 'route-map ' + protocols_options.route_map if protocols_options.route_map is defined }}
{%     endif %}
{%   endfor %}
{% endif %}
{% if refresh is defined and refresh.timers is defined and refresh.timers is not none %}
 refresh timer {{ refresh.timers }}
{% endif %}
{% if timers is defined and timers.throttle is defined and timers.throttle.spf is defined and timers.throttle.spf is not none %}
{#   Timer values have default values #}
 timers throttle spf {{ timers.throttle.spf.delay }} {{ timers.throttle.spf.initial_holdtime }} {{ timers.throttle.spf.max_holdtime }}
{% endif %}
!