#!/bin/bash
#====================================================================
# Description: CDN Node Installation Script
#              - System initialization for CentOS 7
#              - Install and configure components:
#                * OpenResty
#                * Logstash 7.6.1
#                * Logstash-exporter
#                * Young Agent
#              - Setup firewall, SSH, and system optimizations
# Author: Liu YanHao
# Create Time: 2024-11-15
# Last Modified: 2025-01-06
# Version: 1.2
# Usage: ./cdninstall.sh
# Example: ./cdninstall.sh
#====================================================================
set -e

# ----------------------------------------Check System Environment / 检查系统环境----------------------------------------
function check_os() {
    # Check OS version / 检查操作系统版本
    if ! grep -q "CentOS Linux release 7.9" /etc/centos-release 2>/dev/null; then
        echo -e "\e[31m脚本仅支持 CentOS 7.9 / This script only supports CentOS 7.9\e[0m"
        exit 1
    fi

    # Validate required parameters / 验证必需的参数
    if [[ -z "${1}" ]] || [[ -z "${2}" ]]; then
        echo -e "\e[31m请提供正确的 IP 地址和 salt_id 前缀参数 / Please provide correct IP address and salt_id prefix\e[0m"
        exit 1
    fi
}

# ----------------------------------------Software Installation / 软件包安装----------------------------------------
function software_install() {
    # Disable swap / 关闭交换分区
    sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab
    swapoff -a

    # Install required packages / 安装必需软件包
    yum -y install \
        epel-release vim wget curl net-tools lrzsz \
        bash-completion bash-completion-extras \
        htop iotop iftop sysstat lsof \
        fping mtr traceroute tcpdump telnet nc \
        tree zip unzip chrony expect \
        java-11-openjdk-devel.x86_64 java-11-openjdk-headless.x86_64 \
        git
}

# ----------------------------------------Disk Initialization / 磁盘初始化----------------------------------------
function disk_init() {
    bash /root/cdninstall/pkg/disk_init.sh

    if [[ $? -eq 0 ]]; then
        echo -e "\e[1;32m 磁盘初始化成功 \e[0m"
    else
        echo -e "\e[1;31m 磁盘初始化失败 \e[0m"
        exit 1
    fi
}

# ----------------------------------------Hostname Configuration / 主机名配置----------------------------------------
function hostname_config() {
    # Set hostname based on IP / 根据IP设置主机名
    hostnamectl set-hostname cdn-$(echo ${1} | sed 's/\./-/g')
    grep -lr ${1} /etc/hosts &>/dev/null || echo "${1}  $(hostname)" >>/etc/hosts

    if [[ $? -eq 0 ]]; then
        echo -e "\e[1;32m 主机名配置成功 \e[0m"
    else
        echo -e "\e[1;31m 主机名配置失败 \e[0m"
        exit 1
    fi
}

