|
|
|
@@ -110,7 +110,7 @@ load_config() {
|
|
|
|
|
|
|
|
|
|
assert_command_dependencies() {
|
|
|
|
|
local cmd
|
|
|
|
|
for cmd in curl jq gpg wget rsync python3 psql runuser systemctl ss; do
|
|
|
|
|
for cmd in apt-get python3 runuser systemctl; do
|
|
|
|
|
command -v "${cmd}" >/dev/null 2>&1 || die "Comando obrigatorio ausente: ${cmd}"
|
|
|
|
|
done
|
|
|
|
|
}
|
|
|
|
@@ -118,9 +118,13 @@ assert_command_dependencies() {
|
|
|
|
|
assert_ports_available() {
|
|
|
|
|
local port
|
|
|
|
|
[[ "${DRY_RUN}" == "1" ]] && return 0
|
|
|
|
|
command -v ss >/dev/null 2>&1 || return 0
|
|
|
|
|
if [[ "${VFM_APP_PORT}" == "${ZABBIX_WEB_PORT}" || "${VFM_APP_PORT}" == "${GRAFANA_PORT}" || "${ZABBIX_WEB_PORT}" == "${GRAFANA_PORT}" ]]; then
|
|
|
|
|
die "As portas configuradas para V-Fire Monitor, Zabbix e Grafana precisam ser distintas."
|
|
|
|
|
fi
|
|
|
|
|
for port in "${VFM_APP_PORT}" "${ZABBIX_WEB_PORT}" "${GRAFANA_PORT}"; do
|
|
|
|
|
if ss -ltn "( sport = :${port} )" | tail -n +2 | grep -q .; then
|
|
|
|
|
die "Porta ${port} ja esta em uso."
|
|
|
|
|
log "Porta ${port} ja esta em uso. O instalador vai prosseguir para permitir reexecucoes e atualizacoes."
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
}
|
|
|
|
@@ -136,9 +140,9 @@ apt_install() {
|
|
|
|
|
write_zabbix_repo() {
|
|
|
|
|
run_cmd install -d -m 0755 /usr/share/keyrings
|
|
|
|
|
if [[ "${DRY_RUN}" == "1" ]]; then
|
|
|
|
|
printf '[dry-run] curl -fsSL https://repo.zabbix.com/zabbix-official-repo.key | gpg --dearmor -o %s\n' "${ZABBIX_APT_KEYRING}"
|
|
|
|
|
printf '[dry-run] curl -fsSL https://repo.zabbix.com/zabbix-official-repo.key | gpg --dearmor --yes -o %s\n' "${ZABBIX_APT_KEYRING}"
|
|
|
|
|
else
|
|
|
|
|
curl -fsSL "https://repo.zabbix.com/zabbix-official-repo.key" | gpg --dearmor -o "${ZABBIX_APT_KEYRING}"
|
|
|
|
|
curl -fsSL "https://repo.zabbix.com/zabbix-official-repo.key" | gpg --dearmor --yes -o "${ZABBIX_APT_KEYRING}"
|
|
|
|
|
fi
|
|
|
|
|
run_cmd chmod 0644 "${ZABBIX_APT_KEYRING}"
|
|
|
|
|
cat >"${ZABBIX_APT_LIST}" <<EOF
|
|
|
|
@@ -226,6 +230,7 @@ PORT=${VFM_APP_PORT}
|
|
|
|
|
VFM_TRUST_PROXY=0
|
|
|
|
|
VFM_SESSION_COOKIE_SECURE=0
|
|
|
|
|
VFM_WAITRESS_THREADS=8
|
|
|
|
|
VFM_ALLOW_LEGACY_LICENSE_KEY=${ALLOW_LEGACY_LICENSE_KEY}
|
|
|
|
|
${VFM_APP_SECRET:+VFM_APP_SECRET=${VFM_APP_SECRET}}
|
|
|
|
|
${VFM_LICENSE_MASTER_KEY:+VFM_LICENSE_MASTER_KEY=${VFM_LICENSE_MASTER_KEY}}
|
|
|
|
|
EOF
|
|
|
|
@@ -304,6 +309,28 @@ configure_zabbix() {
|
|
|
|
|
set_ini_value "/etc/zabbix/zabbix_server.conf" "DBUser" "${ZABBIX_DB_USER}"
|
|
|
|
|
set_ini_value "/etc/zabbix/zabbix_server.conf" "DBPassword" "${ZABBIX_DB_PASSWORD}"
|
|
|
|
|
|
|
|
|
|
run_cmd install -d -m 0750 /etc/zabbix/web
|
|
|
|
|
cat > /etc/zabbix/web/zabbix.conf.php <<EOF
|
|
|
|
|
<?php
|
|
|
|
|
// Zabbix GUI configuration file generated by V-Fire installer.
|
|
|
|
|
|
|
|
|
|
\$DB['TYPE'] = 'POSTGRESQL';
|
|
|
|
|
\$DB['SERVER'] = 'localhost';
|
|
|
|
|
\$DB['PORT'] = '0';
|
|
|
|
|
\$DB['DATABASE'] = '${ZABBIX_DB_NAME}';
|
|
|
|
|
\$DB['USER'] = '${ZABBIX_DB_USER}';
|
|
|
|
|
\$DB['PASSWORD'] = '${ZABBIX_DB_PASSWORD}';
|
|
|
|
|
\$DB['SCHEMA'] = '';
|
|
|
|
|
|
|
|
|
|
\$ZBX_SERVER = 'localhost';
|
|
|
|
|
\$ZBX_SERVER_PORT = '10051';
|
|
|
|
|
\$ZBX_SERVER_NAME = '${ZABBIX_MONITORED_HOST}';
|
|
|
|
|
|
|
|
|
|
\$IMAGE_FORMAT_DEFAULT = IMAGE_FORMAT_PNG;
|
|
|
|
|
EOF
|
|
|
|
|
run_cmd chown root:www-data /etc/zabbix/web/zabbix.conf.php
|
|
|
|
|
run_cmd chmod 0640 /etc/zabbix/web/zabbix.conf.php
|
|
|
|
|
|
|
|
|
|
if [[ -f /etc/zabbix/nginx.conf ]]; then
|
|
|
|
|
sed -i -E "s|^[[:space:]]*#[[:space:]]*listen[[:space:]]+8080;| listen ${ZABBIX_WEB_PORT};|" /etc/zabbix/nginx.conf
|
|
|
|
|
sed -i -E "s|^[[:space:]]*#[[:space:]]*server_name[[:space:]]+example.com;| server_name _;|" /etc/zabbix/nginx.conf
|
|
|
|
@@ -321,12 +348,13 @@ configure_grafana() {
|
|
|
|
|
run_cmd install -d -m 0755 /etc/grafana/provisioning/datasources
|
|
|
|
|
run_cmd install -d -m 0755 /etc/grafana/provisioning/dashboards
|
|
|
|
|
run_cmd install -d -m 0755 "${GRAFANA_DASHBOARD_DIR}"
|
|
|
|
|
run_cmd install -d -o grafana -g grafana -m 0755 /var/lib/grafana/plugins
|
|
|
|
|
|
|
|
|
|
if [[ "${GRAFANA_INSTALL_ZABBIX_PLUGIN}" == "1" ]]; then
|
|
|
|
|
if [[ "${DRY_RUN}" == "1" ]]; then
|
|
|
|
|
printf '[dry-run] grafana-cli plugins install alexanderzobnin-zabbix-app\n'
|
|
|
|
|
printf '[dry-run] grafana cli --homepath /usr/share/grafana --pluginsDir /var/lib/grafana/plugins plugins install alexanderzobnin-zabbix-app\n'
|
|
|
|
|
else
|
|
|
|
|
grafana-cli plugins install alexanderzobnin-zabbix-app || true
|
|
|
|
|
grafana cli --homepath /usr/share/grafana --pluginsDir /var/lib/grafana/plugins plugins install alexanderzobnin-zabbix-app || true
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
@@ -370,6 +398,7 @@ EOF
|
|
|
|
|
|
|
|
|
|
run_cmd cp "${APP_HOME}/dashboards/grafana/vfire-floorplan-starter.json" "${GRAFANA_DASHBOARD_DIR}/vfire-floorplan-starter.json"
|
|
|
|
|
run_cmd chown -R grafana:grafana "${GRAFANA_DASHBOARD_DIR}"
|
|
|
|
|
run_cmd chown -R grafana:grafana /var/lib/grafana/plugins
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
restart_core_services() {
|
|
|
|
@@ -403,8 +432,28 @@ wait_for_http() {
|
|
|
|
|
|
|
|
|
|
zabbix_api_request() {
|
|
|
|
|
local payload="$1"
|
|
|
|
|
local auth_token="${2:-}"
|
|
|
|
|
local curl_args=(-fsS -H 'Content-Type: application/json-rpc')
|
|
|
|
|
[[ "${DRY_RUN}" == "1" ]] && return 0
|
|
|
|
|
curl -fsS -H 'Content-Type: application/json-rpc' -d "${payload}" "http://127.0.0.1:${ZABBIX_WEB_PORT}/api_jsonrpc.php"
|
|
|
|
|
if [[ -n "${auth_token}" ]]; then
|
|
|
|
|
curl_args+=(-H "Authorization: Bearer ${auth_token}")
|
|
|
|
|
fi
|
|
|
|
|
curl "${curl_args[@]}" -d "${payload}" "http://127.0.0.1:${ZABBIX_WEB_PORT}/api_jsonrpc.php"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zabbix_error_message() {
|
|
|
|
|
local response="$1"
|
|
|
|
|
printf '%s' "${response}" | jq -r '.error.data // .error.message // empty'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zabbix_require_success() {
|
|
|
|
|
local response="$1"
|
|
|
|
|
local context="$2"
|
|
|
|
|
local error_message
|
|
|
|
|
error_message="$(zabbix_error_message "${response}")"
|
|
|
|
|
if [[ -n "${error_message}" ]]; then
|
|
|
|
|
die "${context}: ${error_message}"
|
|
|
|
|
fi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
configure_zabbix_admin_password() {
|
|
|
|
@@ -418,26 +467,26 @@ configure_zabbix_admin_password() {
|
|
|
|
|
user_id="$(printf '%s' "${auth_response}" | jq -r '.result.userid // empty')"
|
|
|
|
|
|
|
|
|
|
if [[ -n "${auth_token}" && -n "${user_id}" && "${ZABBIX_ADMIN_PASSWORD}" != "zabbix" ]]; then
|
|
|
|
|
zabbix_api_request "$(jq -cn \
|
|
|
|
|
--arg auth "${auth_token}" \
|
|
|
|
|
auth_response="$(zabbix_api_request "$(jq -cn \
|
|
|
|
|
--arg userid "${user_id}" \
|
|
|
|
|
--arg current "zabbix" \
|
|
|
|
|
--arg passwd "${ZABBIX_ADMIN_PASSWORD}" \
|
|
|
|
|
'{jsonrpc:"2.0",method:"user.update",params:{userid:$userid,current_passwd:$current,passwd:$passwd},auth:$auth,id:1}')" >/dev/null
|
|
|
|
|
zabbix_api_request "$(jq -cn --arg auth "${auth_token}" '{jsonrpc:"2.0",method:"user.logout",params:[],auth:$auth,id:1}')" >/dev/null || true
|
|
|
|
|
'{jsonrpc:"2.0",method:"user.update",params:{userid:$userid,current_passwd:$current,passwd:$passwd},id:1}')" "${auth_token}" || true)"
|
|
|
|
|
zabbix_require_success "${auth_response}" "Falha ao atualizar a senha administrativa do Zabbix"
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
auth_payload="$(jq -cn --arg username "${ZABBIX_ADMIN_USERNAME}" --arg password "${ZABBIX_ADMIN_PASSWORD}" '{jsonrpc:"2.0",method:"user.login",params:{username:$username,password:$password},id:1}')"
|
|
|
|
|
auth_response="$(zabbix_api_request "${auth_payload}" || true)"
|
|
|
|
|
zabbix_require_success "${auth_response}" "Falha ao autenticar na API do Zabbix com as credenciais administrativas configuradas"
|
|
|
|
|
auth_token="$(printf '%s' "${auth_response}" | jq -r '.result // empty')"
|
|
|
|
|
[[ -n "${auth_token}" ]] || die "Nao foi possivel autenticar na API do Zabbix com as credenciais administrativas configuradas."
|
|
|
|
|
zabbix_api_request "$(jq -cn --arg auth "${auth_token}" '{jsonrpc:"2.0",method:"user.logout",params:[],auth:$auth,id:1}')" >/dev/null || true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
zabbix_login() {
|
|
|
|
|
local response
|
|
|
|
|
response="$(zabbix_api_request "$(jq -cn --arg username "${ZABBIX_ADMIN_USERNAME}" --arg password "${ZABBIX_ADMIN_PASSWORD}" '{jsonrpc:"2.0",method:"user.login",params:{username:$username,password:$password},id:1}')")"
|
|
|
|
|
zabbix_require_success "${response}" "Falha ao obter token da API do Zabbix"
|
|
|
|
|
printf '%s' "${response}" | jq -r '.result // empty'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -451,8 +500,7 @@ zabbix_get_single_id() {
|
|
|
|
|
--arg method "${method}" \
|
|
|
|
|
--arg key "${filter_key}" \
|
|
|
|
|
--arg value "${filter_value}" \
|
|
|
|
|
--arg auth "${auth}" \
|
|
|
|
|
'{jsonrpc:"2.0",method:$method,params:{output:["'"${id_key}"'"],filter:{($key):[$value]}},auth:$auth,id:1}')" \
|
|
|
|
|
'{jsonrpc:"2.0",method:$method,params:{output:["'"${id_key}"'"],filter:{($key):[$value]}},id:1}')" "${auth}" \
|
|
|
|
|
| jq -r ".result[0].${id_key} // empty"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -462,9 +510,8 @@ import_zabbix_template() {
|
|
|
|
|
[[ -f "${ZABBIX_TEMPLATE_FILE}" ]] || die "Template do Zabbix nao encontrado: ${ZABBIX_TEMPLATE_FILE}"
|
|
|
|
|
source="$(cat "${ZABBIX_TEMPLATE_FILE}")"
|
|
|
|
|
zabbix_api_request "$(jq -cn \
|
|
|
|
|
--arg auth "${auth}" \
|
|
|
|
|
--arg source "${source}" \
|
|
|
|
|
'{jsonrpc:"2.0",method:"configuration.import",params:{format:"yaml",source:$source,rules:{template_groups:{createMissing:true,updateExisting:true},templates:{createMissing:true,updateExisting:true},discoveryRules:{createMissing:true,updateExisting:true,deleteMissing:false},items:{createMissing:true,updateExisting:true,deleteMissing:false},triggers:{createMissing:true,updateExisting:true,deleteMissing:false},valueMaps:{createMissing:true,updateExisting:true,deleteMissing:false},templateDashboards:{createMissing:true,updateExisting:true,deleteMissing:false}}},auth:$auth,id:1}')" >/dev/null
|
|
|
|
|
'{jsonrpc:"2.0",method:"configuration.import",params:{format:"yaml",source:$source,rules:{template_groups:{createMissing:true,updateExisting:true},templates:{createMissing:true,updateExisting:true},discoveryRules:{createMissing:true,updateExisting:true,deleteMissing:false},items:{createMissing:true,updateExisting:true,deleteMissing:false},triggers:{createMissing:true,updateExisting:true,deleteMissing:false},valueMaps:{createMissing:true,updateExisting:true,deleteMissing:false},templateDashboards:{createMissing:true,updateExisting:true,deleteMissing:false}}},id:1}')" "${auth}" >/dev/null
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ensure_zabbix_host_group() {
|
|
|
|
@@ -475,7 +522,7 @@ ensure_zabbix_host_group() {
|
|
|
|
|
printf '%s' "${group_id}"
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
zabbix_api_request "$(jq -cn --arg auth "${auth}" --arg name "${ZABBIX_HOST_GROUP}" '{jsonrpc:"2.0",method:"hostgroup.create",params:{name:$name},auth:$auth,id:1}')" | jq -r '.result.groupids[0]'
|
|
|
|
|
zabbix_api_request "$(jq -cn --arg name "${ZABBIX_HOST_GROUP}" '{jsonrpc:"2.0",method:"hostgroup.create",params:{name:$name},id:1}')" "${auth}" | jq -r '.result.groupids[0]'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ensure_zabbix_monitored_host() {
|
|
|
|
@@ -489,22 +536,20 @@ ensure_zabbix_monitored_host() {
|
|
|
|
|
host_id="$(zabbix_get_single_id "host.get" "host" "${ZABBIX_MONITORED_HOST}" "hostid" "${auth}")"
|
|
|
|
|
if [[ -n "${host_id}" ]]; then
|
|
|
|
|
zabbix_api_request "$(jq -cn \
|
|
|
|
|
--arg auth "${auth}" \
|
|
|
|
|
--arg hostid "${host_id}" \
|
|
|
|
|
--arg host "${ZABBIX_MONITORED_HOST}" \
|
|
|
|
|
--arg group_id "${group_id}" \
|
|
|
|
|
--arg template_id "${template_id}" \
|
|
|
|
|
'{jsonrpc:"2.0",method:"host.update",params:{hostid:$hostid,host:$host,name:$host,status:0,groups:[{groupid:$group_id}],templates:[{templateid:$template_id}]},auth:$auth,id:1}')" >/dev/null
|
|
|
|
|
'{jsonrpc:"2.0",method:"host.update",params:{hostid:$hostid,host:$host,name:$host,status:0,groups:[{groupid:$group_id}],templates:[{templateid:$template_id}]},id:1}')" "${auth}" >/dev/null
|
|
|
|
|
printf '%s' "${host_id}"
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
zabbix_api_request "$(jq -cn \
|
|
|
|
|
--arg auth "${auth}" \
|
|
|
|
|
--arg host "${ZABBIX_MONITORED_HOST}" \
|
|
|
|
|
--arg group_id "${group_id}" \
|
|
|
|
|
--arg template_id "${template_id}" \
|
|
|
|
|
'{jsonrpc:"2.0",method:"host.create",params:{host:$host,name:$host,status:0,groups:[{groupid:$group_id}],templates:[{templateid:$template_id}],tags:[{tag:"application",value:"vfire-monitor"}]},auth:$auth,id:1}')" | jq -r '.result.hostids[0]'
|
|
|
|
|
'{jsonrpc:"2.0",method:"host.create",params:{host:$host,name:$host,status:0,groups:[{groupid:$group_id}],templates:[{templateid:$template_id}],tags:[{tag:"application",value:"vfire-monitor"}]},id:1}')" "${auth}" | jq -r '.result.hostids[0]'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
seed_vfire_runtime_config() {
|
|
|
|
@@ -554,7 +599,6 @@ provision_zabbix_objects() {
|
|
|
|
|
[[ -n "${group_id}" ]] || die "Falha ao criar ou localizar host group do Zabbix."
|
|
|
|
|
host_id="$(ensure_zabbix_monitored_host "${auth}" "${group_id}")"
|
|
|
|
|
[[ -n "${host_id}" ]] || die "Falha ao criar ou localizar host monitorado do Zabbix."
|
|
|
|
|
zabbix_api_request "$(jq -cn --arg auth "${auth}" '{jsonrpc:"2.0",method:"user.logout",params:[],auth:$auth,id:1}')" >/dev/null || true
|
|
|
|
|
seed_vfire_runtime_config
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|