mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
fix: nas for huawei
This commit is contained in:
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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, "")
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
})
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user