Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:【账号管理】一级账号录入提供新校验接口 --story=118971366 #1026

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions cmd/account-server/service/account-set/root-account/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,19 @@
package rootaccount

import (
"errors"
"fmt"

accountset "hcm/pkg/api/account-server/account-set"
"hcm/pkg/api/cloud-server/account"
"hcm/pkg/api/core"
"hcm/pkg/api/core/cloud"
"hcm/pkg/client"
"hcm/pkg/criteria/enumor"
"hcm/pkg/criteria/errf"
"hcm/pkg/dal/dao/tools"
"hcm/pkg/iam/meta"
"hcm/pkg/logs"
"hcm/pkg/rest"
)

Expand Down Expand Up @@ -54,3 +61,123 @@ func CheckDuplicateRootAccount(cts *rest.Contexts, client *client.ClientSet, ven

return nil
}

// QueryRootAccountBySecret 根据秘钥获取账号信息
func (s *service) QueryRootAccountBySecret(cts *rest.Contexts) (interface{}, error) {
vendor := enumor.Vendor(cts.Request.PathParameter("vendor"))
if err := vendor.Validate(); err != nil {
return nil, errf.NewFromErr(errf.InvalidParameter, err)
}

// 校验用户有一级账号管理权限
if err := s.checkPermission(cts, meta.RootAccount, meta.Find); err != nil {
return nil, err
}

switch vendor {
case enumor.HuaWei:
return s.getHuaWeiAccountInfo(cts)
case enumor.Aws:
return s.getAwsAccountInfo(cts)
case enumor.Azure:
return s.getAzureAccountInfo(cts)
case enumor.Gcp:
return s.getGcpAccountInfo(cts)
default:
chenjr15 marked this conversation as resolved.
Show resolved Hide resolved
return nil, fmt.Errorf("unsupported vendor: %s, for get root account info", vendor)
}
}

func (s *service) getHuaWeiAccountInfo(cts *rest.Contexts) (*cloud.HuaWeiInfoBySecret, error) {
req := new(accountset.HuaWeiAccountInfoBySecretReq)
if err := cts.DecodeInto(req); err != nil {
return nil, errf.NewFromErr(errf.DecodeRequestFailed, err)
}
if err := req.Validate(); err != nil {
return nil, errf.NewFromErr(errf.InvalidParameter, err)
}

info, err := s.client.HCService().HuaWei.Account.GetBySecret(cts.Kit.Ctx, cts.Kit.Header(), req.HuaWeiSecret)
if err != nil {
logs.Errorf("fail to get huawei account info, err: %v, rid: %s", err, cts.Kit.Rid)
return nil, err
}

return info, nil
}

func (s *service) getAwsAccountInfo(cts *rest.Contexts) (*cloud.AwsInfoBySecret, error) {
req := new(accountset.AwsAccountInfoBySecretReq)
if err := cts.DecodeInto(req); err != nil {
return nil, errf.NewFromErr(errf.DecodeRequestFailed, err)
}
if err := req.Validate(); err != nil {
return nil, errf.NewFromErr(errf.InvalidParameter, err)
}

info, err := s.client.HCService().Aws.Account.GetBySecret(cts.Kit.Ctx, cts.Kit.Header(), req.AwsSecret)
if err != nil {
logs.Errorf("fail to get aws account info, err: %v, rid: %s", err, cts.Kit.Rid)
return nil, err
}

return info, nil
}

func (s *service) getGcpAccountInfo(cts *rest.Contexts) ([]cloud.GcpProjectInfo, error) {
req := new(accountset.GcpAccountInfoBySecretReq)
if err := cts.DecodeInto(req); err != nil {
return nil, errf.NewFromErr(errf.DecodeRequestFailed, err)
}
if err := req.Validate(); err != nil {
return nil, errf.NewFromErr(errf.InvalidParameter, err)
}

info, err := s.client.HCService().Gcp.Account.GetBySecret(cts.Kit.Ctx, cts.Kit.Header(), req.GcpSecret)
if err != nil {
logs.Errorf("fail to get gcp account info, err: %v, rid: %s", err, cts.Kit.Rid)
return nil, err
}

return info.CloudProjectInfos, nil
}

