yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/huawei/keypair.go (about) 1 // Copyright 2019 Yunion 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package huawei 16 17 import ( 18 "fmt" 19 "strconv" 20 "strings" 21 "time" 22 23 "github.com/aokoli/goutils" 24 "golang.org/x/crypto/ssh" 25 26 "yunion.io/x/jsonutils" 27 ) 28 29 // https://support.huaweicloud.com/api-ecs/zh-cn_topic_0020212676.html 30 type SKeypair struct { 31 Fingerprint string `json:"fingerprint"` 32 Name string `json:"name"` 33 PublicKey string `json:"public_key"` 34 } 35 36 func (self *SRegion) getFingerprint(publicKey string) (string, error) { 37 pk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(publicKey)) 38 if err != nil { 39 return "", fmt.Errorf("publicKey error %s", err) 40 } 41 42 fingerprint := strings.Replace(ssh.FingerprintLegacyMD5(pk), ":", "", -1) 43 return fingerprint, nil 44 } 45 46 // https://support.huaweicloud.com/api-ecs/zh-cn_topic_0020212676.html 47 func (self *SRegion) GetKeypairs() ([]SKeypair, int, error) { 48 keypairs := make([]SKeypair, 0) 49 err := doListAll(self.ecsClient.Keypairs.List, nil, &keypairs) 50 return keypairs, len(keypairs), err 51 } 52 53 func (self *SRegion) lookUpKeypair(publicKey string) (string, error) { 54 keypairs, _, err := self.GetKeypairs() 55 if err != nil { 56 return "", err 57 } 58 59 fingerprint, err := self.getFingerprint(publicKey) 60 if err != nil { 61 return "", err 62 } 63 64 for _, keypair := range keypairs { 65 if keypair.Fingerprint == fingerprint { 66 return keypair.Name, nil 67 } 68 } 69 70 return "", fmt.Errorf("keypair not found %s", err) 71 } 72 73 // https://support.huaweicloud.com/api-ecs/zh-cn_topic_0020212678.html 74 func (self *SRegion) ImportKeypair(name, publicKey string) (*SKeypair, error) { 75 keypairObj := jsonutils.NewDict() 76 keypairObj.Add(jsonutils.NewString(name), "name") 77 keypairObj.Add(jsonutils.NewString(publicKey), "public_key") 78 params := jsonutils.NewDict() 79 params.Set("keypair", keypairObj) 80 ret := SKeypair{} 81 err := DoCreate(self.ecsClient.Keypairs.Create, params, &ret) 82 return &ret, err 83 } 84 85 func (self *SRegion) importKeypair(publicKey string) (string, error) { 86 prefix, e := goutils.RandomAlphabetic(6) 87 if e != nil { 88 return "", fmt.Errorf("publicKey error %s", e) 89 } 90 91 name := prefix + strconv.FormatInt(time.Now().Unix(), 10) 92 if k, e := self.ImportKeypair(name, publicKey); e != nil { 93 return "", fmt.Errorf("keypair import error %s", e) 94 } else { 95 return k.Name, nil 96 } 97 } 98 99 func (self *SRegion) syncKeypair(publicKey string) (string, error) { 100 name, e := self.lookUpKeypair(publicKey) 101 if e == nil { 102 return name, nil 103 } 104 return self.importKeypair(publicKey) 105 }