contrib/config_ecs_instance_connect/agent/util/hostfinder.go (192 lines of code) (raw):

package util import ( "errors" "io/ioutil" "os" "strings" "sync" ) const ( HYBRID_DOMAIN = ".axt.aliyuncs.com" ) var region_ids []string = []string{ "cn-hangzhou", "cn-qingdao", "cn-beijing", "cn-zhangjiakou", "cn-huhehaote", "cn-shanghai", "cn-shenzhen", "cn-hongkong", "eu-west-1"} var ( g_regionId string = "" g_domainId = "" g_azoneId = "" g_instanceId = "" g_regionIdInitLock sync.Mutex g_domainIdInitLock sync.Mutex g_azoneIdInitLock sync.Mutex g_instanceIdInitLock sync.Mutex ) func connectionDetect(regionId string) error { host := regionId + ".axt.aliyun.com" url := "https://" + host + "/luban/api/connection_detect" ret, err := HttpGet(url) if err != nil { return err } if ret == "ok" { return nil } return errors.New("Unknown response") } func getRegionIdInVpc() (error, string) { var token, regionId string var err error url := "http://100.100.100.200/latest/meta-data/region-id" token, err = MetaserverToken() if err == nil { regionId, err = HttpGetWithHeaders(url, map[string]string{ "X-aliyun-ecs-metadata-token": token, }) } else { regionId, err = HttpGet(url) } if err != nil { return err, "" } err = connectionDetect(regionId) if err == nil { return nil, regionId } return err, "" } func GetAzoneId() string { g_azoneIdInitLock.Lock() defer g_azoneIdInitLock.Unlock() if len(g_azoneId) > 0 { return g_azoneId } var token, azoneId string var err error url := "http://100.100.100.200/latest/meta-data/zone-id" token, err = MetaserverToken() if err == nil { azoneId, err = HttpGetWithHeaders(url, map[string]string{ "X-aliyun-ecs-metadata-token": token, }) } else { azoneId, err = HttpGet(url) } if err != nil { g_azoneId = "unknown" return g_azoneId } g_azoneId = azoneId return g_azoneId } func GetInstanceId() string { g_instanceIdInitLock.Lock() defer g_instanceIdInitLock.Unlock() if len(g_instanceId) > 0 { return g_instanceId } var token, instanceId string var err error url := "http://100.100.100.200/latest/meta-data/instance-id" token, err = MetaserverToken() if err == nil { instanceId, err = HttpGetWithHeaders(url, map[string]string{ "X-aliyun-ecs-metadata-token": token, }) } else { instanceId, err = HttpGet(url) } if err != nil { g_instanceId = "unknown" return g_instanceId } g_instanceId = instanceId return g_instanceId } func checkClassicRegion(possibleRegionID string) (string, error) { host := possibleRegionID + ".axt.aliyun.com" url := "https://" + host + "/luban/api/classic/region-id" detectedRegionID, err := HttpGet(url) if err != nil { return "", err } // Response of https://available-region.axt.aliyun.com/luban/api/classic/region-id // in classic network should be correct region id information for requesting // instance, so just check connectivity of responded-region.axt.aliyun.com if connectionDetect(detectedRegionID) == nil { return detectedRegionID, nil } return "", errors.New("Unknown regionId") } func pollingRegionId() string { for _, possibleRegionID := range region_ids { detectedRegionID, err := checkClassicRegion(possibleRegionID) if err == nil { return detectedRegionID } } return "" } func IsSelfHosted() bool { return os.Getenv("ALIYUN_ASSIST_SERVER_HOST") != "" } func getRegionIdInFile() string { cur, _ := GetCurrentPath() path := cur + "../region-id" if CheckFileIsExist(path) == false { return "" } raw, err := ioutil.ReadFile(path) if err == nil { content := string(raw) content = strings.Trim(content, "\r") content = strings.Trim(content, "\n") content = strings.Trim(content, "\t") return strings.TrimSpace(content) } return "" } // InitRegionId detects and sets region id of server host in both VPC and classic networks func initRegionId() error { if g_regionId == "" { // Retrieve region ID from meta server in VPC network err, regionId := getRegionIdInVpc() if err == nil { g_regionId = regionId return nil } g_regionId = getRegionIdInFile() if g_regionId != "" { return nil } } return nil } // GetRegionId should be always successful since InitRegionId should be called before. // However, it's hard to terminate the agent under this case since even panic could // only terminate the calling goroutine func GetRegionId() string { g_regionIdInitLock.Lock() defer g_regionIdInitLock.Unlock() if g_regionId != "" { return g_regionId } else { initRegionId() } return g_regionId } // GetServerHost returns empty string when region id is invalid as error handling func GetServerHost() string { g_domainIdInitLock.Lock() defer g_domainIdInitLock.Unlock() if g_domainId != "" { return g_domainId } if IsSelfHosted() { return os.Getenv("ALIYUN_ASSIST_SERVER_HOST") } regionId := GetRegionId() if regionId != "" { return regionId + ".axt.aliyun.com" } else { return "" } }