/*
* Copyright 2014 by SCSK Corporation.
*
* This file is part of PrimeCloud Controller(TM).
*
* PrimeCloud Controller(TM) is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* PrimeCloud Controller(TM) is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PrimeCloud Controller(TM). If not, see <http://www.gnu.org/licenses/>.
*/
package jp.primecloud.auto.process.zabbix;
import java.util.ArrayList;
import java.util.List;
import jp.primecloud.auto.common.constant.PCCConstant;
import jp.primecloud.auto.common.status.ZabbixInstanceStatus;
import jp.primecloud.auto.config.Config;
import jp.primecloud.auto.entity.crud.Component;
import jp.primecloud.auto.entity.crud.ComponentInstance;
import jp.primecloud.auto.entity.crud.ComponentType;
import jp.primecloud.auto.entity.crud.Farm;
import jp.primecloud.auto.entity.crud.Image;
import jp.primecloud.auto.entity.crud.Instance;
import jp.primecloud.auto.entity.crud.Platform;
import jp.primecloud.auto.entity.crud.User;
import jp.primecloud.auto.entity.crud.ZabbixInstance;
import jp.primecloud.auto.exception.AutoException;
import jp.primecloud.auto.process.ProcessLogger;
import jp.primecloud.auto.service.ServiceSupport;
import jp.primecloud.auto.util.MessageUtils;
import jp.primecloud.auto.zabbix.model.hostgroup.Hostgroup;
import jp.primecloud.auto.zabbix.model.proxy.Proxy;
import jp.primecloud.auto.zabbix.model.template.Template;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
/**
* <p>
* TODO: クラスコメントを記述
* </p>
*
*/
public class ZabbixHostProcess extends ServiceSupport {
protected ZabbixProcessClientFactory zabbixProcessClientFactory;
protected ProcessLogger processLogger;
public void startHost(Long instanceNo) {
ZabbixInstance zabbixInstance = zabbixInstanceDao.read(instanceNo);
if (zabbixInstance == null) {
// Zabbix監視対象でない
throw new AutoException("EPROCESS-000401", instanceNo);
}
Instance instance = instanceDao.read(instanceNo);
Platform platform = platformDao.read(instance.getPlatformNo());
// ログ出力
if (log.isInfoEnabled()) {
log.info(MessageUtils.getMessage("IPROCESS-100301", instanceNo, instance.getInstanceName()));
}
ZabbixProcessClient zabbixProcessClient = zabbixProcessClientFactory.createZabbixProcessClient();
String hostid = zabbixInstance.getHostid();
//ホスト名取得
String hostname = getHostName(instance.getFqdn());
//IP/DNS使用フラグ取得
Boolean useIp = BooleanUtils.toBooleanObject(Config.getProperty("zabbix.useIp"));
//ZabbixプロキシID取得
String proxyHostid = getProxyHostid(zabbixProcessClient);
//IP設定
String zabbixListenIp = getZabbixListenIp(zabbixProcessClient, instance, platform);
if (StringUtils.isEmpty(hostid)) {
List<Hostgroup> hostgroups = getInitHostgroups(zabbixProcessClient, instance);
// 監視対象の登録
hostid = zabbixProcessClient.createHost(hostname, instance.getFqdn(), hostgroups, true, useIp, zabbixListenIp, proxyHostid);
// イベントログ出力
processLogger.debug(null,instance, "ZabbixRegist", new Object[] {instance.getFqdn(), hostid });
// データベースの更新
zabbixInstance.setHostid(hostid);
zabbixInstance.setStatus(ZabbixInstanceStatus.MONITORING.toString());
zabbixInstanceDao.update(zabbixInstance);
} else {
// 監視対象の更新
zabbixProcessClient.updateHost(hostid, hostname, instance.getFqdn(), null, true, useIp, zabbixListenIp, proxyHostid);
// データベースの更新
zabbixInstance.setStatus(ZabbixInstanceStatus.MONITORING.toString());
zabbixInstanceDao.update(zabbixInstance);
// イベントログ出力
processLogger.debug(null,instance, "ZabbixStart", new Object[] {instance.getFqdn(), hostid });
}
// 標準テンプレートの適用
Image image = imageDao.read(instance.getImageNo());
String templateNames = image.getZabbixTemplate();
if (StringUtils.isEmpty(templateNames)) {
// TODO: 互換性のためプロパティファイルから取得する方法を残している
templateNames = Config.getProperty("zabbix.basetemplate");
}
if (StringUtils.isNotEmpty(templateNames)) {
for (String templateName : templateNames.split(",")) {
Template template = zabbixProcessClient.getTemplateByName(templateName);
boolean ret = zabbixProcessClient.addTemplate(hostid, template);
if (ret) {
// イベントログ出力
processLogger.debug(null,instance, "ZabbixTemplateAdd", new Object[] {instance.getFqdn(), templateName });
}
}
}
// ログ出力
if (log.isInfoEnabled()) {
log.info(MessageUtils.getMessage("IPROCESS-100302", instanceNo, instance.getInstanceName()));
}
}
public void stopHost(Long instanceNo) {
ZabbixInstance zabbixInstance = zabbixInstanceDao.read(instanceNo);
if (zabbixInstance == null) {
// Zabbix監視対象でない
throw new AutoException("EPROCESS-000401", instanceNo);
}
if (StringUtils.isEmpty(zabbixInstance.getHostid())) {
// 監視登録されていない場合はスキップ
return;
}
Instance instance = instanceDao.read(instanceNo);
// ログ出力
if (log.isInfoEnabled()) {
log.info(MessageUtils.getMessage("IPROCESS-100303", instanceNo, instance.getInstanceName()));
}
ZabbixProcessClient zabbixProcessClient = zabbixProcessClientFactory.createZabbixProcessClient();
// 監視対象の無効化
try {
//ホスト名取得
String hostname = getHostName(instance.getFqdn());
//IP/DNS使用フラグ取得
Boolean useIp = BooleanUtils.toBooleanObject(Config.getProperty("zabbix.useIp"));
//ZabbixプロキシID取得
String proxyHostid = getProxyHostid(zabbixProcessClient);
zabbixProcessClient.updateHost(zabbixInstance.getHostid(), hostname, instance.getFqdn(), null, false, useIp, null, proxyHostid);
// イベントログ出力
processLogger.debug(null,instance, "ZabbixStop", new Object[] {instance.getFqdn(), zabbixInstance.getHostid() });
// データベースの更新
zabbixInstance.setStatus(ZabbixInstanceStatus.UN_MONITORING.toString());
zabbixInstanceDao.update(zabbixInstance);
} catch (AutoException ignore) {
// 処理に失敗した場合、警告ログを出力する
log.warn(ignore.getMessage());
}
// ログ出力
if (log.isInfoEnabled()) {
log.info(MessageUtils.getMessage("IPROCESS-100304", instanceNo, instance.getInstanceName()));
}
}
public void startTemplate(Long instanceNo, Long componentNo) {
ZabbixInstance zabbixInstance = zabbixInstanceDao.read(instanceNo);
if (zabbixInstance == null) {
// Zabbix監視対象でない
throw new AutoException("EPROCESS-000401", instanceNo);
}
if (StringUtils.isEmpty(zabbixInstance.getHostid())) {
// 監視登録されていない場合
throw new AutoException("EPROCESS-000404", instanceNo);
}
Instance instance = instanceDao.read(instanceNo);
// ログ出力
if (log.isInfoEnabled()) {
log.info(MessageUtils.getMessage("IPROCESS-100305", instanceNo, instance.getInstanceName()));
}
Component component = componentDao.read(componentNo);
ZabbixProcessClient zabbixProcessClient = zabbixProcessClientFactory.createZabbixProcessClient();
// ホストグループを更新する
startTemplateHostgroup(zabbixProcessClient, instance, component, zabbixInstance.getHostid());
// テンプレートの設定
ComponentType componentType = componentTypeDao.read(component.getComponentTypeNo());
String templateNames = componentType.getZabbixTemplate();
if (StringUtils.isNotEmpty(templateNames)) {
for (String templateName : templateNames.split(",")) {
// テンプレートを取得
Template template = zabbixProcessClient.getTemplateByName(templateName);
// テンプレートを適用
boolean ret = zabbixProcessClient.addTemplate(zabbixInstance.getHostid(), template);
if (ret) {
// イベントログ出力
processLogger.debug(component, instance, "ZabbixTemplateAdd", new Object[] { instance.getFqdn(), templateName });
}
// ホストに紐づくアイテムを有効化
boolean ret2 = zabbixProcessClient.enableItems(zabbixInstance.getHostid(), template.getTemplateid());
if (ret2) {
// イベントログ出力
processLogger.debug(component, instance, "ZabbixItemEnable", new Object[] { instance.getFqdn(), templateName });
}
}
}
// ログ出力
if (log.isInfoEnabled()) {
log.info(MessageUtils.getMessage("IPROCESS-100306", instanceNo, instance.getInstanceName()));
}
}
public void stopTemplate(Long instanceNo, Long componentNo) {
ZabbixInstance zabbixInstance = zabbixInstanceDao.read(instanceNo);
if (zabbixInstance == null) {
// Zabbix監視対象でない
throw new AutoException("EPROCESS-000401", instanceNo);
}
if (StringUtils.isEmpty(zabbixInstance.getHostid())) {
// 監視登録されていない場合は何もしない
return;
}
Component component = componentDao.read(componentNo);
ComponentType componentType = componentTypeDao.read(component.getComponentTypeNo());
String templateNames = componentType.getZabbixTemplate();
if (StringUtils.isEmpty(templateNames)) {
// テンプレートが登録されていない場合はなにもしない。
return;
}
Instance instance = instanceDao.read(instanceNo);
// ログ出力
if (log.isInfoEnabled()) {
log.info(MessageUtils.getMessage("IPROCESS-100305", instanceNo, instance.getInstanceName()));
}
ZabbixProcessClient zabbixProcessClient = zabbixProcessClientFactory.createZabbixProcessClient();
for (String templateName : templateNames.split(",")) {
// テンプレートを取得
Template template = zabbixProcessClient.getTemplateByName(templateName);
// ホストに紐づくアイテムを無効化
boolean ret = zabbixProcessClient.disableItems(zabbixInstance.getHostid(), template.getTemplateid());
if (ret) {
// イベントログ出力
processLogger.debug(component, instance, "ZabbixItemDisable", new Object[] { instance.getFqdn(), templateName });
}
}
// ログ出力
if (log.isInfoEnabled()) {
log.info(MessageUtils.getMessage("IPROCESS-100306", instanceNo, instance.getInstanceName()));
}
}
public void removeTemplate(Long instanceNo, Long componentNo) {
ZabbixInstance zabbixInstance = zabbixInstanceDao.read(instanceNo);
if (zabbixInstance == null) {
// Zabbix監視対象でない
throw new AutoException("EPROCESS-000401", instanceNo);
}
if (StringUtils.isEmpty(zabbixInstance.getHostid())) {
// 監視登録されていない場合は何もしない
return;
}
Component component = componentDao.read(componentNo);
ComponentType componentType = componentTypeDao.read(component.getComponentTypeNo());
String templateNames = componentType.getZabbixTemplate();
if (StringUtils.isEmpty(templateNames)) {
// テンプレートが設定されていない場合はスキップ
return;
}
Instance instance = instanceDao.read(instanceNo);
// ログ出力
if (log.isInfoEnabled()) {
log.info(MessageUtils.getMessage("IPROCESS-100305", instanceNo, instance.getInstanceName()));
}
ZabbixProcessClient zabbixProcessClient = zabbixProcessClientFactory.createZabbixProcessClient();
for (String templateName : templateNames.split(",")) {
// テンプレートを取得
Template template = zabbixProcessClient.getTemplateByName(templateName);
// テンプレートを除去
boolean ret = zabbixProcessClient.removeTemplate(zabbixInstance.getHostid(), template);
if (ret) {
// イベントログ出力
processLogger.debug(component, instance, "ZabbixTemplateRemove", new Object[] { instance.getFqdn(), templateName });
}
// アイテムを削除
boolean ret2 = zabbixProcessClient.deleteItems(zabbixInstance.getHostid(), template.getTemplateid());
if (ret2) {
// イベントログ出力
processLogger.debug(component, instance, "ZabbixItemDelete", new Object[] { instance.getFqdn(), templateName });
}
}
// ホストグループを更新する
removeTemplateHostgroup(zabbixProcessClient, instance, component, zabbixInstance.getHostid());
// ログ出力
if (log.isInfoEnabled()) {
log.info(MessageUtils.getMessage("IPROCESS-100306", instanceNo, instance.getInstanceName()));
}
}
public void createComponentHostgroup(Long componentNo) {
Component component = componentDao.read(componentNo);
Farm farm = farmDao.read(component.getFarmNo());
User user = userDao.read(farm.getUserNo());
String hostgroupName = getHostgroupName(user, farm, component);
ZabbixProcessClient zabbixProcessClient = zabbixProcessClientFactory.createZabbixProcessClient();
Hostgroup hostgroup = zabbixProcessClient.getHostgroupByName(hostgroupName);
if (hostgroup != null) {
// すでにホストグループが作られている場合は何もしない
return;
}
zabbixProcessClient.createHostgroup(hostgroupName);
}
public void createFarmHostgroup(Long farmNo) {
Farm farm = farmDao.read(farmNo);
User user = userDao.read(farm.getUserNo());
String hostgroupName = getHostgroupName(user, farm);
ZabbixProcessClient zabbixProcessClient = zabbixProcessClientFactory.createZabbixProcessClient();
Hostgroup hostgroup = zabbixProcessClient.getHostgroupByName(hostgroupName);
if (hostgroup != null) {
// すでにホストグループが作られている場合は何もしない
return;
}
zabbixProcessClient.createHostgroup(hostgroupName);
}
public void deleteFarmHostgroup(Long farmNo) {
Farm farm = farmDao.read(farmNo);
User user = userDao.read(farm.getUserNo());
String hostgroupName = user.getUsername() + "_" + farm.getFarmName();
ZabbixProcessClient zabbixProcessClient = zabbixProcessClientFactory.createZabbixProcessClient();
Hostgroup hostgroup = zabbixProcessClient.getHostgroupByName(hostgroupName);
if (hostgroup != null) {
// ホストグループがあれば削除する
zabbixProcessClient.deleteHostgroup(hostgroup.getGroupid(), hostgroupName);
}
// コンポーネントごとのホストグループを削除
String prefix = hostgroupName + "_";
List<Hostgroup> hostgroups = zabbixProcessClient.getHostgroups();
for (Hostgroup hostgroup2 : hostgroups) {
if (StringUtils.startsWith(hostgroup2.getName(), prefix)) {
zabbixProcessClient.deleteHostgroup(hostgroup2.getGroupid(), hostgroup2.getName());
}
}
}
protected String getHostgroupName(User user) {
return getHostgroupName(user, null);
}
protected String getHostgroupName(User user, Farm farm) {
return getHostgroupName(user, farm, null);
}
protected String getHostgroupName(User user, Farm farm, Component component) {
String delimiter = "_";
StringBuilder sb = new StringBuilder();
sb.append(user.getUsername());
if (farm != null) {
sb.append(delimiter);
sb.append(farm.getFarmName());
}
if (component != null) {
sb.append(delimiter);
sb.append(component.getComponentName());
}
// 64文字でカットする
// TODO: Zabbixの制限による暫定対応
if (sb.length() <= 64) {
return sb.toString();
} else {
return sb.substring(0, 64);
}
}
protected List<Hostgroup> getInitHostgroups(ZabbixProcessClient zabbixProcessClient, Instance instance) {
Farm farm = farmDao.read(instance.getFarmNo());
User user = userDao.read(farm.getUserNo());
List<Hostgroup> hostgroups = new ArrayList<Hostgroup>();
// ユーザごとのホストグループ
String hostgroupName = getHostgroupName(user);
Hostgroup hostgroup = zabbixProcessClient.getHostgroupByName(hostgroupName);
if (hostgroup != null) {
hostgroups.add(hostgroup);
}
// ファームごとのホストグループ
String hostgroupName2 = getHostgroupName(user, farm);
Hostgroup hostgroup2 = zabbixProcessClient.getHostgroupByName(hostgroupName2);
if (hostgroup2 != null) {
hostgroups.add(hostgroup2);
}
return hostgroups;
}
protected void startTemplateHostgroup(ZabbixProcessClient zabbixProcessClient, Instance instance,
Component component, String hostid) {
// ホストが含まれるホストグループを取得
List<Hostgroup> hostgroups = zabbixProcessClient.getHostgroupsByHostid(hostid);
List<String> groupids = new ArrayList<String>();
for (Hostgroup hostgroup : hostgroups) {
groupids.add(hostgroup.getGroupid());
}
// コンポーネントごとのホストグループを取得
Farm farm = farmDao.read(instance.getFarmNo());
User user = userDao.read(farm.getUserNo());
Platform platform = platformDao.read(instance.getPlatformNo());
String hostgroupName = getHostgroupName(user, farm, component);
Hostgroup hostgroup = zabbixProcessClient.getHostgroupByName(hostgroupName);
// ホストがホストグループに含まれない場合、ホストグループに含める
if (hostgroup != null && !groupids.contains(hostgroup.getGroupid())) {
hostgroups.add(hostgroup);
//ホスト名取得
String hostname = getHostName(instance.getFqdn());
//IP/DNS使用フラグ取得
Boolean useIp = BooleanUtils.toBooleanObject(Config.getProperty("zabbix.useIp"));
//ZabbixプロキシID取得
String proxyHostid = getProxyHostid(zabbixProcessClient);
//IP設定
String zabbixListenIp = getZabbixListenIp(zabbixProcessClient, instance, platform);
zabbixProcessClient.updateHost(hostid, hostname, instance.getFqdn(), hostgroups, null, useIp, zabbixListenIp, proxyHostid);
}
}
protected void removeTemplateHostgroup(ZabbixProcessClient zabbixProcessClient, Instance instance,
Component component, String hostid) {
// ホストが含まれるホストグループを取得
List<Hostgroup> hostgroups = zabbixProcessClient.getHostgroupsByHostid(hostid);
List<String> groupids = new ArrayList<String>();
for (Hostgroup hostgroup : hostgroups) {
groupids.add(hostgroup.getGroupid());
}
// コンポーネントごとのホストグループ名
Farm farm = farmDao.read(instance.getFarmNo());
User user = userDao.read(farm.getUserNo());
Platform platform = platformDao.read(instance.getPlatformNo());
String hostgroupName = getHostgroupName(user, farm, component);
// 対象のインスタンスに関連付けられたコンポーネントの中に、同名のホストグループになるものがあればスキップする
// TODO: ホストグループ名の最大長が64文字であるZabbixの制限に伴う暫定対応
List<ComponentInstance> componentInstances = componentInstanceDao.readByInstanceNo(instance.getInstanceNo());
for (ComponentInstance componentInstance : componentInstances) {
if (component.getComponentNo().equals(componentInstance.getComponentNo())) {
continue;
}
Component component2 = componentDao.read(componentInstance.getComponentNo());
String hostgroupName2 = getHostgroupName(user, farm, component2);
if (StringUtils.equals(hostgroupName, hostgroupName2)) {
return;
}
}
// ホストグループを取得
Hostgroup hostgroup = zabbixProcessClient.getHostgroupByName(hostgroupName);
// ホストがホストグループに含まれる場合、ホストグループから除去する
if (hostgroup != null && groupids.contains(hostgroup.getGroupid())) {
for (int i = 0; i < hostgroups.size(); i++) {
if (StringUtils.equals(hostgroup.getGroupid(), hostgroups.get(i).getGroupid())) {
hostgroups.remove(i);
break;
}
}
//ホスト名取得
String hostname = getHostName(instance.getFqdn());
//IP/DNS使用フラグ取得
Boolean useIp = BooleanUtils.toBooleanObject(Config.getProperty("zabbix.useIp"));
//ZabbixプロキシID取得
String proxyHostid = getProxyHostid(zabbixProcessClient);
//IP設定
String zabbixListenIp = getZabbixListenIp(zabbixProcessClient, instance, platform);
zabbixProcessClient.updateHost(hostid, hostname, instance.getFqdn(), hostgroups, null, useIp, zabbixListenIp, proxyHostid);
}
}
private String getHostName(String fqdn) {
// Zabbixのホストの「名前」を prefix + _ + FQDN で設定する
// prefix値はconfig.propertiesから取得
String hostname = fqdn;
if (StringUtils.isNotEmpty(Config.getProperty("zabbix.prefix"))) {
//pretixが設定されている場合のみ設定
//設定されていない場合は通常通り、FQDNを設定
hostname = Config.getProperty("zabbix.prefix") + "-" + fqdn;
}
return hostname;
}
private String getProxyHostid(ZabbixProcessClient zabbixProcessClient) {
String proxyName = Config.getProperty("zabbix.proxy");
String proxyHostid = null;
if (StringUtils.isNotEmpty(proxyName)) {
Proxy proxy = zabbixProcessClient.getProxy(proxyName);
if (proxy != null) {
proxyHostid = proxy.getProxyid();
}
}
return proxyHostid;
}
private String getZabbixListenIp(ZabbixProcessClient zabbixProcessClient, Instance instance, Platform platform) {
String zabbixListenIp = instance.getPublicIp();
if (PCCConstant.PLATFORM_TYPE_AWS.equals(platform.getPlatformType())) {
if (BooleanUtils.isTrue(platform.getInternal())) {
// 内部のAWSプラットフォームの場合はprivateIpで待ち受ける
// この分岐に来るパターンは以下の場合
// Eucalyptus
// 内部AWS
// 通常のVPC(VPC+VPNでは無い)
zabbixListenIp = instance.getPrivateIp();
}
}
return zabbixListenIp;
}
/**
* zabbixProcessClientFactoryを設定します。
*
* @param zabbixProcessClientFactory zabbixProcessClientFactory
*/
public void setZabbixProcessClientFactory(ZabbixProcessClientFactory zabbixProcessClientFactory) {
this.zabbixProcessClientFactory = zabbixProcessClientFactory;
}
/**
* processLoggerを設定します。
*
* @param processLogger processLogger
*/
public void setProcessLogger(ProcessLogger processLogger) {
this.processLogger = processLogger;
}
}