Skip to content

Commit

Permalink
feat(bingocloud):improve bingocloud driver
Browse files Browse the repository at this point in the history
  • Loading branch information
李锐 committed Apr 26, 2023
1 parent 2ae7f32 commit fcee942
Show file tree
Hide file tree
Showing 14 changed files with 314 additions and 128 deletions.
11 changes: 5 additions & 6 deletions cmd/bingocli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,11 @@ func newClient(options *BaseOptions) (*bingocloud.SRegion, error) {
options.Endpoint,
options.AccessKey,
options.SecretKey,
).Debug(options.Debug).
CloudproviderConfig(
cloudprovider.ProviderConfig{
ProxyFunc: proxyFunc,
},
),
).Debug(options.Debug).SetCloudproviderConfig(
cloudprovider.ProviderConfig{
ProxyFunc: proxyFunc,
},
),
)
if err != nil {
return nil, err
Expand Down
67 changes: 59 additions & 8 deletions pkg/multicloud/bingocloud/account.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,63 @@
package bingocloud

import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
"unicode/utf8"
)

type SAccount struct {
AccessKeyId string
SecretAccessKey string
Arn string
DeptId string
DeptName string
IsEncrypted string
UserId string
UserName string
Id string `json:"Id"`
AccessKeyId string `json:"AccessKeyId"`
Arn string `json:"Arn"`
FullName string `json:"FullName"`
IsAdmin string `json:"IsAdmin"`
IsEncrypted string `json:"IsEncrypted"`
SecurityKey string `json:"SecurityKey"`
Status string `json:"Status"`
Type string `json:"Type"`
UserId string `json:"UserId"`
UserName string `json:"UserName"`
}

func (self *SAccount) decryptKeys(masterSecretKey string) (string, string) {
if len(self.SecurityKey) == len(masterSecretKey) {
return self.AccessKeyId, self.SecurityKey
}

secretKeyBytes, err := base64.StdEncoding.DecodeString(self.SecurityKey)
if err != nil {
return "", ""
}
var adminSecretKey = ""
if len(masterSecretKey) >= 32 {
adminSecretKey = masterSecretKey[0:32]
} else {
adminSecretKey = fmt.Sprintf("%s%032s", masterSecretKey, "")[0:32]
}
decryptVal, err := aesCrtCrypt([]byte(secretKeyBytes), []byte(adminSecretKey), make([]byte, 16))
if err != nil {
return "", ""
}

decryptSecret := fmt.Sprintf("%s", decryptVal)

if !utf8.ValidString(decryptSecret) {
return self.AccessKeyId, self.SecurityKey
}

return self.AccessKeyId, decryptSecret
}

func aesCrtCrypt(val, key, iv []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockMode := cipher.NewCTR(block, iv)
body := make([]byte, len(val))
blockMode.XORKeyStream(body, val)
return body, nil
}
138 changes: 89 additions & 49 deletions pkg/multicloud/bingocloud/bingo.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ const (
MAX_RESULT = 20
)

var (
ManagerActions = []string{
"DescribeNodes",
"DescribePhysicalHosts",
"DescribeClusters",
"DescribeAvailabilityZones",
"DescribeStorages",
}
)

type BingoCloudConfig struct {
cpcfg cloudprovider.ProviderConfig
endpoint string
Expand All @@ -63,11 +73,15 @@ func NewBingoCloudClientConfig(endpoint, accessKey, secretKey string) *BingoClou
return cfg
}

