heat_template_version: rocky

description: >
  TripleO Firewall settings

parameters:
  ServiceData:
    default: {}
    description: Dictionary packing service data
    type: json
  ServiceNetMap:
    default: {}
    description: Mapping of service_name -> network name. Typically set
                 via parameter_defaults in the resource registry.  This
                 mapping overrides those in ServiceNetMapDefaults.
    type: json
  DefaultPasswords:
    default: {}
    type: json
  RoleName:
    default: ''
    description: Role name on which the service is applied
    type: string
  RoleParameters:
    default: {}
    description: Parameters specific to the role
    type: json
  EndpointMap:
    default: {}
    description: Mapping of service endpoint -> protocol. Typically set
                 via parameter_defaults in the resource registry.
    type: json
  ManageFirewall:
    default: true
    description: Whether to manage IPtables rules.
    type: boolean
  PurgeFirewallRules:
    default: false
    description: Whether IPtables rules should be purged before setting up the new ones.
    type: boolean

conditions:
  no_ctlplane:
    equals:
      - get_params: [ServiceData, net_cidr_map, ctlplane]
      - Null

outputs:
  role_data:
    description: Role data for the TripleO firewall settings
    value:
      service_name: tripleo_firewall
      firewall_rules:
        map_merge:
          repeat:
            for_each:
              <%net_cidr%>: {get_param: [ServiceData, net_cidr_map, ctlplane]}
            template:
              '003 accept ssh from ctlplane subnet <%net_cidr%>':
                source: <%net_cidr%>
                proto: 'tcp'
                dport: 22
      config_settings:
        tripleo::firewall::manage_firewall: {get_param: ManageFirewall}
        tripleo::firewall::purge_firewall_rules: {get_param: PurgeFirewallRules}
      step_config: |
        include ::tripleo::firewall

      host_prep_tasks:
        if:
        - no_ctlplane
        -
          name: Ensure ctlplane subnet is set
          fail:
            msg: |
              No CIDRs found in the ctlplane network tags.
              Please refer to the documentation in order to
              set the correct network tags in DeployedServerPortMap.
        - null

      deploy_steps_tasks:
        - when: step|int == 0
          block:
            - name: create iptables service
              copy:
                dest: /etc/systemd/system/tripleo-iptables.service
                content: |
                  [Unit]
                  Description=Initialize iptables
                  Before=iptables.service
                  AssertPathExists=/etc/sysconfig/iptables

                  [Service]
                  Type=oneshot
                  ExecStart=/usr/sbin/iptables -t raw -nL
                  Environment=BOOTUP=serial
                  Environment=CONSOLETYPE=serial
                  StandardOutput=syslog
                  StandardError=syslog
                  [Install]
                  WantedBy=basic.target
            - name: create ip6tables service
              copy:
                dest: /etc/systemd/system/tripleo-ip6tables.service
                content: |
                  [Unit]
                  Description=Initialize ip6tables
                  Before=ip6tables.service
                  AssertPathExists=/etc/sysconfig/ip6tables

                  [Service]
                  Type=oneshot
                  ExecStart=/usr/sbin/ip6tables -t raw -nL
                  Environment=BOOTUP=serial
                  Environment=CONSOLETYPE=serial
                  StandardOutput=syslog
                  StandardError=syslog
                  [Install]
                  WantedBy=basic.target
            - name: enable tripleo-iptables service (and do a daemon-reload systemd)
              systemd:
                daemon_reload: yes
                enabled: yes
                name: tripleo-iptables.service
            - name: enable tripleo-ip6tables service
              systemd:
                enabled: yes
                name: tripleo-ip6tables.service
      upgrade_tasks:
        - when: step|int == 3
          block:
            - name: blank ipv6 rule before activating ipv6 firewall.
              shell: cat /etc/sysconfig/ip6tables > /etc/sysconfig/ip6tables.n-o-upgrade; cat</dev/null>/etc/sysconfig/ip6tables
              args:
                creates: /etc/sysconfig/ip6tables.n-o-upgrade
            - name: cleanup unmanaged rules pushed by iptables-services
              shell: |
                iptables -C INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT &>/dev/null && \
                  iptables -D INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
                iptables -C INPUT -p icmp -j ACCEPT &>/dev/null && \
                  iptables -D INPUT -p icmp -j ACCEPT
                iptables -C INPUT -i lo -j ACCEPT &>/dev/null && \
                  iptables -D INPUT -i lo -j ACCEPT
                iptables -C INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT &>/dev/null && \
                  iptables -D INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
                iptables -C INPUT -j REJECT --reject-with icmp-host-prohibited &>/dev/null && \
                  iptables -D INPUT -j REJECT --reject-with icmp-host-prohibited
                iptables -C FORWARD -j REJECT --reject-with icmp-host-prohibited &>/dev/null && \
                  iptables -D FORWARD -j REJECT --reject-with icmp-host-prohibited

                sed -i '/^-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT$/d' /etc/sysconfig/iptables
                sed -i '/^-A INPUT -p icmp -j ACCEPT$/d' /etc/sysconfig/iptables
                sed -i '/^-A INPUT -i lo -j ACCEPT$/d' /etc/sysconfig/iptables
                sed -i '/^-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT$/d' /etc/sysconfig/iptables
                sed -i '/^-A INPUT -j REJECT --reject-with icmp-host-prohibited$/d' /etc/sysconfig/iptables
                sed -i '/^-A FORWARD -j REJECT --reject-with icmp-host-prohibited$/d' /etc/sysconfig/iptables

                ip6tables -C INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT &>/dev/null && \
                  ip6tables -D INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
                ip6tables -C INPUT -p ipv6-icmp -j ACCEPT &>/dev/null && \
                  ip6tables -D INPUT -p ipv6-icmp -j ACCEPT
                ip6tables -C INPUT -i lo -j ACCEPT &>/dev/null && \
                  ip6tables -D INPUT -i lo -j ACCEPT
                ip6tables -C INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT &>/dev/null && \
                  ip6tables -D INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
                ip6tables -C INPUT -d fe80::/64 -p udp -m udp --dport 546 -m state --state NEW -j ACCEPT &>/dev/null && \
                  ip6tables -D INPUT -d fe80::/64 -p udp -m udp --dport 546 -m state --state NEW -j ACCEPT
                ip6tables -C INPUT -j REJECT --reject-with icmp6-adm-prohibited &>/dev/null && \
                  ip6tables -D INPUT -j REJECT --reject-with icmp6-adm-prohibited
                ip6tables -C FORWARD -j REJECT --reject-with icmp6-adm-prohibited &>/dev/null && \
                  ip6tables -D FORWARD -j REJECT --reject-with icmp6-adm-prohibited

                sed -i '/^-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT$/d' /etc/sysconfig/ip6tables
                sed -i '/^-A INPUT -p ipv6-icmp -j ACCEPT$/d' /etc/sysconfig/ip6tables
                sed -i '/^-A INPUT -i lo -j ACCEPT$/d' /etc/sysconfig/ip6tables
                sed -i '/^-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT$/d' /etc/sysconfig/ip6tables
                sed -i '/^-A INPUT -d fe80::\/64 -p udp -m udp --dport 546 -m state --state NEW -j ACCEPT$/d' /etc/sysconfig/ip6tables
                sed -i '/^-A INPUT -j REJECT --reject-with icmp6-adm-prohibited$/d' /etc/sysconfig/ip6tables
                sed -i '/^-A FORWARD -j REJECT --reject-with icmp6-adm-prohibited$/d' /etc/sysconfig/ip6tables
