fix: nas for huawei

This commit is contained in:
Qu Xuan
2021-04-09 19:44:14 +08:00
parent 8c749f23d5
commit 19b617b1e4
10 changed files with 433 additions and 4 deletions
+1
View File
@@ -1201,6 +1201,7 @@ func syncPublicCloudProviderInfo(
syncRegionSkus(ctx, userCred, localRegion)
SyncRegionDBInstanceSkus(ctx, userCred, localRegion.Id, true)
SyncRegionNatSkus(ctx, userCred, localRegion.Id, true)
SyncRegionNasSkus(ctx, userCred, localRegion.Id, true)
} else {
syncSkusFromPrivateCloud(ctx, userCred, syncResults, localRegion, remoteRegion)
}
+16 -3
View File
@@ -132,10 +132,23 @@ func (man *SFileSystemManager) ValidateCreateData(ctx context.Context, userCred
return input, err
}
network := net.(*SNetwork)
zone := network.GetZone()
input.ManagerId = network.GetVpc().ManagerId
input.ZoneId = zone.Id
input.CloudregionId = zone.CloudregionId
if zone := network.GetZone(); zone != nil {
input.ZoneId = zone.Id
input.CloudregionId = zone.CloudregionId
} else {
zones, err := network.GetRegion().GetZones()
if err != nil {
return input, httperrors.NewGeneralError(errors.Wrapf(err, "GetZones"))
}
for _, zone := range zones {
if zone.Status == api.ZONE_ENABLE {
input.ZoneId = zone.Id
input.CloudregionId = zone.CloudregionId
break
}
}
}
} else if len(input.ZoneId) > 0 {
_zone, err := validators.ValidateModel(userCred, ZoneManager, &input.ZoneId)
if err != nil {
+4
View File
@@ -2689,3 +2689,7 @@ func (self *SHuaWeiRegionDriver) ValidateCreateNatGateway(ctx context.Context, u
func (self *SHuaWeiRegionDriver) IsSupportedNatGateway() bool {
return true
}
func (self *SHuaWeiRegionDriver) IsSupportedNas() bool {
return true
}
+1 -1
View File
@@ -76,7 +76,7 @@ func (self *FileSystemCreateTask) OnInit(ctx context.Context, obj db.IStandalone
opts.VpcId = network.GetVpc().ExternalId
}
log.Infof("nas create params: %v", opts)
log.Infof("nas create params: %s", jsonutils.Marshal(opts).String())
iFs, err := iRegion.CreateICloudFileSystem(opts)
if err != nil {
+3
View File
@@ -89,6 +89,7 @@ type Client struct {
Groups *modules.SGroupManager
SAMLProviders *modules.SAMLProviderManager
SAMLProviderMappings *modules.SAMLProviderMappingManager
SfsTurbos *modules.SfsTurboManager
}
func (self *Client) SetHttpClient(httpClient *http.Client) {
@@ -146,6 +147,7 @@ func (self *Client) SetHttpClient(httpClient *http.Client) {
self.Groups.SetHttpClient(httpClient)
self.SAMLProviders.SetHttpClient(httpClient)
self.SAMLProviderMappings.SetHttpClient(httpClient)
self.SfsTurbos.SetHttpClient(httpClient)
}
func (self *Client) InitWithOptions(regionId, domainId, projectId string, credential auth.Credential) error {
@@ -237,6 +239,7 @@ func (self *Client) initManagers() {
self.SAMLProviders.SetDomainId(self.domainId)
self.SAMLProviderMappings = modules.NewSAMLProviderMappingManager(self.signer, self.debug)
self.SAMLProviderMappings.SetDomainId(self.domainId)
self.SfsTurbos = modules.NewSfsTurboManager(self.regionId, self.projectId, self.signer, self.debug)
}
self.init = true
@@ -51,6 +51,8 @@ const (
ServiceNameCTS ServiceNameType = "cts" // 云审计服务
ServiceNameCES ServiceNameType = "ces" // 监控服务 CloudEye
ServiceNameEPS ServiceNameType = "eps" // 企业项目
ServiceNameSFSTurbo ServiceNameType = "sfs-turbo" // 文件系统
)
type SManagerContext struct {
@@ -0,0 +1,48 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/auth"
"yunion.io/x/onecloud/pkg/multicloud/huawei/client/responses"
)
type SfsTurboManager struct {
SResourceManager
}
func NewSfsTurboManager(regionId, projectId string, signer auth.Signer, debug bool) *SfsTurboManager {
return &SfsTurboManager{SResourceManager: SResourceManager{
SBaseManager: NewBaseManager(signer, debug),
ServiceName: ServiceNameSFSTurbo,
Region: regionId,
ProjectId: projectId,
version: "v1",
Keyword: "",
KeywordPlural: "shares",
ResourceKeyword: "sfs-turbo/shares",
}}
}
func (self *SfsTurboManager) List(querys map[string]string) (*responses.ListResult, error) {
return self.ListInContextWithSpec(nil, "detail", querys, self.KeywordPlural)
}
func (self *SfsTurboManager) Create(params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return self.CreateInContextWithSpec(self.ctx, "", params, "")
}
+1
View File
@@ -506,6 +506,7 @@ func (self *SHuaweiClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_CLOUDID,
cloudprovider.CLOUD_CAPABILITY_SAML_AUTH,
cloudprovider.CLOUD_CAPABILITY_NAT,
cloudprovider.CLOUD_CAPABILITY_NAS,
}
// huawei objectstore is shared across projects(subscriptions)
// to avoid multiple project access the same bucket
+297
View File
@@ -0,0 +1,297 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package huawei
import (
"fmt"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
type SfsTurbo struct {
multicloud.SNasBase
region *SRegion
EnterpriseProjectId string
Actions []string
AvailCapacity float64
AvailabilityZone string
AzName string
CreatedAt time.Time
CryptKeyId string
ExpandType string
ExportLocation string
Id string
Name string
PayModel string
Region string
SecurityGroupId string
ShareProto string
ShareType string
Size float64
Status string
SubStatus string
SubnetId string
VpcId string
Description string
}
func (self *SfsTurbo) GetName() string {
return self.Name
}
func (self *SfsTurbo) GetId() string {
return self.Id
}
func (self *SfsTurbo) GetGlobalId() string {
return self.Id
}
func (self *SfsTurbo) GetFileSystemType() string {
return "SFS Turbo"
}
func (self *SfsTurbo) Refresh() error {
sf, err := self.region.GetSfsTurbo(self.Id)
if err != nil {
return errors.Wrapf(err, "GetSfsTurbo")
}
return jsonutils.Update(self, sf)
}
func (self *SfsTurbo) GetBillingType() string {
if self.PayModel == "0" {
return billing_api.BILLING_TYPE_POSTPAID
}
return billing_api.BILLING_TYPE_PREPAID
}
func (self *SfsTurbo) GetStorageType() string {
if len(self.ExpandType) == 0 {
return strings.ToLower(self.ShareType)
}
return strings.ToLower(self.ShareType) + ".enhanced"
}
func (self *SfsTurbo) GetProtocol() string {
return self.ShareProto
}
func (self *SfsTurbo) GetStatus() string {
switch self.Status {
case "100":
return api.NAS_STATUS_CREATING
case "200":
return api.NAS_SKU_AVAILABLE
case "300":
return api.NAS_STATUS_UNKNOWN
case "303":
return api.NAS_STATUS_CREATE_FAILED
case "400":
return api.NAS_STATUS_DELETING
case "800":
return api.NAS_STATUS_UNAVAILABLE
default:
return self.Status
}
}
func (self *SfsTurbo) GetCreatedAt() time.Time {
return self.CreatedAt
}
func (self *SfsTurbo) GetCapacityGb() int64 {
return int64(self.Size)
}
func (self *SfsTurbo) GetUsedCapacityGb() int64 {
return int64(self.Size - self.AvailCapacity)
}
func (self *SfsTurbo) GetMountTargetCountLimit() int {
return 1
}
func (self *SfsTurbo) GetZoneId() string {
return self.AvailabilityZone
}
func (self *SfsTurbo) GetMountTargets() ([]cloudprovider.ICloudMountTarget, error) {
mt := &sMoutTarget{sfs: self}
return []cloudprovider.ICloudMountTarget{mt}, nil
}
func (self *SfsTurbo) CreateMountTarget(opts *cloudprovider.SMountTargetCreateOptions) (cloudprovider.ICloudMountTarget, error) {
return nil, errors.Wrap(cloudprovider.ErrNotSupported, "CreateMountTarget")
}
func (self *SfsTurbo) Delete() error {
return self.region.DeleteSfsTurbo(self.Id)
}
func (self *SRegion) GetICloudFileSystems() ([]cloudprovider.ICloudFileSystem, error) {
sfs, err := self.GetSfsTurbos()
if err != nil {
return nil, errors.Wrapf(err, "self.GetSfsTurbos")
}
ret := []cloudprovider.ICloudFileSystem{}
for i := range sfs {
sfs[i].region = self
ret = append(ret, &sfs[i])
}
return ret, nil
}
func (self *SRegion) GetICloudFileSystemById(id string) (cloudprovider.ICloudFileSystem, error) {
sf, err := self.GetSfsTurbo(id)
if err != nil {
return nil, errors.Wrapf(err, "GetSfsTurbo(%s)", id)
}
return sf, nil
}
func (self *SRegion) GetSfsTurbos() ([]SfsTurbo, error) {
queues := make(map[string]string)
sfs := make([]SfsTurbo, 0, 2)
err := doListAllWithOffset(self.ecsClient.SfsTurbos.List, queues, &sfs)
if err != nil {
return nil, errors.Wrapf(err, "doListAllWithOffset")
}
return sfs, nil
}
func (self *SRegion) GetSfsTurbo(id string) (*SfsTurbo, error) {
sf := &SfsTurbo{region: self}
err := DoGet(self.ecsClient.SfsTurbos.Get, id, nil, &sf)
return sf, errors.Wrapf(err, "self.ecsClient.SfsTurbos.Get")
}
func (self *SRegion) DeleteSfsTurbo(id string) error {
return DoDelete(self.ecsClient.SfsTurbos.Delete, id, nil, nil)
}
func (self *SRegion) GetSysDefaultSecgroupId() (string, error) {
secs, err := self.GetSecurityGroups("default", "")
if err != nil {
return "", errors.Wrapf(err, "GetSecurityGroups")
}
if len(secs) > 0 {
return secs[0].ID, nil
}
return "", fmt.Errorf("not found default security group")
}
func (self *SRegion) CreateICloudFileSystem(opts *cloudprovider.FileSystemCraeteOptions) (cloudprovider.ICloudFileSystem, error) {
fs, err := self.CreateSfsTurbo(opts)
if err != nil {
return nil, errors.Wrapf(err, "CreateSfsTurbo")
}
return fs, nil
}
func (self *SRegion) CreateSfsTurbo(opts *cloudprovider.FileSystemCraeteOptions) (*SfsTurbo, error) {
secId, err := self.GetSysDefaultSecgroupId()
if err != nil {
return nil, errors.Wrapf(err, "GetSysDefaultSecgroupId")
}
metadata := map[string]string{}
if strings.HasSuffix(opts.StorageType, ".enhanced") {
metadata["expand_type"] = "bandwidth"
}
params := map[string]interface{}{
"share": map[string]interface{}{
"name": opts.Name,
"share_proto": strings.ToUpper(opts.Protocol),
"share_type": strings.ToUpper(strings.TrimSuffix(opts.StorageType, ".enhanced")),
"size": opts.Capacity,
"availability_zone": opts.ZoneId,
"vpc_id": opts.VpcId,
"subnet_id": opts.NetworkId,
"security_group_id": secId,
"description": opts.Desc,
"metadata": metadata,
},
}
resp, err := self.ecsClient.SfsTurbos.Create(jsonutils.Marshal(params))
if err != nil {
return nil, errors.Wrapf(err, "Create")
}
id, err := resp.GetString("id")
if err != nil {
return nil, errors.Wrapf(err, "resp.GetString(id)")
}
return self.GetSfsTurbo(id)
}
func (self *SRegion) GetICloudAccessGroups() ([]cloudprovider.ICloudAccessGroup, error) {
return []cloudprovider.ICloudAccessGroup{}, nil
}
func (self *SRegion) CreateICloudAccessGroup(opts *cloudprovider.SAccessGroup) (cloudprovider.ICloudAccessGroup, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotSupported, "CreateICloudAccessGroup")
}
func (self *SRegion) GetICloudAccessGroupById(id string) (cloudprovider.ICloudAccessGroup, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "GetICloudAccessGroupById(%s)", id)
}
type sMoutTarget struct {
sfs *SfsTurbo
}
func (self *sMoutTarget) GetName() string {
return self.sfs.Name
}
func (self *sMoutTarget) GetGlobalId() string {
return self.sfs.GetGlobalId()
}
func (self *sMoutTarget) GetAccessGroupId() string {
return ""
}
func (self *sMoutTarget) GetDomainName() string {
return self.sfs.ExportLocation
}
func (self *sMoutTarget) GetNetworkType() string {
return api.NETWORK_TYPE_VPC
}
func (self *sMoutTarget) GetNetworkId() string {
return self.sfs.SubnetId
}
func (self *sMoutTarget) GetVpcId() string {
return self.sfs.VpcId
}
func (self *sMoutTarget) GetStatus() string {
return api.MOUNT_TARGET_STATUS_AVAILABLE
}
func (self *sMoutTarget) Delete() error {
return nil
}
+60
View File
@@ -0,0 +1,60 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package shell
import (
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/huawei"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type FileSystemListOptions struct {
}
shellutils.R(&FileSystemListOptions{}, "file-system-list", "List FileSystem", func(cli *huawei.SRegion, args *FileSystemListOptions) error {
sfs, err := cli.GetSfsTurbos()
if err != nil {
return err
}
printList(sfs, 0, 0, 0, []string{})
return nil
})
type FileSystemIdOptions struct {
ID string `help:"File System ID"`
}
shellutils.R(&FileSystemIdOptions{}, "file-system-delete", "Delete filesystem", func(cli *huawei.SRegion, args *FileSystemIdOptions) error {
return cli.DeleteSfsTurbo(args.ID)
})
shellutils.R(&FileSystemIdOptions{}, "file-system-show", "Show filesystem", func(cli *huawei.SRegion, args *FileSystemIdOptions) error {
fs, err := cli.GetSfsTurbo(args.ID)
if err != nil {
return err
}
printObject(fs)
return nil
})
shellutils.R(&cloudprovider.FileSystemCraeteOptions{}, "file-system-create", "Create filesystem", func(cli *huawei.SRegion, args *cloudprovider.FileSystemCraeteOptions) error {
fs, err := cli.CreateSfsTurbo(args)
if err != nil {
return err
}
printObject(fs)
return nil
})
}