func (s *service) getAzureAccountInfo(cts *rest.Contexts) (*account.AzureAccountInfoBySecretResp, error) {
req := new(accountset.AzureAccountInfoBySecretReq)
if err := cts.DecodeInto(req); err != nil {
return nil, errf.NewFromErr(errf.DecodeRequestFailed, err)
}
if err := req.Validate(); err != nil {
return nil, errf.NewFromErr(errf.InvalidParameter, err)
}

info, err := s.client.HCService().Azure.Account.GetBySecret(cts.Kit.Ctx, cts.Kit.Header(), req.AzureSecret)
if err != nil {
logs.Errorf("fail to get azure account info, err: %v, rid: %s", err, cts.Kit.Rid)
return nil, err
}
if len(info.SubscriptionInfos) < 1 {
logs.Errorf("get azure account info failed, no subscription found, rid: %s", cts.Kit.Rid)
return nil, errors.New("no subscription found")
}

subscription := info.SubscriptionInfos[0]
result := &account.AzureAccountInfoBySecretResp{
CloudSubscriptionID: subscription.CloudSubscriptionID,
CloudSubscriptionName: subscription.CloudSubscriptionName,
}
// 补全ApplicationName
for _, one := range info.ApplicationInfos {
if one.CloudApplicationID == req.CloudApplicationID {
result.CloudApplicationName = one.CloudApplicationName
break
}
}
// 没有拿到应用id的情况
if len(result.CloudApplicationName) == 0 {
logs.Errorf("failed to get application name, rid: %s", cts.Kit.Rid)
return nil, fmt.Errorf("failed to get application name")
KooKouse marked this conversation as resolved.
Show resolved Hide resolved
}

return result, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ func InitService(c *capability.Capability) {
h.Add("UpdateRootAccount", http.MethodPatch, "/root_accounts/{account_id}", svc.Update)
h.Add("AddRootAccount", http.MethodPost, "/root_accounts/add", svc.Add)

h.Add("QueryRootAccountBySecret", http.MethodPost, "/vendors/{vendor}/root_accounts/query_account_by_secret",
svc.QueryRootAccountBySecret)

h.Load(c.WebService)
}

Expand Down
58 changes: 50 additions & 8 deletions cmd/cloud-server/service/account/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package account

import (
"fmt"
"strings"

"hcm/pkg/api/cloud-server/account"
"hcm/pkg/api/core/cloud"
Expand Down Expand Up @@ -198,7 +199,7 @@ func (a *accountSvc) getAndCheckAwsAccountInfo(cts *rest.Contexts) (*cloud.AwsIn
return info, nil
}

func (a *accountSvc) getAndCheckAzureAccountInfo(cts *rest.Contexts) (*cloud.AzureInfoBySecret, error) {
func (a *accountSvc) getAndCheckAzureAccountInfo(cts *rest.Contexts) (*account.AzureAccountInfoBySecretResp, error) {
req := new(account.AzureAccountInfoBySecretReq)
if err := cts.DecodeInto(req); err != nil {
return nil, errf.NewFromErr(errf.DecodeRequestFailed, err)
Expand All @@ -212,18 +213,46 @@ func (a *accountSvc) getAndCheckAzureAccountInfo(cts *rest.Contexts) (*cloud.Azu
logs.Errorf("fail to get account info, err: %v, rid: %s", err, cts.Kit.Rid)
return nil, err
}

// 校验订阅数量,要求订阅数量刚好一个
if len(info.SubscriptionInfos) > 1 {
subs := make([]string, len(info.SubscriptionInfos))
for i, sub := range info.SubscriptionInfos {
subs[i] = "(" + sub.CloudSubscriptionID + ")" + sub.CloudSubscriptionName
}
logs.Errorf("more than one subscription found: %s, rid: %s", strings.Join(subs, ","), cts.Kit.Rid)
return nil, fmt.Errorf("more than one subscription found: %s", strings.Join(subs, ","))
}
subscription := info.SubscriptionInfos[0]
result := &account.AzureAccountInfoBySecretResp{
CloudSubscriptionID: subscription.CloudSubscriptionID,
CloudSubscriptionName: subscription.CloudSubscriptionName,
}
// 补全ApplicationName
for _, one := range info.ApplicationInfos {
if one.CloudApplicationID == req.CloudApplicationID {
result.CloudApplicationName = one.CloudApplicationName
break
}
}
// 没有拿到应用id的情况
if len(result.CloudApplicationName) == 0 {
logs.Errorf("failed to get application name, rid: %s", cts.Kit.Rid)
return nil, fmt.Errorf("failed to get application name")
KooKouse marked this conversation as resolved.
Show resolved Hide resolved
}

if req.DisableCheck {
return info, nil
return result, nil
}
if err = CheckDuplicateMainAccount(cts, a.client, enumor.Azure, enumor.ResourceAccount,
info.CloudSubscriptionID); err != nil {
subscription.CloudSubscriptionID); err != nil {
logs.Errorf("check whether main account duplicate fail, err: %v, rid: %s", err, cts.Kit.Rid)
return nil, err
}
return info, nil
return result, nil
}

func (a *accountSvc) getAndCheckGcpAccountInfo(cts *rest.Contexts) (*cloud.GcpInfoBySecret, error) {
func (a *accountSvc) getAndCheckGcpAccountInfo(cts *rest.Contexts) (*cloud.GcpProjectInfo, error) {
req := new(account.GcpAccountInfoBySecretReq)
if err := cts.DecodeInto(req); err != nil {
return nil, errf.NewFromErr(errf.DecodeRequestFailed, err)
Expand All @@ -237,15 +266,28 @@ func (a *accountSvc) getAndCheckGcpAccountInfo(cts *rest.Contexts) (*cloud.GcpIn
logs.Errorf("fail to get account info, err: %v, rid: %s", err, cts.Kit.Rid)
return nil, err
}

// 只能有一个对应的project,多project报错。
if len(info.CloudProjectInfos) > 1 {
projects := make([]string, len(info.CloudProjectInfos))
for i, project := range info.CloudProjectInfos {
projects[i] = "(" + project.CloudProjectID + ")" + project.CloudProjectName
}
logs.Errorf("more than one project found: %s, rid: %s", strings.Join(projects, ","), cts.Kit.Rid)
return nil, fmt.Errorf("more than one project found: %s", strings.Join(projects, ","))
}
result := info.CloudProjectInfos[0]

if req.DisableCheck {
return info, nil
return &result, nil
}

if err = CheckDuplicateMainAccount(cts, a.client, enumor.Gcp, enumor.ResourceAccount,
info.CloudProjectID); err != nil {
result.CloudProjectID); err != nil {
logs.Errorf("check whether main account duplicate fail, err: %v, rid: %s", err, cts.Kit.Rid)
return nil, err
}
return info, nil
return &result, nil
}

func (a *accountSvc) getAndCheckHuaWeiAccountInfo(cts *rest.Contexts) (*cloud.HuaWeiInfoBySecret, error) {
Expand Down
42 changes: 32 additions & 10 deletions cmd/hc-service/service/account/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package account

import (
"hcm/pkg/adaptor/types"
"hcm/pkg/api/core/cloud"
proto "hcm/pkg/api/hc-service/account"
"hcm/pkg/criteria/errf"
"hcm/pkg/rest"
Expand Down Expand Up @@ -168,28 +169,34 @@ func (svc *service) GcpAccountCheck(cts *rest.Contexts) (interface{}, error) {
return nil, err
}

if infoBySecret.CloudProjectID != req.CloudProjectID {
var projectInfo cloud.GcpProjectInfo
for _, info := range infoBySecret.CloudProjectInfos {
if info.CloudProjectID == req.CloudProjectID {
projectInfo = info
KooKouse marked this conversation as resolved.
Show resolved Hide resolved
break
}
}
if projectInfo.CloudProjectID != req.CloudProjectID {
return nil, errf.New(errf.InvalidParameter,
"CloudProjectID does not match the account to which the secret belongs")
}
if infoBySecret.CloudProjectName != req.CloudProjectName {
if projectInfo.CloudProjectName != req.CloudProjectName {
return nil, errf.New(errf.InvalidParameter,
"CloudProjectName does not match the account to which the secret belongs")
}
if infoBySecret.CloudServiceAccountID != req.CloudServiceAccountID {
if projectInfo.CloudServiceAccountID != req.CloudServiceAccountID {
return nil, errf.New(errf.InvalidParameter,
"CloudServiceAccountID does not match the account to which the secret belongs")
}
if infoBySecret.CloudServiceAccountName != req.CloudServiceAccountName {
if projectInfo.CloudServiceAccountName != req.CloudServiceAccountName {
return nil, errf.New(errf.InvalidParameter,
"CloudServiceAccountName does not match the account to which the secret belongs")
}
if infoBySecret.CloudServiceSecretID != req.CloudServiceSecretID {
if projectInfo.CloudServiceSecretID != req.CloudServiceSecretID {
return nil, errf.New(errf.InvalidParameter,
"CloudServiceSecretID does not match the account to which the secret belongs")
}

return nil, err
return nil, nil
}

// AzureAccountCheck ...
Expand Down Expand Up @@ -218,15 +225,30 @@ func (svc *service) AzureAccountCheck(cts *rest.Contexts) (interface{}, error) {
return nil, err
}

if infoBySecret.CloudSubscriptionID != req.CloudSubscriptionID {
var curSubscription cloud.AzureSubscriptionInfo
for _, subscription := range infoBySecret.SubscriptionInfos {
if subscription.CloudSubscriptionID == req.CloudSubscriptionID {
curSubscription = subscription
KooKouse marked this conversation as resolved.
Show resolved Hide resolved
break
}
}
if curSubscription.CloudSubscriptionID != req.CloudSubscriptionID {
return nil, errf.New(errf.InvalidParameter,
"CloudSubscriptionID does not match the account to which the secret belongs")
}
if infoBySecret.CloudSubscriptionName != req.CloudSubscriptionName {
if curSubscription.CloudSubscriptionName != req.CloudSubscriptionName {
return nil, errf.New(errf.InvalidParameter,
"CloudSubscriptionName does not match the account to which the secret belongs")
}
if infoBySecret.CloudApplicationName != req.CloudApplicationName {

var curApplication cloud.AzureApplicationInfo
for _, application := range infoBySecret.ApplicationInfos {
if application.CloudApplicationID == req.CloudApplicationID {
curApplication = application
break
}
}
if curApplication.CloudApplicationName != req.CloudApplicationName {
return nil, errf.New(errf.InvalidParameter,
"CloudApplicationName does not match the account to which the secret belongs")
}
Expand Down
1 change: 0 additions & 1 deletion cmd/hc-service/service/account/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ func (svc *service) GcpGetInfoBySecret(cts *rest.Contexts) (interface{}, error)
}
// 2. 云上信息获取
return client.GetAccountInfoBySecret(cts.Kit, req.CloudServiceSecretKey)

}

// AzureGetInfoBySecret 根据秘钥信息去云上获取账号信息
Expand Down
Loading