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:
邱剑
2019-01-03 11:42:42 +08:00
9 changed files with 60 additions and 35 deletions
+1 -1
View File
@@ -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"`
+20 -15
View File
@@ -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",
}}
+8 -2
View File
@@ -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,
+1 -5
View File
@@ -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) {
+1 -1
View File
@@ -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
}
+23 -8
View File
@@ -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),
+3 -1
View File
@@ -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
}