# ----------------------------------------Firewall Configuration / 防火墙配置----------------------------------------
function firewall_config() {
    # Enable and start firewall / 启用并启动防火墙
    systemctl enable --now firewalld

    # Configure firewall rules / 配置防火墙规则
    (curl -sSL http://deb.aorta.global/ACL/firewall_allow_all.sh | bash) || (wget -qO- http://deb.aorta.global/ACL/firewall_allow_all.sh | bash)
    firewall-cmd --permanent --add-port={80,443,8085,10050}/tcp
    firewall-cmd --reload

    if [[ $? -eq 0 ]]; then
        echo -e "\e[1;32m 防火墙配置成功 \e[0m"
    else
        echo -e "\e[1;31m 防火墙配置失败 \e[0m"
        exit 1
    fi
}

# ----------------------------------------Network and Time Configuration / 网络和时间配置----------------------------------------
function NetworkYH() {
    # Set timezone and sync time / 设置时区并同步时间
    timedatectl set-timezone Asia/Shanghai
    yum -y install chrony
    systemctl enable chronyd && systemctl restart chronyd
    chronyc tracking && chronyc -a makestep

    if [[ $? -eq 0 ]]; then
        echo -e "\e[1;32m 网络和时间配置成功 \e[0m"
    else
        echo -e "\e[1;31m 网络和时间配置失败 \e[0m"
        exit 1
    fi
}

# ----------------------------------------Kernel Optimization / 内核优化----------------------------------------
function kernel_optimize() {
    # Configure history settings / 配置历史记录设置
    cat <<'EOF' >/etc/profile.d/history.sh
    # Enable history append mode / 启用历史记录追加模式
    shopt -s histappend

    # Set history size and file size / 设置历史记录大小和文件大小
    export HISTSIZE=1000000
    export HISTFILESIZE=1000000

    # Set history time format / 设置历史记录时间格式
    export HISTTIMEFORMAT="%F %T "

    # Ignore duplicates and commands starting with space / 忽略重复命令和以空格开头的命令
    export HISTCONTROL=ignoreboth

    # Sync history across multiple terminals / 在多个终端间同步历史记录
    export PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND$'\n'}history -a; history -c; history -r"
EOF

    # Disable mail check / 禁用邮件检查
    cat <<'EOF' >/etc/profile.d/mailcheck.sh
    unset MAILCHECK
EOF

    # Reload profile settings / 重新加载 profile 配置
    source /etc/profile

    # TCP optimization / TCP 优化
    if [[ $(nproc) -le 2 ]]; then
        cd /root/cdninstall/pkg/kernel_core && sh 2c4g.sh
    elif [[ $(nproc) -le 4 ]]; then
        cd /root/cdninstall/pkg/kernel_core && sh 4c8g.sh
    elif [[ $(nproc) -le 8 ]]; then
        cd /root/cdninstall/pkg/kernel_core && sh 8c16g.sh
    else
        echo -e "\e[1;31m 内核优化失败，检查/root/cdninstall/pkg/kernel_core/2c4g.sh、4c8g.sh、8c16g.sh \e[0m"
        exit 1
    fi

    # 以下内容重启生效
    [ ! -f /etc/security/limits.conf.bak ] && cp /etc/security/limits.conf{,.bak}
    cat >/etc/security/limits.conf <<'EOF'
root     soft   nofile    1048576
root     hard   nofile    1048576
root     soft   nproc     1048576
root     hard   nproc     1048576
root     soft   core      unlimited
root     hard   core      unlimited
root     hard   memlock   unlimited
root     soft   memlock   unlimited

*     soft   nofile    1048576
*     hard   nofile    1048576
*     soft   nproc     1048576
*     hard   nproc     1048576
*     soft   core      unlimited
*     hard   core      unlimited
*     hard   memlock   unlimited
*     soft   memlock   unlimited
EOF
    sysctl -p

    if ! rpm -qa | grep -wq kernel-lt-5.4.278; then
        rpm -ivh /root/cdninstall/pkg/kernel_core/kernel-lt-5.4.278-1.el7.elrepo.x86_64.rpm
        awk -F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg && grub2-set-default 0
    fi
}

# ----------------------------------------Salt Installation / Salt 安装----------------------------------------
function salt_install() {
    bash /root/cdninstall/pkg/salt_install.sh "${1}" "${2}"

    if [[ $? -eq 0 ]]; then
        echo -e "\e[1;32m salt 部署成功 \e[0m"
    else
        echo -e "\e[1;31m salt 部署失败，检查/root/cdninstall/pkg/salt_install.sh \e[0m"
        exit 1
    fi
}

# ----------------------------------------Young Agent Installation / Young Agent 安装----------------------------------------
function young_agent_install() {
    bash /root/cdninstall/pkg/young_agent/young_install.sh

    if [[ $? -eq 0 ]]; then
        echo -e "\e[1;32m young_agent 部署成功 \e[0m"
    else
        echo -e "\e[1;31m young_agent 部署失败，检查/root/cdninstall/pkg/young_agent/young_install.sh \e[0m"
        exit 1
    fi
}

# ----------------------------------------OpenResty Installation / OpenResty 安装----------------------------------------
function openresty_install() {
    bash /root/cdninstall/pkg/openresty_install.sh

    if [[ $? -eq 0 ]]; then
        echo -e "\e[1;32m openresty 部署成功 \e[0m"
    else
        echo -e "\e[1;31m openresty 部署失败，检查/root/cdninstall/pkg/openresty_install.sh \e[0m"
        exit 1
    fi
}

