mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Merge pull request #871 in YUNIONIO/onecloud from ~TANGBIN/onecloud:bugfix/tb-huawei-stage-1-bugfix to release/2.5.0
* commit 'ca5d98ebe86094f85c5bcf6d0c94b7fa992b6f0b': 修复华为云安全组同步及子账户多了一个无效记录的问题
This commit is contained in:
@@ -34,7 +34,7 @@ func init() {
|
||||
NAME string `help:"Name of cloud account"`
|
||||
ACCOUNT string `help:"Account to access the cloud account"`
|
||||
SECRET string `help:"Secret to access the cloud account, clientId/clientScret for Azure"`
|
||||
PROVIDER string `help:"Driver for cloud account" choices:"VMware|Aliyun|Azure|Qcloud|OpenStack"`
|
||||
PROVIDER string `help:"Driver for cloud account" choices:"VMware|Aliyun|Azure|Qcloud|OpenStack|Huawei"`
|
||||
AccessURL string `helo:"hello" metavar:"Azure choices: <AzureGermanCloud、AzureChinaCloud、AzureUSGovernmentCloud、AzurePublicCloud>"`
|
||||
Desc string `help:"Description"`
|
||||
Enabled bool `help:"Enabled the account automatically"`
|
||||
|
||||
@@ -12,21 +12,22 @@ type Client struct {
|
||||
domainId string
|
||||
projectId string
|
||||
|
||||
Bandwidths *modules.SBandwidthManager
|
||||
Disks *modules.SDiskManager
|
||||
Eips *modules.SEipManager
|
||||
Images *modules.SImageManager
|
||||
Interface *modules.SInterfaceManager
|
||||
Keypairs *modules.SKeypairManager
|
||||
Port *modules.SPortManager
|
||||
Projects *modules.SProjectManager
|
||||
Regions *modules.SRegionManager
|
||||
SecurityGroups *modules.SSecurityGroupManager
|
||||
Servers *modules.SServerManager
|
||||
Snapshots *modules.SSnapshotManager
|
||||
Subnets *modules.SSubnetManager
|
||||
Vpcs *modules.SVpcManager
|
||||
Zones *modules.SZoneManager
|
||||
Bandwidths *modules.SBandwidthManager
|
||||
Disks *modules.SDiskManager
|
||||
Eips *modules.SEipManager
|
||||
Images *modules.SImageManager
|
||||
Interface *modules.SInterfaceManager
|
||||
Keypairs *modules.SKeypairManager
|
||||
Port *modules.SPortManager
|
||||
Projects *modules.SProjectManager
|
||||
Regions *modules.SRegionManager
|
||||
SecurityGroupRules *modules.SSecgroupRuleManager
|
||||
SecurityGroups *modules.SSecurityGroupManager
|
||||
Servers *modules.SServerManager
|
||||
Snapshots *modules.SSnapshotManager
|
||||
Subnets *modules.SSubnetManager
|
||||
Vpcs *modules.SVpcManager
|
||||
Zones *modules.SZoneManager
|
||||
}
|
||||
|
||||
func (self *Client) Init() error {
|
||||
@@ -101,6 +102,10 @@ func (self *Client) initManagers() {
|
||||
self.Keypairs = modules.NewKeypairManager(self.regionId, self.projectId, self.signer)
|
||||
}
|
||||
|
||||
if self.SecurityGroupRules == nil {
|
||||
self.SecurityGroupRules = modules.NewSecgroupRuleManager(self.regionId, self.projectId, self.signer)
|
||||
}
|
||||
|
||||
if self.SecurityGroups == nil {
|
||||
self.SecurityGroups = modules.NewSecurityGroupManager(self.regionId, self.projectId, self.signer)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
"yunion.io/x/onecloud/pkg/util/huawei/client/auth"
|
||||
|
||||
@@ -17,8 +17,8 @@ func NewSecgroupRuleManager(regionId string, projectId string, signer auth.Signe
|
||||
Region: regionId,
|
||||
ProjectId: projectId,
|
||||
version: "v1",
|
||||
Keyword: "security-group-rule",
|
||||
KeywordPlural: "security-group-rules",
|
||||
Keyword: "security_group_rule",
|
||||
KeywordPlural: "security_group_rules",
|
||||
|
||||
ResourceKeyword: "security-group-rules",
|
||||
}}
|
||||
|
||||
@@ -31,6 +31,7 @@ type SHuaweiClient struct {
|
||||
providerId string
|
||||
providerName string
|
||||
projectId string // 华为云项目ID.
|
||||
accessUrl string // 服务区域 ChinaCloud | InternationalCloud
|
||||
accessKey string
|
||||
secret string
|
||||
iregions []cloudprovider.ICloudRegion
|
||||
@@ -52,7 +53,8 @@ func parseAccount(account string) (accessKey string, projectId string) {
|
||||
// 进行资源操作时参数account 对应数据库cloudprovider表中的account字段,由accessKey和projectID两部分组成,通过"/"分割。
|
||||
// 初次导入Subaccount时,参数account对应cloudaccounts表中的account字段,即accesskey。此时projectID为空,
|
||||
// 只能进行同步子账号、查询region列表等projectId无关的操作。
|
||||
func NewHuaweiClient(providerId string, providerName string, account string, secret string) (*SHuaweiClient, error) {
|
||||
// todo: 通过accessurl支持国际站。目前暂时未支持国际站
|
||||
func NewHuaweiClient(providerId, providerName, accessurl, account, secret string) (*SHuaweiClient, error) {
|
||||
accessKey, projectId := parseAccount(account)
|
||||
client := SHuaweiClient{
|
||||
providerId: providerId,
|
||||
@@ -137,9 +139,13 @@ func (self *SHuaweiClient) GetSubAccounts() ([]cloudprovider.SSubAccount, error)
|
||||
}
|
||||
|
||||
// https://support.huaweicloud.com/api-iam/zh-cn_topic_0074171149.html
|
||||
subAccounts := make([]cloudprovider.SSubAccount, len(projects))
|
||||
subAccounts := make([]cloudprovider.SSubAccount, 0)
|
||||
for i := range projects {
|
||||
project := projects[i]
|
||||
// name 为MOS的project是华为云内部的一个特殊project。不需要同步到本地
|
||||
if strings.ToLower(project.Name) == "mos" {
|
||||
continue
|
||||
}
|
||||
s := cloudprovider.SSubAccount{
|
||||
Name: project.Name,
|
||||
State: models.CLOUD_PROVIDER_CONNECTED,
|
||||
|
||||
@@ -37,11 +37,7 @@ func (self *SHuaweiClient) fetchProjects() ([]SProject, error) {
|
||||
huawei, _ := clients.NewClientWithAccessKey("", "", self.accessKey, self.secret)
|
||||
projects := make([]SProject, 0)
|
||||
err := DoList(huawei.Projects.List, nil, &projects)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return projects, nil
|
||||
return projects, err
|
||||
}
|
||||
|
||||
func (self *SHuaweiClient) GetProjectById(projectId string) (SProject, error) {
|
||||
|
||||
@@ -15,7 +15,7 @@ func (self *SHuaweiProviderFactory) ValidateChangeBandwidth(instanceId string, b
|
||||
}
|
||||
|
||||
func (self *SHuaweiProviderFactory) GetProvider(providerId, providerName, url, account, secret string) (cloudprovider.ICloudProvider, error) {
|
||||
client, err := huawei.NewHuaweiClient(providerId, providerName, account, secret)
|
||||
client, err := huawei.NewHuaweiClient(providerId, providerName, url, account, secret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@ import (
|
||||
)
|
||||
|
||||
type SecurityGroupRule struct {
|
||||
Direction string `json:"direction"`
|
||||
Ethertype string `json:"ethertype"`
|
||||
ID string `json:"id"`
|
||||
Description string `json:"description"`
|
||||
SecurityGroupID string `json:"security_group_id"`
|
||||
RemoteGroupID *string `json:"remote_group_id,omitempty"`
|
||||
Direction string `json:"direction"`
|
||||
Ethertype string `json:"ethertype"`
|
||||
ID string `json:"id"`
|
||||
Description string `json:"description"`
|
||||
SecurityGroupID string `json:"security_group_id"`
|
||||
RemoteGroupID string `json:"remote_group_id"`
|
||||
}
|
||||
|
||||
type SecurityGroupRuleDetail struct {
|
||||
@@ -59,6 +59,11 @@ func (self *SSecurityGroup) GetId() string {
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) GetVpcId() string {
|
||||
// 无vpc关联的安全组统一返回normal
|
||||
if len(self.VpcID) == 0 {
|
||||
return "normal"
|
||||
}
|
||||
|
||||
return self.VpcID
|
||||
}
|
||||
|
||||
@@ -101,6 +106,11 @@ func (self *SSecurityGroup) GetDescription() string {
|
||||
func (self *SSecurityGroup) GetRules() ([]secrules.SecurityRule, error) {
|
||||
rules := make([]secrules.SecurityRule, 0)
|
||||
for _, r := range self.SecurityGroupRules {
|
||||
// 忽略了源地址是安全组的规则
|
||||
if len(r.RemoteGroupID) > 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
rule, err := self.GetSecurityRule(r.ID)
|
||||
if err != nil {
|
||||
return rules, err
|
||||
@@ -114,7 +124,7 @@ func (self *SSecurityGroup) GetRules() ([]secrules.SecurityRule, error) {
|
||||
|
||||
func (self *SSecurityGroup) GetSecurityRule(ruleId string) (secrules.SecurityRule, error) {
|
||||
remoteRule := SecurityGroupRuleDetail{}
|
||||
err := DoGet(self.vpc.region.ecsClient.SecurityGroups.Get, ruleId, nil, &remoteRule)
|
||||
err := DoGet(self.vpc.region.ecsClient.SecurityGroupRules.Get, ruleId, nil, &remoteRule)
|
||||
if err != nil {
|
||||
return secrules.SecurityRule{}, err
|
||||
}
|
||||
@@ -126,6 +136,11 @@ func (self *SSecurityGroup) GetSecurityRule(ruleId string) (secrules.SecurityRul
|
||||
direction = secrules.SecurityRuleEgress
|
||||
}
|
||||
|
||||
protocol := "any"
|
||||
if remoteRule.Protocol != "" {
|
||||
protocol = remoteRule.Protocol
|
||||
}
|
||||
|
||||
// todo: 没考虑ipv6。可能报错
|
||||
ipNet := &net.IPNet{}
|
||||
if len(remoteRule.RemoteIPPrefix) > 0 {
|
||||
@@ -136,7 +151,7 @@ func (self *SSecurityGroup) GetSecurityRule(ruleId string) (secrules.SecurityRul
|
||||
Priority: 0,
|
||||
Action: secrules.SecurityRuleAllow,
|
||||
IPNet: ipNet,
|
||||
Protocol: remoteRule.Protocol,
|
||||
Protocol: protocol,
|
||||
Direction: direction,
|
||||
PortStart: int(remoteRule.PortRangeMin),
|
||||
PortEnd: int(remoteRule.PortRangeMax),
|
||||
|
||||
@@ -69,12 +69,14 @@ func (self *SVpc) fetchNetworks() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 华为云安全组可以被同region的VPC使用
|
||||
func (self *SVpc) fetchSecurityGroups() error {
|
||||
limit := 100
|
||||
marker := ""
|
||||
secgroups := make([]SSecurityGroup, 0)
|
||||
for {
|
||||
parts, count, err := self.region.GetSecurityGroups(self.GetId(), limit, marker)
|
||||
// todo: vpc 和 安全组的关联关系还需要进一步确认。
|
||||
parts, count, err := self.region.GetSecurityGroups("", limit, marker)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user