# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

# /*---------------------------------------------------------------------------8
# |                                                                            |
# |            Role to set kernel parameters for general hardening             |
# |                                                                            |
# +------------------------------------4--------------------------------------*/
# Description:  A set of common parameters recommeneded from CIS, RH and SUSE -
#               are applied to the host along with some distro specific params.
#
# Objects:
#   External:
#             parameters.yaml                  - parameter file
#
#   Internal:
#             get_parameters_to_apply             - object to store the params
#                                                applicable for a host
#
#   Created:
#
#
# -------------------------------------+---------------------------------------8
# Reviews:
#
#
#
# -------------------------------------+---------------------------------------8
---
# -------------------------------------+---------------------------------------8
#
#   Task: 1.9                                  - kernel parameters
#
# -------------------------------------+---------------------------------------8

# -------------------------------------+---------------------------------------8
#
# <Comment Header>
#
# -------------------------------------+---------------------------------------8

- name:                                "1.9 Kernel parameters - Ensure parameters are available"
  ansible.builtin.include_vars:        parameters.yaml

- name:                                "1.9 Kernel parameters - Print the tier and node tier"
  ansible.builtin.debug:
    msg:
      - "tier is:      {{ tier }}"
      - "node_tier is: {{ node_tier }}"

# ----------------------------------------
# BEGIN
# ----------------------------------------

- name:                                "1.9 Kernel parameters - Gather list of parameters which need to be applied"
  ansible.builtin.set_fact:
    get_parameters_to_apply:           '{{
                                          (parameters["common"] +
                                          (parameters[distribution_id] | default([]))) | unique
                                        }}'

# Print Distribution ID if it is passed correctly.
- name:                                "1.9 Kernel parameters - Display distribution_id which will be used"
  ansible.builtin.debug:
    msg:                              "Distribution ID: {{ distribution_id }}"
    verbosity:                         2


# print only when -vv, otherwise you will have terminal nausea
- name:                                "1.9 Kernel parameters - Display parameters which will be applied"
  ansible.builtin.debug:
    var:                               get_parameters_to_apply
    verbosity:                         2

- name:                                "1.9 Kernel parameters - Set relevant kernel parameters"
  become:                              true
  ansible.posix.sysctl:
    name:                              "{{ item.name }}"
    value:                             "{{ item.value }}"
    state:                             "{{ item.state }}"
    sysctl_set:                        true
    reload:                            true
    ignoreerrors:                      true
  loop:                                "{{ get_parameters_to_apply }}"
  when:
    - item.tier in ["all", tier]
    - item.node_tier in ["all", node_tier]

# Huge pages for Oracle Database VMs
# SAP Note 1672954 : Usage of hugepages on a Linux system that runs an Oracle database.
- name:                                "1.9 Kernel parameters - Oracle Specific Parameters"
  block:
    - name:                            "1.9 Kernel parameters - Calculate the Huge Pages when RAM < 4TB"
      ansible.builtin.set_fact:
        huge_pages:                    "{{ ((ansible_memory_mb.real.total * 0.68 * 1024 * 1024) / (2 * 1024 * 1024)) | round | int }}"
      when:                            ansible_memory_mb.real.total < 4194304

    - name:                            "1.9 Kernel parameters - Calculate the Huge Pages when RAM > 4TB "
      ansible.builtin.set_fact:
        huge_pages:                    "{{ ((ansible_memory_mb.real.total * 0.75 * 1024 * 1024) / (2 * 1024 * 1024)) | round | int }}"
      when:                            ansible_memory_mb.real.total > 4194304

    # print only when -vv, otherwise you will have terminal nausea
    - name:                            "1.9 Kernel parameters - Display Huge pages value"
      ansible.builtin.debug:
        var:                           huge_pages
        verbosity:                     2

    - name:                            "1.9 Kernel parameters - Set Huge pages parameters"
      become:                          true
      ansible.posix.sysctl:
        name:                          "vm.nr_hugepages"
        value:                         "{{ huge_pages }}"
        state:                         "present"
        sysctl_set:                    true
        reload:                        true
        ignoreerrors:                  true

    - name:                            "1.9 Kernel parameters - Set limits"
      ansible.builtin.blockinfile:
        path:                          /etc/security/limits.conf
        insertafter:                   '#@student        -       maxlogins       4'
        state:                         present
        block: |
                oracle     soft memlock unlimited
                oracle     hard memlock unlimited
                @sapsys    hard    nproc    unlimited
                @sapsys    soft    nproc    unlimited
                @dba       hard    nproc    unlimited
                @dba       soft    nproc    unlimited
  when:
    - node_tier in ["oracle","oracle-asm","oracle-multi-sid"]

- name:                                "1.9 Kernel parameters - Set limits for DB2"
  ansible.builtin.blockinfile:
    path:                              /etc/security/limits.conf
    insertafter:                       '#@student        -       maxlogins       4'
    state:                              present
    block: |
                @sapsys    hard    nproc    unlimited
                @sapsys    soft    nproc    unlimited
                @db{{ db_sid | lower }}adm      hard    nproc    unlimited
                @db{{ db_sid | lower }}adm      soft    nproc    unlimited
  when:
    - node_tier == 'db2'

- name:                                "1.9 Kernel parameters - Set limits for HANA"
  ansible.builtin.blockinfile:
    path:                              /etc/security/limits.conf
    insertafter:                       '#@student        -       maxlogins       4'
    state:                              present
    block: |
                @sapsys    hard    nproc    unlimited
                @sapsys    soft    nproc    unlimited
                @dba       hard    nproc    unlimited
                @dba       soft    nproc    unlimited
  when:
    - node_tier == 'hana'

- name:                                "1.9 Kernel parameters - Set limits for app tier"
  ansible.builtin.blockinfile:
    path:                              /etc/security/limits.conf
    insertafter:                       '#@student        -       maxlogins       4'
    state:                              present
    block: |
                @sapsys    hard    nproc    unlimited
                @sapsys    soft    nproc    unlimited
                @sapsys    hard    nofile   65536
                @sapsys    soft    nofile   65536
  when:
    - node_tier in ['scs','ers','app','pas']

# ----------------------------------------
# END
# ----------------------------------------


# /*----------------------------------------------------------------------------8
# |                       Custom kernel parameters                              |
# +------------------------------------4---------------------------------------*/


- name:                                "1.9 Kernel parameters - Gather list of custom defined parameters which need to be applied"
  ansible.builtin.set_fact:
    get_custom_parameters_to_apply:    '{{
                                           (
                                             custom_parameters[distribution_id] | default([]) +
                                             custom_parameters["common"] | default([])
                                           ) | unique(attribute="name") | list
                                        }}'
  when:
    - custom_parameters is defined

- name:                                "1.9 Kernel parameters - Set relevant custom defined kernel parameters"
  become:                              true
  ansible.posix.sysctl:
    name:                              "{{ item.name }}"
    value:                             "{{ item.value }}"
    state:                             "{{ item.state }}"
    sysctl_set:                        true
    reload:                            true
    ignoreerrors:                      true
  loop:                                "{{ get_custom_parameters_to_apply }}"
  when:
    - get_custom_parameters_to_apply is defined
    - item.tier in ["all", tier]
    - item.node_tier in ["all", node_tier]

...
# /*----------------------------------------------------------------------------8
# |                                    END                                      |
# +------------------------------------4--------------------------------------*/
