示例#1
0
func (p *HostService) UpdateById(objectId string, host entity.Host, x_auth_token string) (created bool,
	errorCode string, err error) {
	logrus.Infof("start to update host [%v]", host)
	// do authorize first
	if authorized := GetAuthService().Authorize("update_host", x_auth_token, objectId, p.collectionName); !authorized {
		err = errors.New("required opertion is not authorized!")
		errorCode = COMMON_ERROR_UNAUTHORIZED
		logrus.Errorf("update host with objectId [%v] error is %v", objectId, err)
		return
	}

	if !bson.IsObjectIdHex(objectId) {
		err = errors.New("invalide ObjectId.")
		errorCode = COMMON_ERROR_INVALIDATE
		return
	}

	// FIXING
	//	hostquery, _, _  := p.QueryById(objectId, x_auth_token)
	var selector = bson.M{}
	selector["_id"] = bson.ObjectIdHex(objectId)

	host.ObjectId = bson.ObjectIdHex(objectId)
	host.TimeUpdate = dao.GetCurrentTime()

	logrus.Infof("start to change host")
	err = dao.HandleUpdateByQueryPartial(p.collectionName, selector, &host)
	//	created, err = dao.HandleUpdateOne(&host, dao.QueryStruct{p.collectionName, selector, 0, 0, ""})
	if err != nil {
		logrus.Errorf("update host [%v] error is %v", host, err)
		errorCode = HOST_ERROR_UPDATE
	}
	created = true
	return
}
示例#2
0
func (p *HostService) UpdateStatusById(objectId string, status string, x_auth_token string) (created bool,
	errorCode string, err error) {
	logrus.Infof("start to update host by objectId [%v] status to %v", objectId, status)
	// do authorize first
	if authorized := GetAuthService().Authorize("update_host", x_auth_token, objectId, p.collectionName); !authorized {
		err = errors.New("required opertion is not authorized!")
		errorCode = COMMON_ERROR_UNAUTHORIZED
		logrus.Errorf("update host with objectId [%v] status to [%v] failed, error is %v", objectId, status, err)
		return
	}
	// validate objectId
	if !bson.IsObjectIdHex(objectId) {
		err = errors.New("invalide ObjectId.")
		errorCode = COMMON_ERROR_INVALIDATE
		return
	}
	host, _, err := p.QueryById(objectId, x_auth_token)
	if err != nil {
		logrus.Errorf("get host by objeceId [%v] failed, error is %v", objectId, err)
		return
	}
	if host.Status == status {
		logrus.Infof("this host [%v] is already in state [%v]", host, status)
		return false, "", nil
	}
	var selector = bson.M{}
	selector["_id"] = bson.ObjectIdHex(objectId)

	change := bson.M{"status": status, "time_update": dao.GetCurrentTime()}
	err = dao.HandleUpdateByQueryPartial(p.collectionName, selector, change)
	if err != nil {
		logrus.Errorf("update host with objectId [%v] status to [%v] failed, error is %v", objectId, status, err)
		created = false
		return
	}
	created = true
	return

}
//terminate specified hosts of a cluster
func (p *ClusterService) TerminateHosts(clusterId string, hostIds []string, x_auth_token string) (errorCode string, err error) {
	logrus.Infof("start to decrease cluster hosts [%v]", hostIds)

	if !bson.IsObjectIdHex(clusterId) {
		err = errors.New("Invalid cluster_id")
		errorCode = COMMON_ERROR_INVALIDATE
		return
	}

	if len(hostIds) == 0 {
		errorCode = COMMON_ERROR_INVALIDATE
		err = errors.New("Empty array of host id")
		return errorCode, err
	}

	//query cluster by clusterId
	cluster := entity.Cluster{}
	clusterSelector := bson.M{}
	clusterSelector["_id"] = bson.ObjectIdHex(clusterId)
	err = dao.HandleQueryOne(&cluster, dao.QueryStruct{p.collectionName, clusterSelector, 0, 0, ""})

	_, currentHosts, errorCode, err := GetHostService().QueryHosts(clusterId, 0, 0, HOST_STATUS_RUNNING, x_auth_token)
	if err != nil {
		logrus.Errorf("get host by clusterId[%v] error [%v]", clusterId, err)
		return errorCode, err
	}

	if !deletable(currentHosts, hostIds) {
		logrus.Errorf("cluster's running node should not less than 5 nodes!")
		return CLUSTER_ERROR_DELETE_NODE_NUM, errors.New("cluster's running node should not less than 5 nodes!")
	}

	hosts := []entity.Host{}
	originStatus := make(map[string]string)
	directDeletedHosts := 0
	for _, hostId := range hostIds {
		//query host
		host, errorCode, err := GetHostService().QueryById(hostId, x_auth_token)
		if err != nil {
			return errorCode, err
		}

		//no host name means current host has not been created by docker-machine
		if len(strings.TrimSpace(host.HostName)) <= 0 {
			logrus.Warnf("host has no hostname, will be terminated directly, hostid: %s", hostId)
			_, _, err := GetHostService().UpdateStatusById(hostId, HOST_STATUS_TERMINATED, x_auth_token)
			if err != nil {
				logrus.Warnf("set no hostname host[%s] status to termianted error %v", hostId, err)
			}
			directDeletedHosts++
			continue
		}

		hosts = append(hosts, host)

		//protect master node
		if host.IsMasterNode {
			return HOST_ERROR_DELETE_MASTER, errors.New("Cannot delete master node")
		}

		originStatus[host.ObjectId.Hex()] = host.Status
		//call API to terminate host(master node cannot be deleted now)
		_, errorCode, err = GetHostService().UpdateStatusById(hostId, HOST_STATUS_TERMINATING, x_auth_token)
		if err != nil {
			logrus.Errorf("terminate host error is %s,%v", errorCode, err)
			continue
		}
	}

	if directDeletedHosts > 0 {
		logrus.Infof("update cluster instances - %d", directDeletedHosts)
		newvalue := cluster.Instances - directDeletedHosts
		selector := bson.M{}
		selector["_id"] = cluster.ObjectId

		change := bson.M{"instances": newvalue, "time_update": dao.GetCurrentTime()}
		erro := dao.HandleUpdateByQueryPartial(p.collectionName, selector, change)
		if erro != nil {
			logrus.Errorf("update cluster with objectId [%v] instances to [%d] failed, error is %v", clusterId, newvalue, erro)
		}
	}

	if len(hosts) <= 0 {
		logrus.Infof("no valid hosts will be deleted!")
		return
	}

	if IsDeploymentEnabled() {
		//call deployment module to delete nodes
		go DeleteNodes(cluster, hosts, originStatus, x_auth_token)
	}

	return
}
func (p *ClusterService) DeleteById(clusterId string, x_auth_token string) (errorCode string, err error) {
	logrus.Infof("start to delete Cluster with id [%v]", clusterId)
	// do authorize first
	if authorized := GetAuthService().Authorize("delete_cluster", x_auth_token, clusterId, p.collectionName); !authorized {
		err = errors.New("required opertion is not authorized!")
		errorCode = COMMON_ERROR_UNAUTHORIZED
		logrus.Errorf("authorize failure when deleting cluster with id [%v] , error is %v", clusterId, err)
		return errorCode, err
	}
	if !bson.IsObjectIdHex(clusterId) {
		err = errors.New("Invalid cluster id.")
		errorCode = COMMON_ERROR_INVALIDATE
		return errorCode, err
	}

	//query cluster
	cluster, errorCode, err := p.QueryById(clusterId, x_auth_token)
	if err != nil {
		logrus.Errorf("query cluster error is %v", err)
		return errorCode, err
	}

	//check status
	switch cluster.Status {
	case CLUSTER_STATUS_DEPLOYING, CLUSTER_STATUS_TERMINATING, CLUSTER_STATUS_TERMINATED:
		logrus.Errorf("Cannot operate on a %s cluster", cluster.Status)
		return CLUSTER_ERROR_INVALID_STATUS, errors.New("Cannot operate on a " + cluster.Status + " cluster")

	case CLUSTER_STATUS_RUNNING, CLUSTER_STATUS_FAILED:
		//query all hosts
		var total int
		total, hosts, errorCode, err := GetHostService().QueryHosts(clusterId, 0, 0, "unterminated", x_auth_token)
		if err != nil {
			logrus.Errorf("query hosts in cluster %s error is %v", clusterId, err)
			return errorCode, err
		}

		successNode := 0
		directDeletedHosts := 0
		//set status of all hosts TERMINATING
		for _, host := range hosts {

			//no host name means current host has not been created by docker-machine
			if len(strings.TrimSpace(host.HostName)) <= 0 {
				hostId := host.ObjectId.Hex()
				logrus.Warnf("cluster[%s] host [%s] has no hostname, will be terminated directly", cluster.Name, hostId)
				_, _, err := GetHostService().UpdateStatusById(hostId, HOST_STATUS_TERMINATED, x_auth_token)
				if err != nil {
					logrus.Warnf("set no hostname host status to termianted error %v", err)
				}

				directDeletedHosts++
				continue
			}

			//deploying and terminating host is not allowed to be terminated
			if host.Status == HOST_STATUS_DEPLOYING || host.Status == HOST_STATUS_TERMINATING {
				logrus.Errorf("status of host [%v] is [%s], cluster can not be deleted!", host.HostName, host.Status)
				return CLUSTER_ERROR_DELETE_NOT_ALLOWED, errors.New("cannot delete cluster because not all nodes are ready")
			}

			//set host status to termianting
			_, _, err = GetHostService().UpdateStatusById(host.ObjectId.Hex(), HOST_STATUS_TERMINATING, x_auth_token)
			if err != nil {
				logrus.Warnf("delete host [objectId=%v] error is %v", host.ObjectId.Hex(), err)
			} else {
				successNode++
			}
		}

		logrus.Infof("Cluster %s has %d hosts, %d successfully terminating", cluster.Name, total, successNode)

		selector := bson.M{}
		selector["_id"] = cluster.ObjectId
		change := bson.M{"status": CLUSTER_STATUS_TERMINATING, "time_update": dao.GetCurrentTime()}
		if directDeletedHosts > 0 {
			logrus.Infof("update cluster instances - %d", directDeletedHosts)
			newvalue := cluster.Instances - directDeletedHosts
			change["instances"] = newvalue
		}
		logrus.Debugf("update cluster status and instance bson[%v]", change)
		erro := dao.HandleUpdateByQueryPartial(p.collectionName, selector, change)
		if erro != nil {
			logrus.Errorf("update cluster with objectId [%v] failed, error is %v", clusterId, erro)
		}

		if IsDeploymentEnabled() {
			//call deployment module API
			go DeleteCluster(cluster, x_auth_token)
		}
	default:
		logrus.Errorf("Unknown cluster status %s", cluster.Status)
		return CLUSTER_ERROR_INVALID_STATUS, errors.New("Unknown cluster status " + cluster.Status)
	}

	return
}