func (cfg *BingoCloudConfig) CloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *BingoCloudConfig {
func (cfg *BingoCloudConfig) SetCloudproviderConfig(cpcfg cloudprovider.ProviderConfig) *BingoCloudConfig {
cfg.cpcfg = cpcfg
return cfg
}

func (cfg *BingoCloudConfig) GetCloudproviderConfig() cloudprovider.ProviderConfig {
return cfg.cpcfg
}

func (cfg *BingoCloudConfig) Debug(debug bool) *BingoCloudConfig {
cfg.debug = debug
return cfg
Expand All @@ -77,23 +91,31 @@ type SBingoCloudClient struct {
*BingoCloudConfig

regions []SRegion

managerClient *SBingoCloudClient

user string
}

func NewBingoCloudClient(cfg *BingoCloudConfig) (*SBingoCloudClient, error) {
client := &SBingoCloudClient{BingoCloudConfig: cfg}
var err error
client.regions, err = client.GetRegions()
if err != nil {
return nil, err
}
for i := range client.regions {
client.regions[i].client = client
client.regions, _ = client.GetRegions()
if client.regions != nil {
for i := range client.regions {
client.regions[i].client = client
}
}
client.user = client.getAccountUser()
return client, nil
}

func (self *SBingoCloudClient) SetManagerClient(client *SBingoCloudClient) {
self.regions = client.regions
self.managerClient = client
}

func (self *SBingoCloudClient) GetAccountId() string {
return self.endpoint
return self.accessKey
}

func (self *SBingoCloudClient) GetRegion(id string) (*SRegion, error) {
Expand Down Expand Up @@ -296,56 +318,36 @@ func (self *SBingoCloudClient) GetSubAccounts() ([]cloudprovider.SSubAccount, er
}
_ = result.Unmarshal(&tags, "tagSet")

var subAccounts []cloudprovider.SSubAccount
var subAccounts = []cloudprovider.SSubAccount{{
Id: self.getAccountUser(),
Account: self.accessKey,
Secret: self.secretKey,
Name: self.cpcfg.Name,
HealthStatus: api.CLOUD_PROVIDER_HEALTH_NORMAL,
}}

for i := range tags {
account, err := self.listAccessKeys(tags[i].ResourceId)
if err != nil {
continue
}
ak, sk := account.decryptKeys(self.secretKey)
subAccount := cloudprovider.SSubAccount{
Account: self.accessKey,
Name: tags[i].ResourceId,
DefaultProjectId: tags[i].Value,
Id: account.UserId,
Name: account.UserName,
HealthStatus: api.CLOUD_PROVIDER_HEALTH_NORMAL,
Account: ak,
Secret: sk,
IsSubAccount: true,
DefaultProjectId: tags[i].Value,
}
subAccounts = append(subAccounts, subAccount)
}
return subAccounts, nil
}

func (self *SBingoCloudClient) GetEnrollmentAccounts() ([]cloudprovider.SEnrollmentAccount, error) {
params := map[string]string{"Marker": "", "MaxItems": "1000", "AccountName": "paas_app"}
var result struct {
IsTruncated string
Marker string `json:"marker,omitempty"`
Users struct {
Member *SAccount `json:"member,omitempty"`
}
}
var eas []cloudprovider.SEnrollmentAccount
for {
resp, err := self.invoke("ListAccounts", params)
if err != nil {
return nil, err
}
err = resp.Unmarshal(&result, "ListAccountsResult")
if err != nil {
return nil, err
}
ea := cloudprovider.SEnrollmentAccount{
Id: result.Users.Member.UserId,
Name: result.Users.Member.UserName,
}
eas = append(eas, ea)
//for _, user := range result.Users.Member {
// ea := cloudprovider.SEnrollmentAccount{
// Id: user.UserId,
// Name: user.UserName,
// }
// eas = append(eas, ea)
//}
if params["Marker"] == result.Marker {
break
}
params["Marker"] = result.Marker
}
return eas, nil
return nil, nil
}

func (self *SBingoCloudClient) GetIRegions() []cloudprovider.ICloudRegion {
Expand All @@ -357,6 +359,44 @@ func (self *SBingoCloudClient) GetIRegions() []cloudprovider.ICloudRegion {
return ret
}

func (self *SBingoCloudClient) listAccessKeys(userName string) (*SAccount, error) {
params := map[string]string{"Marker": "", "MaxItems": "1000", "UserName": userName}

resp, err := self.managerClient.invoke("ListAccessKeys", params)
if err != nil {
return nil, err
}

var account *SAccount
err = resp.Unmarshal(&account, "ListAccessKeysResult", "AccessKeyMetadata", "member")
if err != nil {
return nil, err
}

return account, nil
}

func (self *SBingoCloudClient) getAccountUser() string {
quotas, err := self.getQuotas()
if err != nil {
return ""
}
ownerId := ""
if len(quotas) > 0 {
ownerId = quotas[0].OwnerId
}
return ownerId
}

func (self *SBingoCloudClient) getQuotas() ([]SQuotas, error) {
resp, err := self.invoke("DescribeQuotas", nil)
if err != nil {
return nil, err
}
var ret []SQuotas
return ret, resp.Unmarshal(&ret, "quotaSet")
}

func (self *SBingoCloudClient) describeTags(filter map[string]string) (jsonutils.JSONObject, error) {
params := map[string]string{"MaxResults": "10000"}
i := 1
Expand Down
26 changes: 24 additions & 2 deletions pkg/multicloud/bingocloud/disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"strconv"

"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"

api "yunion.io/x/cloudmux/pkg/apis/compute"
Expand Down Expand Up @@ -60,6 +61,8 @@ type SDisk struct {
StorageId string `json:"storageId"`
VolumeId string `json:"volumeId"`
VolumeName string `json:"volumeName"`

ImageId string `json:"imageId"`
}

func (self *SDisk) GetISnapshots() ([]cloudprovider.ICloudSnapshot, error) {
Expand Down Expand Up @@ -118,7 +121,13 @@ func (self *SDisk) GetIsAutoDelete() bool {
}

func (self *SDisk) GetTemplateId() string {
return ""
if self.ImageId == "" && len(self.AttachmentSet) > 0 {
instances, _, _ := self.storage.cluster.region.GetInstances(self.AttachmentSet[0].InstanceId, "", 1, "")
if instances != nil {
self.ImageId = instances[0].InstancesSet.ImageId
}
}
return self.ImageId
}

func (self *SDisk) GetDiskType() string {
Expand Down Expand Up @@ -187,6 +196,14 @@ func (self *SDisk) Rebuild(ctx context.Context) error {
return cloudprovider.ErrNotImplemented
}

func (self *SDisk) Refresh() error {
newDisk, err := self.storage.cluster.region.GetDisk(self.GetGlobalId())
if err != nil {
return err
}
return jsonutils.Update(self, &newDisk)
}

func (self *SDisk) GetStatus() string {
switch self.Status {
case "available", "in-use":
Expand All @@ -203,6 +220,10 @@ func (self *SRegion) GetDisks(id string, maxResult int, nextToken string) ([]SDi
params[fmt.Sprintf("Filter.%d.Name", idx)] = "volume-id"
params[fmt.Sprintf("Filter.%d.Value.1", idx)] = id
idx++
} else {
params[fmt.Sprintf("Filter.%d.Name", idx)] = "owner-id"
params[fmt.Sprintf("Filter.%d.Value.1", idx)] = self.client.user
idx++
}

if len(nextToken) > 0 {
Expand Down Expand Up @@ -277,7 +298,7 @@ func (self *SRegion) GetDisk(id string) (*SDisk, error) {
func (self *SStorage) CreateIDisk(conf *cloudprovider.DiskCreateConfig) (cloudprovider.ICloudDisk, error) {
params := map[string]string{}
params["VolumeName"] = conf.Name
params["AvailabilityZone"] = self.cluster.ClusterId
params["AvailabilityZone"] = conf.ZoneId
params["Size"] = strconv.Itoa(conf.SizeGb)

resp, err := self.cluster.region.invoke("CreateVolume", params)
Expand All @@ -286,6 +307,7 @@ func (self *SStorage) CreateIDisk(conf *cloudprovider.DiskCreateConfig) (cloudpr
}
ret := &SDisk{}
_ = resp.Unmarshal(&ret)
ret.storage = self

return ret, nil
}
8 changes: 7 additions & 1 deletion pkg/multicloud/bingocloud/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,11 @@ func (self *SRegion) GetImages(id, nextToken string) ([]SImage, string, error) {
if len(nextToken) > 0 {
params["NextToken"] = nextToken
}
//idx := 1
//params[fmt.Sprintf("Filter.%d.Name", idx)] = "owner-id"
//params[fmt.Sprintf("Filter.%d.Value.1", idx)] = self.client.user
//idx++

resp, err := self.invoke("DescribeImages", params)
if err != nil {
return nil, "", err
Expand Down Expand Up @@ -250,7 +255,8 @@ func (self *SStoragecache) GetIImageById(id string) (cloudprovider.ICloudImage,
return nil, err
}
for i := range images {
if images[i].GetGlobalId() == id && images[i].StorageId == self.storageId {
// && images[i].StorageId == self.storageId
if images[i].GetGlobalId() == id {
images[i].cache = self
return &images[i], nil
}
Expand Down
Loading

0 comments on commit fcee942

Please sign in to comment.