#!/bin/bash -e

distro=$1
dist=$2
apacheuser=$3
apachegroup=$4
nagiosuser=$5
nagiosgroup=$6
opensearchpass=$7
proddir=$8

if [ $# -ge 11 ]; then
    ADDING_NODE=$9
    shift 9
    MANAGER_BASE_URL=$1
    NODE_NAME=$2
    API_TOKEN=$3
fi

if [ -z $NODE_NAME ]; then
    NODE_NAME=`hostname --fqdn`
fi

SELF_IP=$(hostname -I | cut -d ' ' -f 1)

pkgname="opensearch-3.1.0"
pkgarch="linux-x64"

echo "Installing OpenSearch..."

# Delete the old archive
rm -rf "$pkgname"

# Extract archive
tar -xzf "$pkgname-$pkgarch.tar.gz"

update_config_file() {
    configdir=$1
    configfile=$2
    # Before running this script, make sure to replace the /path/to your OpenSearch directory,
    # and remember to replace the CN in the node's distinguished name with a real
    # DNS A record.

    echo "plugins.security.ssl.transport.pemcert_filepath: $NODE_NAME.pem" | sudo tee -a $configdir/$configfile
    echo "plugins.security.ssl.transport.pemkey_filepath: $NODE_NAME-key.pem" | sudo tee -a $configdir/$configfile
    echo "plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem" | sudo tee -a $configdir/$configfile
    echo "plugins.security.ssl.http.enabled: true" | sudo tee -a $configfile
    echo "plugins.security.ssl.http.pemcert_filepath: $NODE_NAME.pem" | sudo tee -a $configdir/$configfile
    echo "plugins.security.ssl.http.pemkey_filepath: $NODE_NAME-key.pem" | sudo tee -a $configdir/$configfile
    echo "plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem" | sudo tee -a $configdir/$configfile
    echo "plugins.security.allow_default_init_securityindex: true" | sudo tee -a $configdir/$configfile
    echo "plugins.security.authcz.admin_dn:" | sudo tee -a $configdir/$configfile
    echo "  - 'CN=nagioslogserver,OU=NAGIOSLOGSERVER-ADMIN,O=ORG'" | sudo tee -a $configdir/$configfile
    echo "plugins.security.nodes_dn:" | sudo tee -a $configdir/$configfile
    echo "  - 'CN=*,OU=NAGIOSLOGSERVER,O=ORG'" | sudo tee -a $configdir/$configfile
    echo "plugins.security.audit.type: internal_opensearch" | sudo tee -a $configdir/$configfile
    echo "plugins.security.enable_snapshot_restore_privilege: true" | sudo tee -a $configdir/$configfile
    echo "plugins.security.check_snapshot_restore_write_privileges: true" | sudo tee -a $configdir/$configfile
    echo "plugins.security.restapi.roles_enabled: [\"all_access\", \"security_rest_api_access\"]" | sudo tee -a $configdir/$configfile
    echo "path.repo: [\"/usr/local/nagioslogserver/opensearch/snapshots\"]" | sudo tee -a $configdir/$configfile
}

configure_manager_ssl() {
    # Confiugure SSL on the manager system

    # Adapted from https://opensearch.org/docs/2.14/install-and-configure/install-opensearch/tar/
    cd /usr/local/nagioslogserver/opensearch/config

    # Root certificate setup

    # Create private key for root certificate
    openssl genrsa -out root-ca-key.pem 2048
    # Create a self-signed root cert
    openssl req -new -x509 -sha256 -key root-ca-key.pem -subj "/O=ORG/OU=NAGIOSLOGSERVER/CN=ROOT" -out root-ca.pem -days 36500

    # User certificate setup

    # Create nagioslogserver cert private key
    openssl genrsa -out nagioslogserver-key-temp.pem 2048
    # Convert key to PKCS#8
    openssl pkcs8 -inform PEM -outform PEM -in nagioslogserver-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out nagioslogserver-key.pem
    # Create CSR
    openssl req -new -key nagioslogserver-key.pem -subj "/O=ORG/OU=NAGIOSLOGSERVER-ADMIN/CN=nagioslogserver" -out nagioslogserver.csr
    # Sign the cert
    openssl x509 -req -in nagioslogserver.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out nagioslogserver.pem -days 36500

    # Give appropriate permissions so that the api can send it to another cluster node
    chmod g+r nagioslogserver-key.pem root-ca-key.pem
    if [ -f root-ca.srl ]; then
        chmod g+rw root-ca.srl
    fi

    # Node certificate setup

    # Create Node private key
    openssl genrsa -out $NODE_NAME-key-temp.pem 2048

    # Convert the private key to PKCS#8.
    openssl pkcs8 -inform PEM -outform PEM -in $NODE_NAME-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out $NODE_NAME-key.pem
   
    # Create the CSR and replace the arguments passed to -subj so they reflect your specific host.
    # The CN should match a DNS A record for the host--do not use the hostname.
    openssl req -new -key $NODE_NAME-key.pem -subj "/O=ORG/OU=NAGIOSLOGSERVER/CN=$NODE_NAME" -out $NODE_NAME.csr
   
    # Create an extension file that defines a SAN DNS name for the host. This
    # should match the DNS A record of the host.
    althosts=`ip addr | grep inet | grep -v inet6 | sed 's/.*inet //g' | sed 's/\/.*//g' | grep -v ^127`
    ALTNAME=subjectAltName=DNS:localhost
    for althost in $althosts
    do 
        ALTNAME="$ALTNAME,IP:$althost" 
    done
    ALTNAME="$ALTNAME,DNS:$NODE_NAME"
    echo $ALTNAME > $NODE_NAME.ext

    # Sign the node certificate with the root certificate and private key that you created earlier.
    openssl x509 -req -in $NODE_NAME.csr -CA root-ca.pem -CAkey root-ca-key.pem -CAcreateserial -sha256 -out $NODE_NAME.pem -days 36500 -extfile $NODE_NAME.ext

    # Cleanup
    rm *temp.pem *csr *ext

    # Add the config files:
    update_config_file "/usr/local/nagioslogserver/opensearch/config" "opensearch.yml"
    update_config_file "/usr/local/nagioslogserver/opensearch/config" "opensearch-worker.yml"

    sed -i "s/\$config\['opensearch_password'\].*/\$config['opensearch_password'] = '$opensearchpass';/" ./opensearch_config.php

	# Generate hash of the password.
    nlspasshash=`OPENSEARCH_JAVA_HOME=/usr/local/nagioslogserver/opensearch/jdk/ /usr/local/nagioslogserver/opensearch/plugins/opensearch-security/tools/hash.sh -p $opensearchpass 2>&1 | grep -v '\*'`
    while [[ $nlspasshash == *"/"* ]];
    do
        nlspasshash=`OPENSEARCH_JAVA_HOME=/usr/local/nagioslogserver/opensearch/jdk/ /usr/local/nagioslogserver/opensearch/plugins/opensearch-security/tools/hash.sh -p $opensearchpass 2>&1 | grep -v '\*'`
    done

    sed -i "s/hash: .*/hash: \"$nlspasshash\"/" /usr/local/nagioslogserver/opensearch/config/opensearch-security/internal_users.yml

    chown $nagiosuser:$nagiosgroup /usr/local/nagioslogserver/opensearch/config/*

    echo "Restarting OpenSearch Service"

    systemctl restart opensearch.service

    # Apply securityadmin changes
    cd /usr/local/nagioslogserver/opensearch/plugins/opensearch-security/tools
    OPENSEARCH_JAVA_HOME=/usr/local/nagioslogserver/opensearch/jdk ./securityadmin.sh -cd /usr/local/nagioslogserver/opensearch/config/opensearch-security/ -cacert /usr/local/nagioslogserver/opensearch/config/root-ca.pem -cert /usr/local/nagioslogserver/opensearch/config/nagioslogserver.pem -key /usr/local/nagioslogserver/opensearch/config/nagioslogserver-key.pem -icl -nhnv
}

configure_node_ssl() {
    # Confiugure SSL on the node system

    # Adapted from https://opensearch.org/docs/2.14/install-and-configure/install-opensearch/tar/
    cd /usr/local/nagioslogserver/opensearch/config

    # Retrieve user certificates from manager:

    # Get CA Certificate
    curl $MANAGER_BASE_URL/api/system/get_opensearch_ca_cert?token=${API_TOKEN} -o /usr/local/nagioslogserver/opensearch/config/root-ca.pem
    curl $MANAGER_BASE_URL/api/system/get_opensearch_ca_key?token=${API_TOKEN} -o /usr/local/nagioslogserver/opensearch/config/root-ca-key.pem

    # User key and cert:
    curl $MANAGER_BASE_URL/api/system/get_opensearch_user_cert?token=${API_TOKEN} -o /usr/local/nagioslogserver/opensearch/config/nagioslogserver.pem
    curl $MANAGER_BASE_URL/api/system/get_opensearch_user_key?token=${API_TOKEN} -o /usr/local/nagioslogserver/opensearch/config/nagioslogserver-key.pem

    # Create Node private key
    openssl genrsa -out $NODE_NAME-key-temp.pem 2048

    # Convert the private key to PKCS#8.
    openssl pkcs8 -inform PEM -outform PEM -in $NODE_NAME-key-temp.pem -topk8 -nocrypt -v1 PBE-SHA1-3DES -out $NODE_NAME-key.pem
   
    # Create the CSR and replace the arguments passed to -subj so they reflect your specific host.
    # The CN should match a DNS A record for the host--do not use the hostname.
    openssl req -new -key $NODE_NAME-key.pem -subj "/O=ORG/OU=NAGIOSLOGSERVER/CN=$NODE_NAME" -out $NODE_NAME.csr
   
    # Create an extension file that defines a SAN DNS name for the host. This
    # should match the DNS A record of the host.
    althosts=`ip addr | grep inet | grep -v inet6 | sed 's/.*inet //g' | sed 's/\/.*//g' | grep -v ^127`
    ALTNAME=subjectAltName=DNS:localhost
    for althost in $althosts
    do 
        ALTNAME="$ALTNAME,IP:$althost" 
    done
    ALTNAME="$ALTNAME,DNS:$NODE_NAME"
    echo $ALTNAME > $NODE_NAME.ext

    # Sign the cert
    curl -X POST -F "csr=@${NODE_NAME}.csr" -F "ext=@${NODE_NAME}.ext" ${MANAGER_BASE_URL}/api/system/sign_node_cert?token=${API_TOKEN} > $NODE_NAME.pem

    # Cleanup
    rm *temp.pem *csr *ext

    # Add the config files:
    update_config_file "/usr/local/nagioslogserver/opensearch/config" "opensearch.yml"
    update_config_file "/usr/local/nagioslogserver/opensearch/config" "opensearch-worker.yml"

    # Retrieve the nagioslogserver user password from the manager node

    opensearchpassline=`curl ${MANAGER_BASE_URL}/api/system/get_opensearch_local_config?token=${API_TOKEN} | grep opensearch_password`

    sed -i "s/\$config\['opensearch_password'\].*//" ./opensearch_config.php
    echo $opensearchpassline >> ./opensearch_config.php

    curl ${MANAGER_BASE_URL}/api/system/get_internal_users?token=${API_TOKEN} -o /usr/local/nagioslogserver/opensearch/config/opensearch-security/internal_users.yml

    chown $nagiosuser:$nagiosgroup /usr/local/nagioslogserver/opensearch/config/*

    echo "Restarting OpenSearch Service"

    systemctl restart opensearch.service

    touch /var/www/html/nagioslogserver/application/cache/installed
}

# Make and install 
(
    mkdir -p /usr/local/nagioslogserver/opensearch /var/log/opensearch /var/run/opensearch /usr/local/nagioslogserver/opensearch/snapshots
    chown nagios:nagios /usr/local/nagioslogserver/opensearch/snapshots
    
    cp -r $pkgname/* /usr/local/nagioslogserver/opensearch

    if [ "$distro" == "Debian" ] || [ "$distro" == "Ubuntu" ]; then
        cp mods/etc/init.d/opensearch.deb.init /etc/init.d/opensearch
    else
        cp mods/etc/init.d/opensearch.init /etc/init.d/opensearch
    fi

    # In Ubuntu/Debian there is no sysconfig folder, instead they are put in defaults 
    if [ -d "/etc/sysconfig" ]; then
        cp -r mods/etc/sysconfig/* /etc/sysconfig
    else
        cp -r mods/etc/sysconfig/* /etc/default
    fi

    if [ -d "/usr/lib/systemd" ] ; then
        cp -pr mods/etc/systemd/* /usr/lib/systemd
    fi

    sysctl -w vm.max_map_count=262144
    echo vm.max_map_count=262144 >> /etc/sysctl.conf

    MANAGER_IP=`printf "${MANAGER_BASE_URL}" | sed -z 's/^.*:\/\///' | sed 's/\/.*$//'`

    sed -i "s/NODE_NAME/$NODE_NAME/g" mods/opensearch/config/*.yml
    sed -i "s/SELF_IP/$SELF_IP/g" mods/opensearch/config/*.yml
    sed -i "s/MANAGER_IP/$MANAGER_IP/g" mods/opensearch/config/*.yml
    cp -r mods/opensearch/* /usr/local/nagioslogserver/opensearch
    if [ "x$ADDING_NODE" = "xtrue" ]; then
        cp mods/opensearch/config/opensearch-worker.yml /usr/local/nagioslogserver/opensearch/config/opensearch.yml
    fi
    cp mods/opensearch/config/opensearch_config.php /usr/local/nagioslogserver/opensearch/config
    cp -r mods/etc/systemd/opensearch.service  /usr/lib/systemd/system
    systemctl daemon-reload
    cp mods/opensearch/bin/opensearch-env /usr/local/nagioslogserver/opensearch/bin
    chown -R $nagiosuser:$nagiosgroup /usr/local/nagioslogserver/opensearch /var/log/opensearch /var/run/opensearch
    chmod +x /etc/init.d/opensearch /usr/local/nagioslogserver/opensearch/bin/opensearch  /usr/local/nagioslogserver/opensearch/plugins/opensearch-security/tools/*.sh

    systemctl enable opensearch
)

CURRENT_DIR=`pwd`

if [ -z "$MANAGER_BASE_URL" ]; then
    configure_manager_ssl
else
    configure_node_ssl
fi

# Update the discovery type for an automatic multi-node cluster
sed -i 's/^discovery\.type/#discovery.type/g' /usr/local/nagioslogserver/opensearch/config/opensearch.yml
chmod 664 /usr/local/nagioslogserver/opensearch/config/opensearch.yml

cd $CURRENT_DIR

systemctl restart opensearch

# Post-install modifications
./post-install

# Do a simple sanity check to make sure some key files exist...
for f in /usr/local/nagioslogserver/opensearch/bin/opensearch /usr/local/nagioslogserver/opensearch/config/opensearch.yml ; do
    if [ ! -f "$f" ]; then
        echo "ERROR: OpenSearch install appears to have failed - exiting.  Missing file = $f"
        exit 1
    fi
done

# Things are okay
echo "OpenSearch installed OK"