# ----------------------------------------Logstash Installation / Logstash 安装----------------------------------------
function logstash_install() {
    # Calculate workers based on CPU cores / 根据CPU核心数计算workers数
    CPUs=$(lscpu | grep "^CPU(s)" | awk '{print $2}')
    workers=$((CPUs / 2))

    # Install and configure logstash / 安装并配置logstash
    rpm -qa | grep -wq logstash || rpm -ivh /root/cdninstall/pkg/logstash/logstash-7.6.1.rpm
    cp -f /root/cdninstall/pkg/logstash/nginx.conf /etc/logstash/conf.d/nginx.conf

    # Configure pipelines / 配置管道
    cat >/etc/logstash/pipelines.yml <<EOF
# This file is where you define your pipelines. You can define multiple.
# For more information on multiple pipelines, see the documentation:
#   https://www.elastic.co/guide/en/logstash/current/multiple-pipelines.html

- pipeline.id: main
  path.config: "/etc/logstash/conf.d/*.conf"
  pipeline.workers: ${workers}
  pipeline.batch.size: 2000
  pipeline.batch.delay: 500
EOF
    systemctl daemon-reload
    systemctl enable --now logstash

    if [[ $? -eq 0 ]]; then
        echo -e "\e[1;32m logstash 部署成功 \e[0m"
    else
        echo -e "\e[1;31m logstash 部署失败，检查/etc/logstash/conf.d/nginx.conf配置文件 \e[0m"
        exit 1
    fi
}

# ----------------------------------------Logstash-exporter Installation / Logstash-exporter 安装----------------------------------------
function logstash_exporter_install() {
    # Download and setup logstash-exporter / 下载并设置logstash-exporter
    if [ ! -f /usr/bin/logstash-exporter ]; then
        wget -O /usr/bin/logstash-exporter https://github.com/kuskoman/logstash-exporter/releases/download/v1.7.0/logstash-exporter-linux
        chmod a+x /usr/bin/logstash-exporter
    fi

    # 使用systemd托管
    cat >/usr/lib/systemd/system/logstash-exporter.service <<EOF
Description=logstash-exporter.service
After=syslog.target
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/logstash-exporter
Restart=always
RestartSec=10
StartLimitInterval=100

[Install]
WantedBy=multi-user.target
EOF
    systemctl daemon-reload
    systemctl enable --now logstash-exporter.service

    if [[ $? -eq 0 ]]; then
        echo -e "\e[1;32m logstash-exporter 部署成功 \e[0m"
    else
        echo -e "\e[1;31m logstash-exporter 部署失败，检查/usr/lib/systemd/system/logstash-exporter.service配置文件 \e[0m"
        exit 1
    fi
}

# ----------------------------------------Log Cleanup Configuration / 日志清理配置----------------------------------------
function spuercdn_cron() {
    # Setup log rotation cron job / 设置日志轮转定时任务
    cat >/var/spool/cron/root <<EOF
0 0 */3 * * > /usr/local/nginx/logs/spuercdn.log
EOF
    crontab -l | grep -wq spuercdn.log

    if [[ $? -eq 0 ]]; then
        echo -e "\e[1;32m 日志清理配置成功 \e[0m"
    else
        echo -e "\e[1;31m 日志清理配置失败 \e[0m"
        exit 1
    fi
}

function Register_cdn() {
    curl --location 'https://www.agc.cloud/api/spuercdn/api/v1/node-init' \
        --header 'Content-Type: application/json' \
        --data "{
           \"ips\":[
              \"${1}\"
           ]
    }"
    sleep 15
}

# ----------------------------------------Main Function / 主函数----------------------------------------
function main() {
    check_os "${1}" "${2}"     # System check / 系统检查
    software_install           # Install required software / 安装必需软件
    disk_init                  # Initialize disk / 初始化磁盘
    hostname_config "${1}"     # Configure hostname / 配置主机名
    firewall_config            # Configure firewall / 配置防火墙
    NetworkYH                  # Configure network and time / 配置网络和时间
    kernel_optimize            # Optimize kernel parameters / 优化内核参数
    salt_install "${1}" "${2}" # Install salt / 安装salt
    young_agent_install        # Young Agent Installation / Young Agent 安装
    openresty_install          # OpenResty Installation / OpenResty 安装
    logstash_install           # Logstash Installation / Logstash 安装
    logstash_exporter_install  # Logstash-exporter Installation / Logstash-exporter 安装
    spuercdn_cron              # Log Cleanup Configuration / 日志清理配置
    Register_cdn "${1}"        # Register CDN Node / 注册CDN节点
}

main "${1}" "${2}"
[[ $? -eq 0 ]] && echo -e "\e[1;32m cdninstall 组件全部部署成功，正在重启系统，请稍后...... \e[0m" && reboot
