123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- /**
- 阿里云ecs实例自动申请、部署、释放
- **/
- package cluster
- import (
- "bytes"
- "crypto/hmac"
- "crypto/sha1"
- "encoding/base64"
- "encoding/json"
- "fmt"
- "hash"
- "io"
- "io/ioutil"
- db "jy/mongodbutil"
- ju "jy/util"
- "log"
- "net/http"
- "net/url"
- qu "qfw/util"
- "sort"
- "strings"
- "time"
- )
- const (
- Password = "Jy_ExtractBid_2019"
- URL = "https://ecs.aliyuncs.com"
- )
- //批量创建实例
- func RunInstances(TaskName string, num, hours int) {
- if esconfig, ok := ju.Config["esconfig"].(map[string]interface{}); ok {
- if b, ok := esconfig["available"].(bool); ok && b {
- res := GET("RunInstances", [][]string{
- []string{"RegionId", "cn-beijing"},
- []string{"LaunchTemplateId", qu.ObjToString(esconfig["LaunchTemplateId"])},
- //[]string{"ImageId", "centos_7_06_64_20G_alibase_20181212.vhd"},
- //[]string{"InstanceType", "ecs.ic5.large"},
- //[]string{"SecurityGroupId", "sg-bp16x3td2evrejhkshp7"},
- []string{"VSwitchId", qu.ObjToString(esconfig["VSwitchId"])},
- []string{"InternetMaxBandwidthIn", "50"},
- []string{"InternetMaxBandwidthOut", "0"},
- []string{"InstanceChargeType", "PostPaid"},
- []string{"SpotStrategy", "SpotWithPriceLimit"},
- []string{"SpotPriceLimit", "4.99"},
- []string{"InstanceName", "extract"},
- []string{"UniqueSuffix", "true"},
- []string{"Password", Password},
- []string{"Amount", fmt.Sprint(num)},
- []string{"AutoReleaseTime", time.Now().Add(time.Duration(hours) * time.Hour).UTC().Format("2006-01-02T15:04:05Z")},
- })
- // {"RequestId":"95653A72-4907-4DD0-86F9-00E216193173","InstanceIdSets":{"InstanceIdSet":["i-2ze0z0xdiqgtwji5jd9s"]}}
- if tmp, ok := res["InstanceIdSets"].(map[string]interface{}); ok {
- if t, ok := tmp["InstanceIdSet"].([]interface{}); ok {
- //实例id持久化
- for _, v := range t {
- db.Mgo.Save("ecs", map[string]interface{}{
- "InstanceId": v,
- "TaskName": TaskName,
- "UseFor": "extract",
- })
- }
- }
- }
- log.Println(res)
- }
- }
- }
- //查询多台实例的详细信息
- func DescribeInstances() {
- res := GET("DescribeInstances", [][]string{
- []string{"RegionId", "cn-beijing"},
- []string{"InstanceChargeType", "PostPaid"},
- []string{"PageSize", "100"},
- })
- for _, ins := range res["Instances"].(map[string]interface{}) {
- for _, val := range ins.([]interface{}) {
- if tmp, ok := val.(map[string]interface{}); ok {
- if t, ok := tmp["VpcAttributes"].(map[string]interface{}); ok {
- if tt, ok := t["PrivateIpAddress"].(map[string]interface{}); ok {
- ttt := tt["IpAddress"].([]interface{})
- tmp["ip_nw"] = ttt[0]
- }
- }
- if t, ok := tmp["PublicIpAddress"].(map[string]interface{}); ok {
- if tt, ok := t["IpAddress"].([]interface{}); ok && len(tt) > 0 {
- tmp["ip_ww"] = tt[0]
- }
- }
- //更新实例信息
- db.Mgo.Update("ecs", `{"InstanceId":"`+qu.ObjToString(tmp["InstanceId"])+`"}`, map[string]interface{}{"$set": tmp}, true, false)
- }
- }
- }
- log.Println(res)
- }
- //停止实例
- func StopInstance(InstanceId string) {
- res := GET("StopInstance", [][]string{
- []string{"InstanceId", InstanceId},
- })
- db.Mgo.Update("ecs", `{"InstanceId":"`+InstanceId+`"}`, map[string]interface{}{"$set": map[string]interface{}{"Status": "Released"}}, true, false)
- log.Println("StopInstance", res)
- }
- //释放实例
- func DeleteInstance(InstanceId string) {
- res := GET("DeleteInstance", [][]string{
- []string{"InstanceId", InstanceId},
- []string{"Force", "true"},
- })
- db.Mgo.Update("ecs", `{"InstanceId":"`+InstanceId+`"}`, map[string]interface{}{"$set": map[string]interface{}{"Status": "Deleted"}}, true, false)
- log.Println("DeleteInstance", res)
- }
- //实例自动释放时间
- func ModifyInstanceAutoReleaseTime(InstanceId string, hours int) {
- res := GET("ModifyInstanceAutoReleaseTime", [][]string{
- []string{"InstanceId", InstanceId},
- []string{"AutoReleaseTime", time.Now().Add(time.Duration(hours) * time.Hour).UTC().Format("2006-01-02T15:04:05Z")},
- })
- log.Println("ModifyInstanceAutoReleaseTime", res)
- }
- //GET请求
- func GET(action string, param [][]string) (mres map[string]interface{}) {
- esconfig, _ := ju.Config["esconfig"].(map[string]interface{})
- ps := ¶mSorter{[]string{
- "Format",
- "Version",
- "SignatureMethod",
- "SignatureNonce",
- "SignatureVersion",
- "AccessKeyId",
- "Timestamp",
- }, []string{
- "JSON",
- "2014-05-26",
- "HMAC-SHA1",
- fmt.Sprintf("%d", time.Now().UnixNano()/1000),
- "1.0",
- qu.ObjToString(esconfig["AccessID"]),
- time.Now().UTC().Format("2006-01-02T15:04:05Z"),
- }}
- ps.Keys = append(ps.Keys, "Action")
- ps.Vals = append(ps.Vals, action)
- if len(param) > 0 {
- for _, v := range param {
- ps.Keys = append(ps.Keys, v[0])
- ps.Vals = append(ps.Vals, v[1])
- }
- }
- ps.Sort()
- reqStr := ps.String()
- str := "GET&" +
- percentEncode("/") + "&" +
- percentEncode(reqStr)
- str = SP(str, "%3A", "%253A", -1)
- h := hmac.New(func() hash.Hash { return sha1.New() }, []byte(qu.ObjToString(esconfig["AccessSecret"])+"&"))
- io.WriteString(h, str)
- signedStr := base64.StdEncoding.EncodeToString(h.Sum(nil))
- ps.Keys = append(ps.Keys, "Signature")
- ps.Vals = append(ps.Vals, signedStr)
- reqStr = ps.Query()
- res, err := http.Get(fmt.Sprintf("%s?%s", URL, reqStr))
- if err != nil {
- log.Println(err.Error())
- } else {
- defer res.Body.Close()
- bt, err := ioutil.ReadAll(res.Body)
- if err == nil {
- //log.Println(string(bt))
- err := json.Unmarshal(bt, &mres)
- if err != nil {
- log.Println(err.Error())
- }
- }
- }
- return
- }
- var SP = strings.Replace
- func percentEncode(str string) string {
- str = url.QueryEscape(str)
- str = SP(SP(SP(str, "+", "%20", -1), "*", "%2A", -1), "%7E", "~", -1)
- return str
- }
- type paramSorter struct {
- Keys []string
- Vals []string
- }
- func (ps *paramSorter) String() string {
- str := ""
- for n, k := range ps.Keys {
- str += k + "=" + ps.Vals[n]
- if n < len(ps.Keys)-1 {
- str += "&"
- }
- }
- return str
- }
- func (ps *paramSorter) Query() string {
- str := ""
- for n, k := range ps.Keys {
- str += k + "=" + url.QueryEscape(ps.Vals[n])
- if n < len(ps.Keys)-1 {
- str += "&"
- }
- }
- return str
- }
- func (ps *paramSorter) Sort() {
- sort.Sort(ps)
- }
- func (ps *paramSorter) Len() int {
- return len(ps.Vals)
- }
- func (ps *paramSorter) Less(i, j int) bool {
- return bytes.Compare([]byte(ps.Keys[i]), []byte(ps.Keys[j])) < 0
- }
- func (ps *paramSorter) Swap(i, j int) {
- ps.Vals[i], ps.Vals[j] = ps.Vals[j], ps.Vals[i]
- ps.Keys[i], ps.Keys[j] = ps.Keys[j], ps.Keys[i]
- }
|