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 }
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 }