diff --git a/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics/multiple_nics.j2 b/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics/multiple_nics.j2 index e4029ac76..2c3f61740 100644 --- a/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics/multiple_nics.j2 +++ b/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics/multiple_nics.j2 @@ -5,7 +5,7 @@ network_config: mtu: {{ ctlplane_mtu }} dns_servers: {{ ctlplane_dns_nameservers }} domain: {{ dns_search_domains }} -{% if default_route_networks and 'ControlPlane' in default_route_networks %} +{% if default_route_networks is not defined or 'ControlPlane' in default_route_networks %} routes: {{ ctlplane_host_routes + [{'default': true, 'next_hop': ctlplane_gateway_ip}] }} {% else %} routes: {{ ctlplane_host_routes }} @@ -13,7 +13,7 @@ network_config: use_dhcp: false addresses: - ip_netmask: {{ ctlplane_ip }}/{{ ctlplane_subnet_cidr }} -{% for network in role_networks %} +{% for network in role_networks and network not in networks_skip_config|default([]) %} {% if network not in ["External", "Tenant"] %} - type: interface name: nic{{ loop.index +1 }} @@ -22,7 +22,7 @@ network_config: addresses: - ip_netmask: {{ lookup('vars', role_networks_lower[network] ~ '_ip') }}/{{ lookup('vars', role_networks_lower[network] ~ '_cidr') }} -{% if default_route_networks and 'ControlPlane' in default_route_networks %} +{% if default_route_networks and network in default_route_networks %} routes: {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') + [{'default': true, 'next_hop': lookup('vars', role_networks_lower[network] ~ '_gateway_ip')}] }} {% else %} diff --git a/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics/multiple_nics_dpdk.j2 b/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics/multiple_nics_dpdk.j2 new file mode 100644 index 000000000..4da05a72f --- /dev/null +++ b/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics/multiple_nics_dpdk.j2 @@ -0,0 +1,76 @@ +--- +network_config: +- type: interface + name: nic1 + mtu: {{ ctlplane_mtu }} + dns_servers: {{ ctlplane_dns_nameservers }} + domain: {{ dns_search_domains }} +{% if default_route_networks is not defined or 'ControlPlane' in default_route_networks %} + routes: {{ ctlplane_host_routes + [{'default': true, 'next_hop': ctlplane_gateway_ip}] }} +{% else %} + routes: {{ ctlplane_host_routes }} +{% endif %} + use_dhcp: false + addresses: + - ip_netmask: {{ ctlplane_ip }}/{{ ctlplane_subnet_cidr }} +{% set nics_used = [1] %} +{% for network in role_networks and network not in networks_skip_config|default([]) %} +{% if network not in ["External", "Tenant"] %} +- type: interface + name: nic{{ loop.index +1 }} + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + use_dhcp: false + addresses: + - ip_netmask: + {{ lookup('vars', role_networks_lower[network] ~ '_ip') }}/{{ lookup('vars', role_networks_lower[network] ~ '_cidr') }} +{% if default_route_networks and network in default_route_networks %} + routes: + {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') + [{'default': true, 'next_hop': lookup('vars', role_networks_lower[network] ~ '_gateway_ip')}] }} +{% else %} + routes: {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') }} +{% endif %} +{% elif 'external_bridge' in role_tags %} +- type: ovs_bridge +{% if network == 'External' %} + name: {{ neutron_physical_bridge_name }} +{% else %} + name: {{ 'br-' ~ role_networks_lower[network] }} +{% endif %} + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + dns_servers: {{ ctlplane_dns_nameservers }} + use_dhcp: false + addresses: + - ip_netmask: + {{ lookup('vars', role_networks_lower[network] ~ '_ip') }}/{{ lookup('vars', role_networks_lower[network] ~ '_cidr') }} +{% if default_route_networks and network in default_route_networks %} + routes: + {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') + [{'default': true, 'next_hop': lookup('vars', role_networks_lower[network] ~ '_gateway_ip')}] }} +{% else %} + routes: {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') }} +{% endif %} + members: + - type: interface + name: nic{{loop.index + 1}} + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + use_dhcp: false + primary: true +{% endif %} +{% set _ = nics_used.append(loop.index) %} +{% endfor %} +- type: ovs_user_bridge + name: br-dpdk0 + members: + - type: ovs_dpdk_bond + name: dpdkbond0 + rx_queue: {{ num_dpdk_interface_rx_queues }} + members: + - type: ovs_dpdk_port + name: dpdk0 + members: + - type: interface + name: nic{{nics_used[-1] + 1}} + - type: ovs_dpdk_port + name: dpdk1 + members: + - type: interface + name: nic{{nics_used[-1] + 2}} diff --git a/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics/multiple_nics_dvr.j2 b/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics/multiple_nics_dvr.j2 new file mode 100644 index 000000000..a2b6bce10 --- /dev/null +++ b/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics/multiple_nics_dvr.j2 @@ -0,0 +1,66 @@ +--- +network_config: +- type: interface + name: nic1 + mtu: {{ ctlplane_mtu }} + dns_servers: {{ ctlplane_dns_nameservers }} + domain: {{ dns_search_domains }} +{% if default_route_networks is not defined or 'ControlPlane' in default_route_networks %} + routes: {{ ctlplane_host_routes + [{'default': true, 'next_hop': ctlplane_gateway_ip}] }} +{% else %} + routes: {{ ctlplane_host_routes }} +{% endif %} + use_dhcp: false + addresses: + - ip_netmask: {{ ctlplane_ip }}/{{ ctlplane_subnet_cidr }} +{% set nics_used = [1] %} +{% for network in role_networks and network not in networks_skip_config|default([]) %} +{% if network not in ["External", "Tenant"] %} +- type: interface + name: nic{{ loop.index +1 }} + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + use_dhcp: false + addresses: + - ip_netmask: + {{ lookup('vars', role_networks_lower[network] ~ '_ip') }}/{{ lookup('vars', role_networks_lower[network] ~ '_cidr') }} +{% if default_route_networks and network in default_route_networks %} + routes: + {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') + [{'default': true, 'next_hop': lookup('vars', role_networks_lower[network] ~ '_gateway_ip')}] }} +{% else %} + routes: {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') }} +{% endif %} +{% elif network == 'Tenant' %} +- type: ovs_bridge + name: {{ 'br-' ~ role_networks_lower[network] }} + name: {{ neutron_physical_bridge_name }} + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + dns_servers: {{ ctlplane_dns_nameservers }} + use_dhcp: false + addresses: + - ip_netmask: + {{ lookup('vars', role_networks_lower[network] ~ '_ip') }}/{{ lookup('vars', role_networks_lower[network] ~ '_cidr') }} +{% if default_route_networks and network in default_route_networks %} + routes: + {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') + [{'default': true, 'next_hop': lookup('vars', role_networks_lower[network] ~ '_gateway_ip')}] }} +{% else %} + routes: {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') }} +{% endif %} + members: + - type: interface + name: nic{{loop.index + 1}} + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + use_dhcp: false + primary: true +{% endif %} +{% set _ = nics_used.append(loop.index) %} +{% endfor %} +- type: ovs_bridge + name: {{ neutron_physical_bridge_name }} + mtu: {{ lookup('vars', role_networks_lower['External'] ~ '_mtu') }} + dns_servers: {{ ctlplane_dns_nameservers }} + use_dhcp: false + members: + - type: interface + name: nic{{nics_used[-1] + 1}} + mtu: {{ lookup('vars', role_networks_lower['External'] ~ '_mtu') }} + primary: true diff --git a/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics_vlans/multiple_nics_vlans.j2 b/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics_vlans/multiple_nics_vlans.j2 index 56095c516..a7ee38c15 100644 --- a/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics_vlans/multiple_nics_vlans.j2 +++ b/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics_vlans/multiple_nics_vlans.j2 @@ -5,7 +5,7 @@ network_config: mtu: {{ ctlplane_mtu }} dns_servers: {{ ctlplane_dns_nameservers }} domain: {{ dns_search_domains }} -{% if default_route_networks and 'ControlPlane' in default_route_networks %} +{% if default_route_networks is not defined or 'ControlPlane' in default_route_networks %} routes: {{ ctlplane_host_routes + [{'default': true, 'next_hop': ctlplane_gateway_ip}] }} {% else %} routes: {{ ctlplane_host_routes }} @@ -13,7 +13,7 @@ network_config: use_dhcp: false addresses: - ip_netmask: {{ ctlplane_ip }}/{{ ctlplane_subnet_cidr }} -{% for network in role_networks %} +{% for network in role_networks and network not in networks_skip_config|default([]) %} {% if network not in ["External", "Tenant"] %} - type: interface name: nic{{ loop.index + 1 }} @@ -26,7 +26,7 @@ network_config: addresses: - ip_netmask: {{ lookup('vars', role_networks_lower[network] ~ '_ip') }}/{{ lookup('vars', role_networks_lower[network] ~ '_cidr') }} -{% if default_route_networks and 'ControlPlane' in default_route_networks %} +{% if default_route_networks and network in default_route_networks %} routes: {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') + [{'default': true, 'next_hop': lookup('vars', role_networks_lower[network] ~ '_gateway_ip')}] }} {% else %} @@ -42,7 +42,7 @@ network_config: mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} dns_servers: {{ ctlplane_dns_nameservers }} use_dhcp: false - members: + members: - type: interface name: nic{{ loop.index + 1 }} mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} diff --git a/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics_vlans/multiple_nics_vlans_dpdk.j2 b/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics_vlans/multiple_nics_vlans_dpdk.j2 new file mode 100644 index 000000000..b6791b3e4 --- /dev/null +++ b/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics_vlans/multiple_nics_vlans_dpdk.j2 @@ -0,0 +1,83 @@ +--- +network_config: +- type: interface + name: nic1 + mtu: {{ ctlplane_mtu }} + dns_servers: {{ ctlplane_dns_nameservers }} + domain: {{ dns_search_domains }} +{% if default_route_networks is not defined or 'ControlPlane' in default_route_networks %} + routes: {{ ctlplane_host_routes + [{'default': true, 'next_hop': ctlplane_gateway_ip}] }} +{% else %} + routes: {{ ctlplane_host_routes }} +{% endif %} + use_dhcp: false + addresses: + - ip_netmask: {{ ctlplane_ip }}/{{ ctlplane_subnet_cidr }} +{% set nics_used = [1] %} +{% for network in role_networks and network not in networks_skip_config|default([]) %} +{% if network not in ["External", "Tenant"] %} +- type: interface + name: nic{{ loop.index + 1 }} + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + use_dhcp: false +- type: vlan + device: nic{{ loop.index + 1 }} + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + vlan_id: {{ lookup('vars', role_networks_lower[network] ~ '_vlan_id') }} + addresses: + - ip_netmask: + {{ lookup('vars', role_networks_lower[network] ~ '_ip') }}/{{ lookup('vars', role_networks_lower[network] ~ '_cidr') }} +{% if default_route_networks and network in default_route_networks %} + routes: + {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') + [{'default': true, 'next_hop': lookup('vars', role_networks_lower[network] ~ '_gateway_ip')}] }} +{% else %} + routes: {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') }} +{% endif %} +{% elif 'external_bridge' in role_tags %} +- type: ovs_bridge +{% if network == 'External' %} + name: {{ neutron_physical_bridge_name }} +{% else %} + name: {{ 'br-' ~ role_networks_lower[network] }} +{% endif %} + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + dns_servers: {{ ctlplane_dns_nameservers }} + use_dhcp: false + members: + - type: interface + name: nic{{ loop.index + 1 }} + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + use_dhcp: false + primary: true + - type: vlan + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + vlan_id: {{ lookup('vars', role_networks_lower[network] ~ '_vlan_id') }} + addresses: + - ip_netmask: + {{ lookup('vars', role_networks_lower[network] ~ '_ip') }}/{{ lookup('vars', role_networks_lower[network] ~ '_cidr') }} +{% if default_route_networks and network in default_route_networks %} + routes: + {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') + [{'default': true, 'next_hop': lookup('vars', role_networks_lower[network] ~ '_gateway_ip')}] }} +{% else %} + routes: {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') }} +{% endif %} +{% endif %} +{% set _ = nics_used.append(loop.index) %} +{% endfor %} +- type: ovs_user_bridge + name: br-dpdk0 + members: + - type: ovs_dpdk_bond + name: dpdkbond0 + rx_queue: {{ num_dpdk_interface_rx_queues }} + members: + - type: ovs_dpdk_port + name: dpdk0 + members: + - type: interface + name: nic{{nics_used[-1] + 1}} + - type: ovs_dpdk_port + name: dpdk1 + members: + - type: interface + name: nic{{nics_used[-1] + 2}} diff --git a/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics_vlans/multiple_nics_vlans_dvr.j2 b/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics_vlans/multiple_nics_vlans_dvr.j2 new file mode 100644 index 000000000..c9a7a960e --- /dev/null +++ b/tripleo_ansible/roles/tripleo_network_config/templates/multiple_nics_vlans/multiple_nics_vlans_dvr.j2 @@ -0,0 +1,72 @@ +--- +network_config: +- type: interface + name: nic1 + mtu: {{ ctlplane_mtu }} + dns_servers: {{ ctlplane_dns_nameservers }} + domain: {{ dns_search_domains }} +{% if default_route_networks is not defined or 'ControlPlane' in default_route_networks %} + routes: {{ ctlplane_host_routes + [{'default': true, 'next_hop': ctlplane_gateway_ip}] }} +{% else %} + routes: {{ ctlplane_host_routes }} +{% endif %} + use_dhcp: false + addresses: + - ip_netmask: {{ ctlplane_ip }}/{{ ctlplane_subnet_cidr }} +{% set nics_used = [1] %} +{% for network in role_networks and network not in networks_skip_config|default([]) %} +{% if network not in ["External", "Tenant"] %} +- type: interface + name: nic{{ loop.index + 1 }} + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + use_dhcp: false +- type: vlan + device: nic{{ loop.index + 1 }} + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + vlan_id: {{ lookup('vars', role_networks_lower[network] ~ '_vlan_id') }} + addresses: + - ip_netmask: + {{ lookup('vars', role_networks_lower[network] ~ '_ip') }}/{{ lookup('vars', role_networks_lower[network] ~ '_cidr') }} +{% if default_route_networks and network in default_route_networks %} + routes: + {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') + [{'default': true, 'next_hop': lookup('vars', role_networks_lower[network] ~ '_gateway_ip')}] }} +{% else %} + routes: {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') }} +{% endif %} +{% elif network == 'Tenant' %} +- type: ovs_bridge + name: {{ 'br-' ~ role_networks_lower[network] }} + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + dns_servers: {{ ctlplane_dns_nameservers }} + use_dhcp: false + members: + - type: interface + name: nic{{ loop.index + 1 }} + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + use_dhcp: false + primary: true + - type: vlan + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + vlan_id: {{ lookup('vars', role_networks_lower[network] ~ '_vlan_id') }} + addresses: + - ip_netmask: + {{ lookup('vars', role_networks_lower[network] ~ '_ip') }}/{{ lookup('vars', role_networks_lower[network] ~ '_cidr') }} +{% if default_route_networks and network in default_route_networks %} + routes: + {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') + [{'default': true, 'next_hop': lookup('vars', role_networks_lower[network] ~ '_gateway_ip')}] }} +{% else %} + routes: {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') }} +{% endif %} +{% endif %} +{% set _ = nics_used.append(loop.index) %} +{% endfor %} +- type: ovs_bridge + name: {{ neutron_physical_bridge_name }} + mtu: {{ lookup('vars', role_networks_lower['External'] ~ '_mtu') }} + dns_servers: {{ ctlplane_dns_nameservers }} + use_dhcp: false + members: + - type: interface + name: nic{{nics_used[-1] + 1}} + mtu: {{ lookup('vars', role_networks_lower['External'] ~ '_mtu') }} + primary: true diff --git a/tripleo_ansible/roles/tripleo_network_config/templates/single_nic_vlans/controller_no_external.j2 b/tripleo_ansible/roles/tripleo_network_config/templates/single_nic_vlans/controller_no_external.j2 new file mode 100644 index 000000000..89e594992 --- /dev/null +++ b/tripleo_ansible/roles/tripleo_network_config/templates/single_nic_vlans/controller_no_external.j2 @@ -0,0 +1,40 @@ +--- +{% set mtu_list = [ctlplane_mtu] %} +{% for network in role_networks %} +{{ mtu_list.append(lookup('vars', role_networks_lower[network] ~ '_mtu')) }} +{%- endfor %} +{% set min_viable_mtu = mtu_list | max %} +network_config: +- type: ovs_bridge + name: {{ neutron_physical_bridge_name }} + mtu: {{ min_viable_mtu }} + use_dhcp: false + dns_servers: {{ ctlplane_dns_nameservers }} + domain: {{ dns_search_domains }} + addresses: + - ip_netmask: {{ ctlplane_ip }}/{{ ctlplane_subnet_cidr }} +{% if default_route_networks is not defined or 'ControlPlane' in default_route_networks %} + routes: {{ ctlplane_host_routes + [{'default': true, 'next_hop': ctlplane_gateway_ip}] }} +{% else %} + routes: {{ ctlplane_host_routes }} +{% endif %} + members: + - type: interface + name: nic1 + mtu: {{ min_viable_mtu }} + # force the MAC address of the bridge to this interface + primary: true +{% for network in role_networks and network != 'External' %} + - type: vlan + mtu: {{ lookup('vars', role_networks_lower[network] ~ '_mtu') }} + vlan_id: {{ lookup('vars', role_networks_lower[network] ~ '_vlan_id') }} + addresses: + - ip_netmask: + {{ lookup('vars', role_networks_lower[network] ~ '_ip') }}/{{ lookup('vars', role_networks_lower[network] ~ '_cidr') }} +{% if default_route_networks and network in default_route_networks %} + routes: + {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') + [{'default': true, 'next_hop': lookup('vars', role_networks_lower[network] ~ '_gateway_ip')}] }} +{% else %} + routes: {{ lookup('vars', role_networks_lower[network] ~ '_host_routes') }} +{% endif %} +{% endfor %} diff --git a/tripleo_ansible/roles/tripleo_network_config/templates/single_nic_vlans/single_nic_vlans.j2 b/tripleo_ansible/roles/tripleo_network_config/templates/single_nic_vlans/single_nic_vlans.j2 index b5a2d0682..684fd6d61 100644 --- a/tripleo_ansible/roles/tripleo_network_config/templates/single_nic_vlans/single_nic_vlans.j2 +++ b/tripleo_ansible/roles/tripleo_network_config/templates/single_nic_vlans/single_nic_vlans.j2 @@ -1,5 +1,5 @@ --- -{% set mtu_list = [] %} +{% set mtu_list = [ctlplane_mtu] %} {% for network in role_networks %} {{ mtu_list.append(lookup('vars', role_networks_lower[network] ~ '_mtu')) }} {%- endfor %} @@ -13,7 +13,7 @@ network_config: domain: {{ dns_search_domains }} addresses: - ip_netmask: {{ ctlplane_ip }}/{{ ctlplane_subnet_cidr }} -{% if default_route_networks and 'ControlPlane' in default_route_networks %} +{% if default_route_networks is not defined or 'ControlPlane' in default_route_networks %} routes: {{ ctlplane_host_routes + [{'default': true, 'next_hop': ctlplane_gateway_ip}] }} {% else %} routes: {{ ctlplane_host_routes }} diff --git a/tripleo_ansible/roles/tripleo_network_config/templates/single_nic_vlans/storage_single_nic_vlans.j2 b/tripleo_ansible/roles/tripleo_network_config/templates/single_nic_vlans/single_nic_vlans_storage.j2 similarity index 91% rename from tripleo_ansible/roles/tripleo_network_config/templates/single_nic_vlans/storage_single_nic_vlans.j2 rename to tripleo_ansible/roles/tripleo_network_config/templates/single_nic_vlans/single_nic_vlans_storage.j2 index a545535c1..eb2611452 100644 --- a/tripleo_ansible/roles/tripleo_network_config/templates/single_nic_vlans/storage_single_nic_vlans.j2 +++ b/tripleo_ansible/roles/tripleo_network_config/templates/single_nic_vlans/single_nic_vlans_storage.j2 @@ -1,5 +1,5 @@ --- -{% set mtu_list = [] %} +{% set mtu_list = [ctlplane_mtu] %} {% for network in role_networks %} {{ mtu_list.append(lookup('vars', role_networks_lower[network] ~ '_mtu')) }} {%- endfor %} @@ -13,7 +13,7 @@ network_config: domain: {{ dns_search_domains }} addresses: - ip_netmask: {{ ctlplane_ip }}/{{ ctlplane_subnet_cidr }} -{% if default_route_networks and 'ControlPlane' in default_route_networks %} +{% if default_route_networks is not defined or 'ControlPlane' in default_route_networks %} routes: {{ ctlplane_host_routes + [{'default': true, 'next_hop': ctlplane_gateway_ip}] }} {% else %} routes: {{ ctlplane_host_routes }}