mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
fix(cloudid): vendor update form volcengine iam (#19856)
This commit is contained in:
@@ -88,7 +88,7 @@ require (
|
||||
k8s.io/client-go v0.19.3
|
||||
k8s.io/cluster-bootstrap v0.19.3
|
||||
moul.io/http2curl/v2 v2.3.0
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240401032225-9a152ed52202
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240402061507-4922cc681244
|
||||
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32
|
||||
yunion.io/x/jsonutils v1.0.1-0.20240203102553-4096f103b401
|
||||
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
|
||||
|
||||
@@ -1204,8 +1204,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240401032225-9a152ed52202 h1:nufuDeVPNxkYT8IbVbkwSb4SbGYxWV1w1DhrhR7++tE=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240401032225-9a152ed52202/go.mod h1:dsUESXIbXJ+/ywbNClhldOrbPOiBi2udrgOnB/ffoWk=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240402061507-4922cc681244 h1:b63UITGOFheDihKXXzF1fPX/Cgb/zDa3a93cs9pmmkA=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240402061507-4922cc681244/go.mod h1:dsUESXIbXJ+/ywbNClhldOrbPOiBi2udrgOnB/ffoWk=
|
||||
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32 h1:v7POYkQwo1XzOxBoIoRVr/k0V9Y5JyjpshlIFa9raug=
|
||||
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
|
||||
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
api "yunion.io/x/onecloud/pkg/apis/cloudid"
|
||||
@@ -436,7 +437,7 @@ func (base SProviderBaseProviderDriver) RequestCreateClouduser(ctx context.Conte
|
||||
|
||||
iUser, err := provider.CreateIClouduser(opts)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "CreateICloudgroup")
|
||||
return errors.Wrapf(err, "CreateIClouduser")
|
||||
}
|
||||
_, err = db.Update(user, func() error {
|
||||
user.ExternalId = iUser.GetGlobalId()
|
||||
@@ -537,8 +538,11 @@ func (base SProviderBaseProviderDriver) RequestCreateSAMLProvider(ctx context.Co
|
||||
opts := &cloudprovider.SAMLProviderCreateOptions{
|
||||
Metadata: models.SamlIdpInstance().GetMetadata(providers[i].Id),
|
||||
Name: strings.TrimPrefix(options.Options.ApiServer, "https://"),
|
||||
Desc: "create by cloudpods",
|
||||
}
|
||||
|
||||
log.Debugf("create saml provider for manager %s(%s) %s", providers[i].Name, providers[i].Id, opts.Metadata.String())
|
||||
|
||||
opts.Name = strings.TrimPrefix(opts.Name, "http://")
|
||||
|
||||
iSaml, err := iProvider.CreateICloudSAMLProvider(opts)
|
||||
@@ -577,17 +581,44 @@ func (base SProviderBaseProviderDriver) RequestCreateRoleForSamlUser(ctx context
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetSamlProvider")
|
||||
}
|
||||
policies, err := group.GetCloudpolicies()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetCloudpolicies")
|
||||
}
|
||||
roles, err := account.GetCloudroles(provider.Id)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetCloudroles")
|
||||
}
|
||||
for i := range roles {
|
||||
if roles[i].Status == apis.STATUS_AVAILABLE && len(roles[i].ExternalId) > 0 && roles[i].SAMLProviderId == samlProvider.Id {
|
||||
if roles[i].Status == apis.STATUS_AVAILABLE && len(roles[i].ExternalId) > 0 && roles[i].SAMLProviderId == samlProvider.Id && roles[i].CloudgroupId == group.Id {
|
||||
_, err := db.Update(user, func() error {
|
||||
user.CloudroleId = roles[i].Id
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
existPolicies := []string{}
|
||||
iRole, err := roles[i].GetICloudrole()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
iPolicies, err := iRole.GetICloudpolicies()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetICloudpolicies")
|
||||
}
|
||||
for _, policy := range iPolicies {
|
||||
existPolicies = append(existPolicies, policy.GetGlobalId())
|
||||
}
|
||||
for _, policy := range policies {
|
||||
if !utils.IsInStringArray(policy.ExternalId, existPolicies) {
|
||||
err = iRole.AttachPolicy(policy.ExternalId, policy.PolicyType)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "attach %s policy %s", policy.PolicyType, policy.ExternalId)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
iProvider, err := group.GetProvider()
|
||||
@@ -622,5 +653,14 @@ func (base SProviderBaseProviderDriver) RequestCreateRoleForSamlUser(ctx context
|
||||
user.CloudroleId = role.Id
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, policy := range policies {
|
||||
err := iRole.AttachPolicy(policy.ExternalId, policy.PolicyType)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "attach %s policy %s", policy.PolicyType, policy.ExternalId)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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 drivers
|
||||
|
||||
import (
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudid/models"
|
||||
)
|
||||
|
||||
type SVolcEngineDriver struct {
|
||||
SProviderBaseProviderDriver
|
||||
}
|
||||
|
||||
func (driver SVolcEngineDriver) GetProvider() string {
|
||||
return api.CLOUD_PROVIDER_VOLCENGINE
|
||||
}
|
||||
|
||||
func init() {
|
||||
models.RegisterProviderDriver(&SVolcEngineDriver{})
|
||||
}
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
@@ -29,7 +28,6 @@ import (
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
api "yunion.io/x/onecloud/pkg/apis/cloudid"
|
||||
computeapi "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
|
||||
"yunion.io/x/onecloud/pkg/cloudid/options"
|
||||
@@ -77,30 +75,6 @@ func (manager *SCloudaccountManager) GetResourceCount() ([]db.SScopeResourceCoun
|
||||
return []db.SScopeResourceCount{}, nil
|
||||
}
|
||||
|
||||
func (self *SCloudaccount) GetClouduserAccountName(name string) (string, string) {
|
||||
account := ""
|
||||
switch self.Provider {
|
||||
case computeapi.CLOUD_PROVIDER_ALIYUN:
|
||||
suffix := strings.TrimPrefix(self.IamLoginUrl, "https://signin.aliyun.com/")
|
||||
suffix = strings.TrimSuffix(suffix, "/login.htm")
|
||||
if len(suffix) > 0 {
|
||||
name = fmt.Sprintf("%s@%s", name, suffix)
|
||||
account = suffix
|
||||
}
|
||||
case computeapi.CLOUD_PROVIDER_QCLOUD, computeapi.CLOUD_PROVIDER_HUAWEI:
|
||||
u, _ := url.Parse(self.IamLoginUrl)
|
||||
if u != nil {
|
||||
account = u.Query().Get("account")
|
||||
}
|
||||
case computeapi.CLOUD_PROVIDER_AWS:
|
||||
account := strings.TrimPrefix(self.IamLoginUrl, "https://")
|
||||
if info := strings.Split(account, "."); len(info) > 0 {
|
||||
account = info[0]
|
||||
}
|
||||
}
|
||||
return account, name
|
||||
}
|
||||
|
||||
func (manager *SCloudaccountManager) GetCloudaccounts() ([]SCloudaccount, error) {
|
||||
accounts := []SCloudaccount{}
|
||||
q := manager.Query()
|
||||
|
||||
@@ -85,6 +85,7 @@ func GetMetadata(driver ICloudSAMLLoginDriver) ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "read body %s fail", metaUrl)
|
||||
}
|
||||
os.WriteFile(filePath, metaBytes, 0644)
|
||||
} else {
|
||||
return nil, errors.Wrapf(err, "read file %s fail", filePath)
|
||||
}
|
||||
|
||||
@@ -22,4 +22,5 @@ import (
|
||||
_ "yunion.io/x/onecloud/pkg/cloudid/saml/providers/google"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudid/saml/providers/huawei"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudid/saml/providers/qcloud"
|
||||
_ "yunion.io/x/onecloud/pkg/cloudid/saml/providers/volcengine"
|
||||
)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
package volcengine // import "yunion.io/x/onecloud/pkg/cloudid/saml/providers/volcengine"
|
||||
@@ -0,0 +1,95 @@
|
||||
// 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 volcengine
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/samlutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudid/models"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/samlutils/idp"
|
||||
)
|
||||
|
||||
func (d *SVolcEngineSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, managerId string, sp *idp.SSAMLServiceProvider, redirectUrl string) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
data := samlutils.SSAMLIdpInitiatedLoginData{}
|
||||
|
||||
provider, err := models.CloudproviderManager.FetchProvier(managerId)
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
|
||||
account, err := provider.GetCloudaccount()
|
||||
if err != nil {
|
||||
return data, errors.Wrapf(err, "GetCloudaccount")
|
||||
}
|
||||
|
||||
role, err := provider.GetRole(ctx, userCred.GetUserId())
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
|
||||
samlProvider, err := provider.GetSamlProvider()
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
|
||||
// trn:iam::${AccountID}:role/${RoleName},trn:iam::${AccountID}:saml-provider/${SAMLProviderName}
|
||||
roleStr := fmt.Sprintf("trn:iam::%s:role/%s,trn:iam::%s:saml-provider/%s", account.AccountId, role.ExternalId, account.AccountId, samlProvider.ExternalId)
|
||||
|
||||
data.NameId = role.Name
|
||||
data.NameIdFormat = samlutils.NAME_ID_FORMAT_TRANSIENT
|
||||
data.AudienceRestriction = "https://console.volcengine.com"
|
||||
for _, v := range []struct {
|
||||
name string
|
||||
friendlyName string
|
||||
value string
|
||||
}{
|
||||
{
|
||||
name: "https://www.volcengine.com/SAML/Attributes/Identity",
|
||||
friendlyName: "RoleEntitlement",
|
||||
value: roleStr,
|
||||
},
|
||||
{
|
||||
name: "https://www.volcengine.com/SAML/Attributes/SessionName",
|
||||
friendlyName: "SessionName",
|
||||
value: role.Name,
|
||||
},
|
||||
{
|
||||
name: "https://www.volcengine.com/SAML/Attributes/SessionDuration",
|
||||
friendlyName: "SessionDuration",
|
||||
value: "7200",
|
||||
},
|
||||
} {
|
||||
data.Attributes = append(data.Attributes, samlutils.SSAMLResponseAttribute{
|
||||
Name: v.name,
|
||||
FriendlyName: v.friendlyName,
|
||||
Values: []string{v.value},
|
||||
})
|
||||
}
|
||||
if len(redirectUrl) == 0 {
|
||||
redirectUrl = "https://console.volcengine.com"
|
||||
}
|
||||
data.RelayState = redirectUrl
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (d *SVolcEngineSAMLDriver) GetSpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, managerId string, sp *idp.SSAMLServiceProvider) (samlutils.SSAMLSpInitiatedLoginData, error) {
|
||||
return samlutils.SSAMLSpInitiatedLoginData{}, errors.ErrNotSupported
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// 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 volcengine
|
||||
|
||||
import (
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudid/models"
|
||||
)
|
||||
|
||||
type SVolcEngineSAMLDriver struct{}
|
||||
|
||||
func (d *SVolcEngineSAMLDriver) GetEntityID() string {
|
||||
return cloudprovider.SAML_ENTITY_ID_VOLC_ENGINE
|
||||
}
|
||||
|
||||
func (d *SVolcEngineSAMLDriver) GetMetadataFilename() string {
|
||||
return "volcengine.xml"
|
||||
}
|
||||
|
||||
func (d *SVolcEngineSAMLDriver) GetMetadataUrl() string {
|
||||
return "https://signin.volcengine.com/saml_role/SpMetadata.xml"
|
||||
}
|
||||
|
||||
func init() {
|
||||
models.Register(&SVolcEngineSAMLDriver{})
|
||||
}
|
||||
@@ -85,8 +85,8 @@ func StartService() {
|
||||
|
||||
if !opts.IsSlaveNode {
|
||||
cron := cronman.InitCronJobManager(true, options.Options.CronJobWorkerCount)
|
||||
cron.AddJobAtIntervalsWithStartRun("SyncCloudaccountResources", time.Duration(opts.CloudIdResourceSyncIntervalHours)*time.Hour, models.CloudaccountManager.SyncCloudaccountResources, false)
|
||||
cron.AddJobAtIntervalsWithStartRun("SyncCloudproviderResources", time.Duration(opts.CloudIdResourceSyncIntervalHours)*time.Hour, models.CloudproviderManager.SyncCloudproviderResources, false)
|
||||
cron.AddJobAtIntervalsWithStartRun("SyncCloudaccountResources", time.Duration(opts.CloudIdResourceSyncIntervalHours)*time.Hour, models.CloudaccountManager.SyncCloudaccountResources, true)
|
||||
cron.AddJobAtIntervalsWithStartRun("SyncCloudproviderResources", time.Duration(opts.CloudIdResourceSyncIntervalHours)*time.Hour, models.CloudproviderManager.SyncCloudproviderResources, true)
|
||||
|
||||
cron.AddJobEveryFewHour("AutoPurgeSplitable", 4, 30, 0, db.AutoPurgeSplitable, false)
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ func (self *CloudgroupSetPoliciesTask) OnInit(ctx context.Context, obj db.IStand
|
||||
|
||||
for _, policy := range input.Add {
|
||||
for id, role := range iRoleMap {
|
||||
err := role.AttachPolicy(policy.ExternalId)
|
||||
err := role.AttachPolicy(policy.ExternalId, policy.PolicyType)
|
||||
if err != nil {
|
||||
logclient.AddSimpleActionLog(roleMap[id], logclient.ACT_ATTACH_POLICY, err, self.GetUserCred(), false)
|
||||
}
|
||||
@@ -99,7 +99,7 @@ func (self *CloudgroupSetPoliciesTask) OnInit(ctx context.Context, obj db.IStand
|
||||
|
||||
for _, policy := range input.Del {
|
||||
for id, role := range iRoleMap {
|
||||
err := role.DetachPolicy(policy.ExternalId)
|
||||
err := role.DetachPolicy(policy.ExternalId, policy.PolicyType)
|
||||
if err != nil {
|
||||
logclient.AddSimpleActionLog(roleMap[id], logclient.ACT_DETACH_POLICY, err, self.GetUserCred(), false)
|
||||
}
|
||||
|
||||
@@ -82,9 +82,9 @@ func (self *ClouduserCreateTask) OnInit(ctx context.Context, obj db.IStandaloneM
|
||||
}{
|
||||
Id: self.Id,
|
||||
IamLoginUrl: account.IamLoginUrl,
|
||||
Account: account.AccountId,
|
||||
}
|
||||
msg.Password, _ = user.GetPassword()
|
||||
msg.Account, msg.Name = account.GetClouduserAccountName(user.Name)
|
||||
|
||||
notifyclient.NotifyWithContact(ctx, []string{user.Email}, npk.NotifyByEmail, npk.NotifyPriorityNormal, "CLOUD_USER_CREATED", jsonutils.Marshal(msg))
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -1472,7 +1472,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
|
||||
# sigs.k8s.io/yaml v1.2.0
|
||||
## explicit; go 1.12
|
||||
sigs.k8s.io/yaml
|
||||
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240401032225-9a152ed52202
|
||||
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20240402061507-4922cc681244
|
||||
## explicit; go 1.18
|
||||
yunion.io/x/cloudmux/pkg/apis
|
||||
yunion.io/x/cloudmux/pkg/apis/billing
|
||||
|
||||
+2
-2
@@ -1369,8 +1369,8 @@ type ICloudrole interface {
|
||||
GetSAMLProvider() string
|
||||
|
||||
GetICloudpolicies() ([]ICloudpolicy, error)
|
||||
AttachPolicy(id string) error
|
||||
DetachPolicy(id string) error
|
||||
AttachPolicy(policyName string, policyType string) error
|
||||
DetachPolicy(policyName string, policyType string) error
|
||||
|
||||
Delete() error
|
||||
}
|
||||
|
||||
+2
@@ -24,9 +24,11 @@ const (
|
||||
SAML_ENTITY_ID_HUAWEI_CLOUD = "https://auth.huaweicloud.com/"
|
||||
SAML_ENTITY_ID_GOOGLE = "google.com"
|
||||
SAML_ENTITY_ID_AZURE = "urn:federation:MicrosoftOnline"
|
||||
SAML_ENTITY_ID_VOLC_ENGINE = "https://www.volcengine.com/"
|
||||
)
|
||||
|
||||
type SAMLProviderCreateOptions struct {
|
||||
Name string
|
||||
Metadata samlutils.EntityDescriptor
|
||||
Desc string
|
||||
}
|
||||
|
||||
+5
-4
@@ -20,6 +20,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
)
|
||||
@@ -67,12 +68,12 @@ func (self *SRole) GetICloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRole) AttachPolicy(policyName string) error {
|
||||
return self.client.AttachPolicy2Role("System", policyName, self.RoleName)
|
||||
func (self *SRole) AttachPolicy(policyName string, policyType string) error {
|
||||
return self.client.AttachPolicy2Role(utils.Capitalize(policyType), policyName, self.RoleName)
|
||||
}
|
||||
|
||||
func (self *SRole) DetachPolicy(policyName string) error {
|
||||
return self.client.DetachPolicyFromRole("System", policyName, self.RoleName)
|
||||
func (self *SRole) DetachPolicy(policyName string, policyType string) error {
|
||||
return self.client.DetachPolicyFromRole(utils.Capitalize(policyType), policyName, self.RoleName)
|
||||
}
|
||||
|
||||
func (self *SRole) Delete() error {
|
||||
|
||||
+2
-2
@@ -88,11 +88,11 @@ func (self *SRole) GetSAMLProvider() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SRole) AttachPolicy(id string) error {
|
||||
func (self *SRole) AttachPolicy(id string, policyType string) error {
|
||||
return self.client.AttachRolePolicy(self.RoleName, self.client.getIamArn(id))
|
||||
}
|
||||
|
||||
func (self *SRole) DetachPolicy(id string) error {
|
||||
func (self *SRole) DetachPolicy(id string, polityType string) error {
|
||||
return self.client.DetachRolePolicy(self.RoleName, self.client.getIamArn(id))
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -128,11 +128,11 @@ func (self *SRole) GetICloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRole) AttachPolicy(id string) error {
|
||||
func (self *SRole) AttachPolicy(id string, policyType string) error {
|
||||
return self.client.AttachRolePolicy(self.RoleName, id)
|
||||
}
|
||||
|
||||
func (self *SRole) DetachPolicy(id string) error {
|
||||
func (self *SRole) DetachPolicy(id string, policyType string) error {
|
||||
return self.client.DetachRolePolicy(self.RoleName, id)
|
||||
}
|
||||
|
||||
|
||||
+298
@@ -0,0 +1,298 @@
|
||||
// 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 volcengine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type SGroup struct {
|
||||
client *SVolcEngineClient
|
||||
|
||||
Description string
|
||||
CreatedDate string
|
||||
UserGroupName string
|
||||
UpdateDate string
|
||||
AccountId string
|
||||
UserGroupId string
|
||||
}
|
||||
|
||||
func (self *SGroup) GetName() string {
|
||||
return self.UserGroupName
|
||||
}
|
||||
|
||||
func (self *SGroup) GetGlobalId() string {
|
||||
return self.UserGroupName
|
||||
}
|
||||
|
||||
func (self *SGroup) GetDescription() string {
|
||||
return self.Description
|
||||
}
|
||||
|
||||
func (self *SGroup) GetICloudusers() ([]cloudprovider.IClouduser, error) {
|
||||
users, err := self.client.ListUsersForGroup(self.UserGroupName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []cloudprovider.IClouduser{}
|
||||
for i := range users {
|
||||
users[i].client = self.client
|
||||
ret = append(ret, &users[i])
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SGroup) GetISystemCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
|
||||
policies, err := self.client.ListAttachedUserGroupPolicies(self.UserGroupName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []cloudprovider.ICloudpolicy{}
|
||||
for i := range policies {
|
||||
policies[i].client = self.client
|
||||
if policies[i].PolicyType == "System" {
|
||||
ret = append(ret, &policies[i])
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SGroup) GetICustomCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
|
||||
policies, err := self.client.ListAttachedUserGroupPolicies(self.UserGroupName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []cloudprovider.ICloudpolicy{}
|
||||
for i := range policies {
|
||||
policies[i].client = self.client
|
||||
if policies[i].PolicyType == "Custom" {
|
||||
ret = append(ret, &policies[i])
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SGroup) AddUser(name string) error {
|
||||
return self.client.AddUserToGroup(name, self.UserGroupName)
|
||||
}
|
||||
|
||||
func (self *SGroup) RemoveUser(name string) error {
|
||||
return self.client.RemoveUserFromGroup(name, self.UserGroupName)
|
||||
}
|
||||
|
||||
func (self *SGroup) AttachSystemPolicy(policyName string) error {
|
||||
return self.client.AttachUserGroupPolicy(self.UserGroupName, policyName, "System")
|
||||
}
|
||||
|
||||
func (self *SGroup) AttachCustomPolicy(policyName string) error {
|
||||
return self.client.AttachUserGroupPolicy(self.UserGroupName, policyName, "Custom")
|
||||
}
|
||||
|
||||
func (self *SGroup) DetachSystemPolicy(policyName string) error {
|
||||
return self.client.DetachUserGroupPolicy(self.UserGroupName, policyName, "System")
|
||||
}
|
||||
|
||||
func (self *SGroup) DetachCustomPolicy(policyName string) error {
|
||||
return self.client.DetachUserGroupPolicy(self.UserGroupName, policyName, "Custom")
|
||||
}
|
||||
|
||||
func (self *SGroup) Delete() error {
|
||||
return self.client.DeleteGroup(self.UserGroupName)
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) CreateICloudgroup(name string, desc string) (cloudprovider.ICloudgroup, error) {
|
||||
group, err := self.CreateGroup(name, desc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return group, nil
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) {
|
||||
groups, err := self.ListGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []cloudprovider.ICloudgroup{}
|
||||
for i := range groups {
|
||||
groups[i].client = self
|
||||
ret = append(ret, &groups[i])
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) ListGroups() ([]SGroup, error) {
|
||||
params := map[string]string{
|
||||
"Limit": "50",
|
||||
}
|
||||
offset := 0
|
||||
ret := []SGroup{}
|
||||
for {
|
||||
params["Offset"] = fmt.Sprintf("%d", offset)
|
||||
resp, err := client.iamRequest("", "ListGroups", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
part := struct {
|
||||
UserGroups []SGroup
|
||||
Total int
|
||||
}{}
|
||||
err = resp.Unmarshal(&part)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret = append(ret, part.UserGroups...)
|
||||
if len(part.UserGroups) == 0 || len(ret) >= part.Total {
|
||||
break
|
||||
}
|
||||
offset = len(ret)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) ListUsersForGroup(name string) ([]SUser, error) {
|
||||
params := map[string]string{
|
||||
"Limit": "50",
|
||||
"UserGroupName": name,
|
||||
}
|
||||
offset := 0
|
||||
ret := []SUser{}
|
||||
for {
|
||||
params["Offset"] = fmt.Sprintf("%d", offset)
|
||||
resp, err := client.iamRequest("", "ListUsersForGroup", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
part := struct {
|
||||
Users []SUser
|
||||
Total int
|
||||
}{}
|
||||
err = resp.Unmarshal(&part)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret = append(ret, part.Users...)
|
||||
if len(part.Users) == 0 || len(ret) >= part.Total {
|
||||
break
|
||||
}
|
||||
offset = len(ret)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) ListAttachedUserGroupPolicies(name string) ([]SPolicy, error) {
|
||||
params := map[string]string{
|
||||
"UserGroupName": name,
|
||||
}
|
||||
resp, err := client.iamRequest("", "ListAttachedUserGroupPolicies", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []SPolicy{}
|
||||
err = resp.Unmarshal(&ret, "AttachedPolicyMetadata")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) AttachUserGroupPolicy(name, policy, policyType string) error {
|
||||
params := map[string]string{
|
||||
"UserGroupName": name,
|
||||
"PolicyName": policy,
|
||||
"PolicyType": policyType,
|
||||
}
|
||||
_, err := client.iamRequest("", "AttachUserGroupPolicy", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) DetachUserGroupPolicy(name, policy, policyType string) error {
|
||||
params := map[string]string{
|
||||
"UserGroupName": name,
|
||||
"PolicyName": policy,
|
||||
"PolicyType": policyType,
|
||||
}
|
||||
_, err := client.iamRequest("", "DetachUserGroupPolicy", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) DeleteGroup(name string) error {
|
||||
params := map[string]string{
|
||||
"UserGroupName": name,
|
||||
}
|
||||
_, err := client.iamRequest("", "DeleteGroup", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) AddUserToGroup(user, group string) error {
|
||||
params := map[string]string{
|
||||
"UserGroupName": group,
|
||||
"UserName": user,
|
||||
}
|
||||
_, err := client.iamRequest("", "AddUserToGroup", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) RemoveUserFromGroup(user, group string) error {
|
||||
params := map[string]string{
|
||||
"UserGroupName": group,
|
||||
"UserName": user,
|
||||
}
|
||||
_, err := client.iamRequest("", "RemoveUserFromGroup", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) CreateGroup(name, desc string) (*SGroup, error) {
|
||||
params := map[string]string{
|
||||
"UserGroupName": name,
|
||||
"Description": desc,
|
||||
}
|
||||
resp, err := client.iamRequest("", "CreateGroup", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &SGroup{client: client}
|
||||
err = resp.Unmarshal(ret, "UserGroup")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) GetICloudgroupByName(name string) (cloudprovider.ICloudgroup, error) {
|
||||
group, err := client.GetGroup(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return group, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) GetGroup(name string) (*SGroup, error) {
|
||||
params := map[string]string{
|
||||
"UserGroupName": name,
|
||||
}
|
||||
resp, err := client.iamRequest("", "GetGroup", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &SGroup{client: client}
|
||||
err = resp.Unmarshal(ret, "UserGroup")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
// 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 volcengine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
const (
|
||||
POLICY_TYPE_SYSTEM = "System"
|
||||
POLICY_TYPE_CUSTOM = "Custom"
|
||||
)
|
||||
|
||||
type SPolicy struct {
|
||||
client *SVolcEngineClient
|
||||
|
||||
CreateDate string
|
||||
UpdateDate string
|
||||
PolicyDocument string
|
||||
Status string
|
||||
PolicyName string
|
||||
PolicyType string
|
||||
Description string
|
||||
Category string
|
||||
IsServiceRolePolicy int
|
||||
AttachmentCount int
|
||||
}
|
||||
|
||||
func (policy *SPolicy) GetName() string {
|
||||
return policy.PolicyName
|
||||
}
|
||||
|
||||
func (policy *SPolicy) GetDescription() string {
|
||||
return policy.Description
|
||||
}
|
||||
|
||||
func (policy *SPolicy) GetGlobalId() string {
|
||||
return policy.PolicyName
|
||||
}
|
||||
|
||||
func (policy *SPolicy) UpdateDocument(document *jsonutils.JSONDict) error {
|
||||
return cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (policy *SPolicy) Delete() error {
|
||||
return policy.client.DeletePolicy(policy.PolicyName)
|
||||
}
|
||||
|
||||
func (policy *SPolicy) GetDocument() (*jsonutils.JSONDict, error) {
|
||||
doc, err := jsonutils.Parse([]byte(policy.PolicyDocument))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret, ok := doc.(*jsonutils.JSONDict)
|
||||
if !ok {
|
||||
return nil, errors.Wrapf(cloudprovider.ErrNotSupported, policy.PolicyDocument)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) GetISystemCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
|
||||
policies, err := self.ListPolicies("System")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []cloudprovider.ICloudpolicy{}
|
||||
for i := range policies {
|
||||
policies[i].client = self
|
||||
ret = append(ret, &policies[i])
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) GetICustomCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
|
||||
policies, err := self.ListPolicies("Custom")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []cloudprovider.ICloudpolicy{}
|
||||
for i := range policies {
|
||||
policies[i].client = self
|
||||
ret = append(ret, &policies[i])
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) ListPolicies(scope string) ([]SPolicy, error) {
|
||||
params := map[string]string{
|
||||
"Limit": "50",
|
||||
}
|
||||
if len(scope) > 0 {
|
||||
params["Scope"] = scope
|
||||
}
|
||||
offset := 0
|
||||
ret := []SPolicy{}
|
||||
for {
|
||||
params["Offset"] = fmt.Sprintf("%d", offset)
|
||||
resp, err := client.iamRequest("", "ListPolicies", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
part := struct {
|
||||
PolicyMetadata []SPolicy
|
||||
Total int
|
||||
}{}
|
||||
err = resp.Unmarshal(&part)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret = append(ret, part.PolicyMetadata...)
|
||||
if len(part.PolicyMetadata) == 0 || len(ret) >= part.Total {
|
||||
break
|
||||
}
|
||||
offset = len(ret)
|
||||
}
|
||||
return ret, nil
|
||||
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) DeletePolicy(name string) error {
|
||||
params := map[string]string{
|
||||
"PolicyName": name,
|
||||
}
|
||||
_, err := client.iamRequest("", "DeletePolicy", params)
|
||||
return err
|
||||
}
|
||||
+5
-5
@@ -36,8 +36,8 @@ type SProject struct {
|
||||
Path string
|
||||
DisplayName string
|
||||
Description string
|
||||
CreateDate time.Time
|
||||
UpdateDate time.Time
|
||||
CreateDate string
|
||||
UpdateDate string
|
||||
Status string
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ func (client *SVolcEngineClient) GetProject(name string) (*SProject, error) {
|
||||
params := map[string]string{
|
||||
"ProjectName": name,
|
||||
}
|
||||
body, err := client.iamRequest("", "GetProject", params)
|
||||
body, err := client.iam20210801Request("", "GetProject", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -97,7 +97,7 @@ func (client *SVolcEngineClient) ListProjects(limit int, offset int) ([]SProject
|
||||
"Limit": fmt.Sprintf("%d", limit),
|
||||
"Offset": fmt.Sprintf("%d", offset),
|
||||
}
|
||||
resp, err := client.iamRequest("", "ListProjects", params)
|
||||
resp, err := client.iam20210801Request("", "ListProjects", params)
|
||||
if err != nil {
|
||||
return nil, 0, errors.Wrap(err, "iamRequest.ListProjects")
|
||||
}
|
||||
@@ -123,7 +123,7 @@ func (client *SVolcEngineClient) CreateProject(name string) (*SProject, error) {
|
||||
"DisplayName": name,
|
||||
"ProjectName": name,
|
||||
}
|
||||
resp, err := client.iamRequest("", "CreateProject", params)
|
||||
resp, err := client.iam20210801Request("", "CreateProject", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "CreateProject")
|
||||
}
|
||||
|
||||
+78
@@ -16,6 +16,7 @@ package volcengine
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
@@ -66,6 +67,10 @@ func (f *SVolcEngineProviderFactory) ValidateUpdateCloudaccountCredential(ctx co
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (factory *SVolcEngineProviderFactory) IsSupportSAMLAuth() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func validateClientCloudenv(client *volcengine.SVolcEngineClient) error {
|
||||
regions := client.GetIRegions()
|
||||
if len(regions) == 0 {
|
||||
@@ -210,3 +215,76 @@ func (self *SVolcEngineProvider) GetVersion() string {
|
||||
func (self *SVolcEngineProvider) GetMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
|
||||
return self.client.GetMetrics(opts)
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) CreateICloudSAMLProvider(opts *cloudprovider.SAMLProviderCreateOptions) (cloudprovider.ICloudSAMLProvider, error) {
|
||||
sp, err := self.client.CreateSAMLProvider(opts.Name, opts.Metadata.String(), opts.Desc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "CreateSAMLProvider")
|
||||
}
|
||||
return sp, nil
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) GetICloudSAMLProviders() ([]cloudprovider.ICloudSAMLProvider, error) {
|
||||
return self.client.GetICloudSAMLProviders()
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) GetICloudroles() ([]cloudprovider.ICloudrole, error) {
|
||||
return self.client.GetICloudroles()
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) GetICloudroleById(id string) (cloudprovider.ICloudrole, error) {
|
||||
role, err := self.client.GetRole(id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetRole(%s)", id)
|
||||
}
|
||||
return role, nil
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) CreateICloudrole(opts *cloudprovider.SRoleCreateOptions) (cloudprovider.ICloudrole, error) {
|
||||
stetement := fmt.Sprintf(`{"Statement":[{"Effect":"Allow","Action":["sts:AssumeRoleWithSAML"],"Principal":{"Federated":["trn:iam::%s:saml-provider/%s"]}}]}`, self.client.GetAccountId(), opts.SAMLProvider)
|
||||
role, err := self.client.CreateRole(opts.Name, stetement, opts.Desc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "CreateRole")
|
||||
}
|
||||
return role, nil
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) CreateIClouduser(conf *cloudprovider.SClouduserCreateConfig) (cloudprovider.IClouduser, error) {
|
||||
return self.client.CreateIClouduser(conf)
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) GetICloudusers() ([]cloudprovider.IClouduser, error) {
|
||||
return self.client.GetICloudusers()
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) GetIClouduserByName(name string) (cloudprovider.IClouduser, error) {
|
||||
return self.client.GetIClouduserByName(name)
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) {
|
||||
return self.client.GetICloudgroups()
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) CreateICloudgroup(name, desc string) (cloudprovider.ICloudgroup, error) {
|
||||
return self.client.CreateICloudgroup(name, desc)
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) GetICloudgroupByName(name string) (cloudprovider.ICloudgroup, error) {
|
||||
return self.client.GetICloudgroupByName(name)
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) GetISystemCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
|
||||
return self.client.GetISystemCloudpolicies()
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) GetICustomCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
|
||||
return self.client.GetICustomCloudpolicies()
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) CreateICloudpolicy(opts *cloudprovider.SCloudpolicyCreateOptions) (cloudprovider.ICloudpolicy, error) {
|
||||
return nil, cloudprovider.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (self *SVolcEngineProvider) GetSamlEntityId() string {
|
||||
return cloudprovider.SAML_ENTITY_ID_VOLC_ENGINE
|
||||
}
|
||||
|
||||
+224
@@ -0,0 +1,224 @@
|
||||
// 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 volcengine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
)
|
||||
|
||||
type PolicyDocument struct {
|
||||
Statement []struct {
|
||||
Effect string
|
||||
Action []string
|
||||
Principal struct {
|
||||
Federated []string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type SRole struct {
|
||||
client *SVolcEngineClient
|
||||
|
||||
RoleName string
|
||||
DisplayName string
|
||||
TrustPolicyDocument string
|
||||
Description string
|
||||
}
|
||||
|
||||
func (self *SRole) GetGlobalId() string {
|
||||
return self.RoleName
|
||||
}
|
||||
|
||||
func (self *SRole) GetName() string {
|
||||
return self.RoleName
|
||||
}
|
||||
|
||||
func (self *SRole) GetICloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
|
||||
policies, err := self.client.ListAttachedRolePolicies(self.RoleName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []cloudprovider.ICloudpolicy{}
|
||||
for i := range policies {
|
||||
policies[i].client = self.client
|
||||
ret = append(ret, &policies[i])
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SRole) AttachPolicy(policyName string, policyType string) error {
|
||||
return self.client.AttachRolePolicy(self.RoleName, policyName, utils.Capitalize(policyType))
|
||||
}
|
||||
|
||||
func (self *SRole) DetachPolicy(policyName string, policyType string) error {
|
||||
return self.client.DetachRolePolicy(self.RoleName, policyName, utils.Capitalize(policyType))
|
||||
}
|
||||
|
||||
func (self *SRole) Delete() error {
|
||||
return self.client.DeleteRole(self.RoleName)
|
||||
}
|
||||
|
||||
func (self *SRole) GetDocument() *jsonutils.JSONDict {
|
||||
doc, err := jsonutils.ParseString(self.TrustPolicyDocument)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return doc.(*jsonutils.JSONDict)
|
||||
}
|
||||
|
||||
func (self *SRole) GetSAMLProvider() string {
|
||||
document := self.GetDocument()
|
||||
if document == nil {
|
||||
return ""
|
||||
}
|
||||
info := &PolicyDocument{}
|
||||
document.Unmarshal(info)
|
||||
for _, statement := range info.Statement {
|
||||
for _, sp := range statement.Principal.Federated {
|
||||
info := strings.Split(sp, "/")
|
||||
if len(info) == 2 {
|
||||
return info[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) GetICloudroles() ([]cloudprovider.ICloudrole, error) {
|
||||
roles, err := self.ListRoles()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []cloudprovider.ICloudrole{}
|
||||
for i := range roles {
|
||||
roles[i].client = self
|
||||
ret = append(ret, &roles[i])
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) ListRoles() ([]SRole, error) {
|
||||
params := map[string]string{
|
||||
"Limit": "50",
|
||||
}
|
||||
offset := 0
|
||||
ret := []SRole{}
|
||||
for {
|
||||
params["Offset"] = fmt.Sprintf("%d", offset)
|
||||
resp, err := client.iamRequest("", "ListRoles", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
part := struct {
|
||||
RoleMetadata []SRole
|
||||
Total int
|
||||
}{}
|
||||
err = resp.Unmarshal(&part)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret = append(ret, part.RoleMetadata...)
|
||||
if len(part.RoleMetadata) == 0 || len(ret) >= part.Total {
|
||||
break
|
||||
}
|
||||
offset = len(ret)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) GetRole(name string) (*SRole, error) {
|
||||
params := map[string]string{
|
||||
"RoleName": name,
|
||||
}
|
||||
resp, err := client.iamRequest("", "GetRole", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &SRole{client: client}
|
||||
err = resp.Unmarshal(ret, "Role")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) CreateRole(name, statement, desc string) (*SRole, error) {
|
||||
params := map[string]string{
|
||||
"RoleName": name,
|
||||
"DisplayName": name,
|
||||
"TrustPolicyDocument": statement,
|
||||
"Description": desc,
|
||||
}
|
||||
resp, err := client.iamRequest("", "CreateRole", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &SRole{client: client}
|
||||
err = resp.Unmarshal(ret, "Role")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) DeleteRole(name string) error {
|
||||
params := map[string]string{
|
||||
"RoleName": name,
|
||||
}
|
||||
_, err := client.iamRequest("", "DeleteRole", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) ListAttachedRolePolicies(name string) ([]SPolicy, error) {
|
||||
params := map[string]string{
|
||||
"RoleName": name,
|
||||
}
|
||||
resp, err := client.iamRequest("", "ListAttachedRolePolicies", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []SPolicy{}
|
||||
err = resp.Unmarshal(&ret, "AttachedPolicyMetadata")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) AttachRolePolicy(name, policy, policyType string) error {
|
||||
params := map[string]string{
|
||||
"RoleName": name,
|
||||
"PolicyName": policy,
|
||||
"PolicyType": policyType,
|
||||
}
|
||||
_, err := client.iamRequest("", "AttachRolePolicy", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) DetachRolePolicy(name, policy, policyType string) error {
|
||||
params := map[string]string{
|
||||
"RoleName": name,
|
||||
"PolicyName": policy,
|
||||
"PolicyType": policyType,
|
||||
}
|
||||
_, err := client.iamRequest("", "DetachRolePolicy", params)
|
||||
return err
|
||||
}
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
// Copyright 2023 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 volcengine
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/apis"
|
||||
"yunion.io/x/cloudmux/pkg/apis/cloudid"
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/cloudmux/pkg/multicloud"
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/httputils"
|
||||
"yunion.io/x/pkg/util/samlutils"
|
||||
)
|
||||
|
||||
type SSamlProvider struct {
|
||||
multicloud.SResourceBase
|
||||
multicloud.STagBase
|
||||
client *SVolcEngineClient
|
||||
|
||||
Trn string
|
||||
EncodedSAMLMetadataDocument string
|
||||
ProviderName string
|
||||
SAMLProviderName string
|
||||
IdpType string
|
||||
SSOType string
|
||||
Status string
|
||||
Description string
|
||||
}
|
||||
|
||||
func (self *SSamlProvider) GetName() string {
|
||||
if len(self.SAMLProviderName) > 0 {
|
||||
return self.SAMLProviderName
|
||||
}
|
||||
return self.ProviderName
|
||||
}
|
||||
|
||||
func (self *SSamlProvider) GetGlobalId() string {
|
||||
if len(self.SAMLProviderName) > 0 {
|
||||
return self.SAMLProviderName
|
||||
}
|
||||
return self.ProviderName
|
||||
}
|
||||
|
||||
func (self *SSamlProvider) GetId() string {
|
||||
if len(self.SAMLProviderName) > 0 {
|
||||
return self.SAMLProviderName
|
||||
}
|
||||
return self.ProviderName
|
||||
}
|
||||
|
||||
func (self *SSamlProvider) GetAuthUrl(apiServer string) string {
|
||||
input := samlutils.SIdpInitiatedLoginInput{
|
||||
EntityID: cloudprovider.SAML_ENTITY_ID_VOLC_ENGINE,
|
||||
IdpId: self.client.cpcfg.AccountId,
|
||||
}
|
||||
return httputils.JoinPath(apiServer, cloudid.SAML_IDP_PREFIX, fmt.Sprintf("sso?%s", jsonutils.Marshal(input).QueryString()))
|
||||
}
|
||||
|
||||
func (self *SSamlProvider) Delete() error {
|
||||
return self.client.DeleteSamlProvider(self.GetName())
|
||||
}
|
||||
|
||||
func (self *SSamlProvider) GetStatus() string {
|
||||
return apis.STATUS_AVAILABLE
|
||||
}
|
||||
|
||||
func (self *SSamlProvider) GetMetadataDocument() (*samlutils.EntityDescriptor, error) {
|
||||
provider, err := self.client.GetSamlProvider(self.GetName())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := base64.StdEncoding.DecodeString(provider.EncodedSAMLMetadataDocument)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret, err := samlutils.ParseMetadata(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ret, nil
|
||||
}
|
||||
|
||||
func (self *SSamlProvider) UpdateMetadata(metadata samlutils.EntityDescriptor) error {
|
||||
return self.client.UpdateSAMLProvider(self.GetName(), metadata.String())
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) GetSamlProviders() ([]SSamlProvider, error) {
|
||||
params := map[string]string{}
|
||||
params["Limit"] = "50"
|
||||
ret := []SSamlProvider{}
|
||||
offset := 0
|
||||
for {
|
||||
params["Offset"] = fmt.Sprintf("%d", offset)
|
||||
resp, err := self.iamRequest("", "ListSAMLProviders", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
part := struct {
|
||||
SAMLProviders []SSamlProvider
|
||||
Total int
|
||||
}{}
|
||||
err = resp.Unmarshal(&part)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret = append(ret, part.SAMLProviders...)
|
||||
if len(ret) >= part.Total || len(part.SAMLProviders) == 0 {
|
||||
break
|
||||
}
|
||||
offset = len(ret)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) GetICloudSAMLProviders() ([]cloudprovider.ICloudSAMLProvider, error) {
|
||||
providers, err := self.GetSamlProviders()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []cloudprovider.ICloudSAMLProvider{}
|
||||
for i := range providers {
|
||||
providers[i].client = self
|
||||
ret = append(ret, &providers[i])
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) DeleteSamlProvider(name string) error {
|
||||
params := map[string]string{
|
||||
"SAMLProviderName": name,
|
||||
}
|
||||
_, err := self.iamRequest("", "DeleteSAMLProvider", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) CreateSAMLProvider(name, metadata, desc string) (*SSamlProvider, error) {
|
||||
name = strings.ReplaceAll(name, ":", "_")
|
||||
params := map[string]string{
|
||||
"EncodedSAMLMetadataDocument": base64.StdEncoding.EncodeToString([]byte(metadata)),
|
||||
"SAMLProviderName": name,
|
||||
"SSOType": "1",
|
||||
"Status": "1",
|
||||
}
|
||||
if len(desc) > 0 {
|
||||
params["Description"] = desc
|
||||
}
|
||||
resp, err := self.iamRequest("", "CreateSAMLProvider", params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "CreateSAMLProvider")
|
||||
}
|
||||
sp := &SSamlProvider{client: self}
|
||||
err = resp.Unmarshal(sp)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "resp.Unmarshal")
|
||||
}
|
||||
return sp, nil
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) GetSamlProvider(name string) (*SSamlProvider, error) {
|
||||
params := map[string]string{
|
||||
"SAMLProviderName": name,
|
||||
}
|
||||
resp, err := self.iamRequest("", "GetSAMLProvider", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &SSamlProvider{client: self}
|
||||
err = resp.Unmarshal(ret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) UpdateSAMLProvider(name, metadata string) error {
|
||||
name = strings.ReplaceAll(name, ":", "_")
|
||||
params := map[string]string{
|
||||
"EncodedSAMLMetadataDocument": base64.StdEncoding.EncodeToString([]byte(metadata)),
|
||||
"SAMLProviderName": name,
|
||||
"Status": "1",
|
||||
}
|
||||
_, err := self.iamRequest("", "UpdateSAMLProvider", params)
|
||||
return err
|
||||
}
|
||||
+308
-20
@@ -15,15 +15,20 @@
|
||||
package volcengine
|
||||
|
||||
import (
|
||||
"time"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/cloudmux/pkg/multicloud"
|
||||
"yunion.io/x/pkg/errors"
|
||||
)
|
||||
|
||||
type SUser struct {
|
||||
multicloud.SBaseClouduser
|
||||
client *SVolcEngineClient
|
||||
|
||||
Id int
|
||||
CreateDate time.Time
|
||||
UpdateDate time.Time
|
||||
CreateDate string
|
||||
UpdateDate string
|
||||
Status string
|
||||
AccountId string
|
||||
UserName string
|
||||
@@ -37,27 +42,310 @@ type SUser struct {
|
||||
Source string
|
||||
}
|
||||
|
||||
type SCallerIdentity struct {
|
||||
AccountId string
|
||||
UserId string
|
||||
RoleId string
|
||||
PrincipalId string
|
||||
IdentityType string
|
||||
func (user *SUser) GetGlobalId() string {
|
||||
return user.UserName
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) GetCallerIdentity() (*SCallerIdentity, error) {
|
||||
// sys is not currently supported
|
||||
params := map[string]string{}
|
||||
body, err := client.iamRequest("", "ListUsers", params)
|
||||
func (user *SUser) GetName() string {
|
||||
return user.UserName
|
||||
}
|
||||
|
||||
func (user *SUser) GetEmailAddr() string {
|
||||
return user.Email
|
||||
}
|
||||
|
||||
func (user *SUser) GetInviteUrl() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (user *SUser) Delete() error {
|
||||
return user.client.DeleteUser(user.UserName)
|
||||
}
|
||||
|
||||
func (user *SUser) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) {
|
||||
groups, err := user.client.ListGroupsForUser(user.UserName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
id := &SCallerIdentity{}
|
||||
users := []SUser{}
|
||||
err = body.Unmarshal(&users, "UserMetadata")
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "resp.Unmarshal")
|
||||
ret := []cloudprovider.ICloudgroup{}
|
||||
for i := range groups {
|
||||
groups[i].client = user.client
|
||||
ret = append(ret, &groups[i])
|
||||
}
|
||||
id.AccountId = users[0].AccountId
|
||||
return id, nil
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (user *SUser) GetISystemCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
|
||||
policies, err := user.client.ListAttachedUserPolicies(user.UserName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []cloudprovider.ICloudpolicy{}
|
||||
for i := range policies {
|
||||
policies[i].client = user.client
|
||||
if policies[i].PolicyType == "System" {
|
||||
ret = append(ret, &policies[i])
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (user *SUser) GetICustomCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
|
||||
policies, err := user.client.ListAttachedUserPolicies(user.UserName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []cloudprovider.ICloudpolicy{}
|
||||
for i := range policies {
|
||||
policies[i].client = user.client
|
||||
if policies[i].PolicyType == "Custom" {
|
||||
ret = append(ret, &policies[i])
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (user *SUser) IsConsoleLogin() bool {
|
||||
profile, err := user.client.GetLoginProfile(user.UserName)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return profile.LoginAllowed
|
||||
}
|
||||
|
||||
func (user *SUser) ResetPassword(password string) error {
|
||||
return user.client.UpdateLoginProfile(user.UserName, password, nil)
|
||||
}
|
||||
|
||||
func (user *SUser) AttachSystemPolicy(policyName string) error {
|
||||
return user.client.AttachUserPolicy(user.UserName, policyName, "System")
|
||||
}
|
||||
|
||||
func (user *SUser) AttachCustomPolicy(policyName string) error {
|
||||
return user.client.AttachUserPolicy(user.UserName, policyName, "Custom")
|
||||
}
|
||||
|
||||
func (user *SUser) DetachSystemPolicy(policyName string) error {
|
||||
return user.client.DetachUserPolicy(user.UserName, policyName, "System")
|
||||
}
|
||||
|
||||
func (user *SUser) DetachCustomPolicy(policyName string) error {
|
||||
return user.client.DetachUserPolicy(user.UserName, policyName, "Custom")
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) GetUsers() ([]SUser, error) {
|
||||
params := map[string]string{
|
||||
"Limit": "50",
|
||||
}
|
||||
offset := 0
|
||||
ret := []SUser{}
|
||||
for {
|
||||
params["Offset"] = fmt.Sprintf("%d", offset)
|
||||
resp, err := client.iamRequest("", "ListUsers", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
part := struct {
|
||||
UserMetadata []SUser
|
||||
Total int
|
||||
}{}
|
||||
err = resp.Unmarshal(&part)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret = append(ret, part.UserMetadata...)
|
||||
if len(part.UserMetadata) == 0 || len(ret) >= part.Total {
|
||||
break
|
||||
}
|
||||
offset = len(ret)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) DeleteUser(name string) error {
|
||||
params := map[string]string{
|
||||
"UserName": name,
|
||||
}
|
||||
_, err := self.iamRequest("", "DeleteUser", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) GetICloudusers() ([]cloudprovider.IClouduser, error) {
|
||||
users, err := client.GetUsers()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []cloudprovider.IClouduser{}
|
||||
for i := range users {
|
||||
users[i].client = client
|
||||
ret = append(ret, &users[i])
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) CreateIClouduser(opts *cloudprovider.SClouduserCreateConfig) (cloudprovider.IClouduser, error) {
|
||||
user, err := client.CreateUser(opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = client.CreateLoginProfile(user.UserName, opts.Password, &opts.IsConsoleLogin)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "CreateLoginProfile")
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) CreateUser(opts *cloudprovider.SClouduserCreateConfig) (*SUser, error) {
|
||||
params := map[string]string{
|
||||
"UserName": opts.Name,
|
||||
"Description": opts.Desc,
|
||||
"Email": opts.Email,
|
||||
"MobilePhone": opts.MobilePhone,
|
||||
}
|
||||
resp, err := self.iamRequest("", "CreateUser", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &SUser{client: self}
|
||||
err = resp.Unmarshal(ret, "User")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
type LoginProfile struct {
|
||||
PasswordResetRequired bool
|
||||
LoginAllowed bool
|
||||
LastLoginDate string
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) GetLoginProfile(name string) (*LoginProfile, error) {
|
||||
params := map[string]string{
|
||||
"UserName": name,
|
||||
}
|
||||
resp, err := self.iamRequest("", "GetLoginProfile", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &LoginProfile{}
|
||||
err = resp.Unmarshal(ret, "LoginProfile")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) CreateLoginProfile(name, password string, loginAllowd *bool) error {
|
||||
params := map[string]string{
|
||||
"UserName": name,
|
||||
"Password": password,
|
||||
}
|
||||
if loginAllowd != nil {
|
||||
params["LoginAllowed"] = fmt.Sprintf("%v", *loginAllowd)
|
||||
}
|
||||
_, err := self.iamRequest("", "CreateLoginProfile", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (self *SVolcEngineClient) UpdateLoginProfile(name, password string, loginAllowd *bool) error {
|
||||
params := map[string]string{
|
||||
"UserName": name,
|
||||
"Password": password,
|
||||
}
|
||||
if loginAllowd != nil {
|
||||
params["LoginAllowed"] = fmt.Sprintf("%v", *loginAllowd)
|
||||
}
|
||||
_, err := self.iamRequest("", "UpdateLoginProfile", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) ListGroupsForUser(name string) ([]SGroup, error) {
|
||||
params := map[string]string{
|
||||
"Limit": "50",
|
||||
"UserName": name,
|
||||
}
|
||||
offset := 0
|
||||
ret := []SGroup{}
|
||||
for {
|
||||
params["Offset"] = fmt.Sprintf("%d", offset)
|
||||
resp, err := client.iamRequest("", "ListGroupsForUser", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
part := struct {
|
||||
UserGroups []SGroup
|
||||
Total int
|
||||
}{}
|
||||
err = resp.Unmarshal(&part)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret = append(ret, part.UserGroups...)
|
||||
if len(part.UserGroups) == 0 || len(ret) >= part.Total {
|
||||
break
|
||||
}
|
||||
offset = len(ret)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) ListAttachedUserPolicies(name string) ([]SPolicy, error) {
|
||||
params := map[string]string{
|
||||
"UserName": name,
|
||||
}
|
||||
resp, err := client.iamRequest("", "ListAttachedUserPolicies", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := []SPolicy{}
|
||||
err = resp.Unmarshal(&ret, "AttachedPolicyMetadata")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) AttachUserPolicy(name, policy, policyType string) error {
|
||||
params := map[string]string{
|
||||
"UserName": name,
|
||||
"PolicyName": policy,
|
||||
"PolicyType": policyType,
|
||||
}
|
||||
_, err := client.iamRequest("", "AttachUserPolicy", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) DetachUserPolicy(name, policy, policyType string) error {
|
||||
params := map[string]string{
|
||||
"UserName": name,
|
||||
"PolicyName": policy,
|
||||
"PolicyType": policyType,
|
||||
}
|
||||
_, err := client.iamRequest("", "DetachUserPolicy", params)
|
||||
return err
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) GetIClouduserByName(name string) (cloudprovider.IClouduser, error) {
|
||||
user, err := client.GetUser(name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) GetUser(name string) (*SUser, error) {
|
||||
params := map[string]string{
|
||||
"UserName": name,
|
||||
}
|
||||
resp, err := client.iamRequest("", "GetUser", params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ret := &SUser{client: client}
|
||||
err = resp.Unmarshal(ret, "User")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
+93
-38
@@ -18,14 +18,18 @@ import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/color"
|
||||
tos "github.com/volcengine/ve-tos-golang-sdk/v2/tos"
|
||||
sdk "github.com/volcengine/volc-sdk-golang/base"
|
||||
"moul.io/http2curl/v2"
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
@@ -42,7 +46,7 @@ const (
|
||||
CLOUD_PROVIDER_VOLCENGINE_EN = "VolcEngine"
|
||||
|
||||
VOLCENGINE_API_VERSION = "2020-04-01"
|
||||
VOLCENGINE_IAM_API_VERSION = "2021-08-01"
|
||||
VOLCENGINE_IAM_API_VERSION = "2018-01-01"
|
||||
VOLCENGINE_OBSERVE_API_VERSION = "2018-01-01"
|
||||
VOLCENGINE_BILLING_API_VERSION = "2022-01-01"
|
||||
|
||||
@@ -98,10 +102,6 @@ func (cfg *VolcEngineClientConfig) Debug(debug bool) *VolcEngineClientConfig {
|
||||
return cfg
|
||||
}
|
||||
|
||||
func (cfg VolcEngineClientConfig) Copy() VolcEngineClientConfig {
|
||||
return cfg
|
||||
}
|
||||
|
||||
type SVolcEngineClient struct {
|
||||
*VolcEngineClientConfig
|
||||
|
||||
@@ -180,11 +180,16 @@ func (client *SVolcEngineClient) GetAccountId() string {
|
||||
if len(client.ownerId) > 0 {
|
||||
return client.ownerId
|
||||
}
|
||||
caller, err := client.GetCallerIdentity()
|
||||
|
||||
toscli, err := client.getTosClient(VOLCENGINE_DEFAULT_REGION)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
client.ownerId = caller.AccountId
|
||||
out, err := toscli.ListBuckets(context.Background(), &tos.ListBucketsInput{})
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
client.ownerId = out.Owner.ID
|
||||
return client.ownerId
|
||||
}
|
||||
|
||||
@@ -229,7 +234,7 @@ func (client *SVolcEngineClient) GetProjects() ([]SProject, error) {
|
||||
if len(client.projects) >= total {
|
||||
break
|
||||
}
|
||||
offset += total
|
||||
offset = len(client.projects)
|
||||
}
|
||||
return client.projects, nil
|
||||
}
|
||||
@@ -287,19 +292,6 @@ func (client *SVolcEngineClient) jsonRequest(cred sdk.Credentials, domain string
|
||||
"Version": []string{apiVersion},
|
||||
}
|
||||
|
||||
var body interface{} = nil
|
||||
if _params, ok := params.(map[string]string); ok {
|
||||
for k, v := range _params {
|
||||
query.Set(k, v)
|
||||
}
|
||||
} else {
|
||||
body = params
|
||||
}
|
||||
|
||||
u, err := url.Parse(fmt.Sprintf("http://%s?%s", domain, query.Encode()))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "url.Parse")
|
||||
}
|
||||
method := httputils.GET
|
||||
for prefix, _method := range map[string]httputils.THttpMethod{
|
||||
"Get": httputils.GET,
|
||||
@@ -307,6 +299,7 @@ func (client *SVolcEngineClient) jsonRequest(cred sdk.Credentials, domain string
|
||||
"List": httputils.GET,
|
||||
"Delete": httputils.GET,
|
||||
"Put": httputils.PUT,
|
||||
"Create": httputils.POST,
|
||||
} {
|
||||
if strings.HasPrefix(apiName, prefix) {
|
||||
method = _method
|
||||
@@ -322,21 +315,84 @@ func (client *SVolcEngineClient) jsonRequest(cred sdk.Credentials, domain string
|
||||
method = httputils.POST
|
||||
}
|
||||
|
||||
req := httputils.NewJsonRequest(method, u.String(), body)
|
||||
vErr := &sVolcError{}
|
||||
_cli := &sCred{
|
||||
form := url.Values{}
|
||||
_params, _ := params.(map[string]string)
|
||||
switch method {
|
||||
case httputils.POST:
|
||||
for k, v := range _params {
|
||||
form.Set(k, v)
|
||||
query.Set(k, v)
|
||||
}
|
||||
default:
|
||||
for k, v := range _params {
|
||||
query.Set(k, v)
|
||||
}
|
||||
}
|
||||
|
||||
u, err := url.Parse(fmt.Sprintf("http://%s?%s", domain, query.Encode()))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "url.Parse")
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(string(method), u.String(), strings.NewReader(form.Encode()))
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "NewRequest")
|
||||
}
|
||||
|
||||
cli := &sCred{
|
||||
client: client,
|
||||
cred: cred,
|
||||
}
|
||||
cli := httputils.NewJsonClient(_cli)
|
||||
_, resp, err := cli.Send(context.Background(), req, vErr, client.debug)
|
||||
|
||||
resp, err := cli.Do(req)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, apiName)
|
||||
return nil, errors.Wrapf(err, "Do request")
|
||||
}
|
||||
if resp.Contains("Result") {
|
||||
return resp.Get("Result")
|
||||
defer resp.Body.Close()
|
||||
|
||||
red := color.New(color.FgRed, color.Bold).PrintlnFunc()
|
||||
green := color.New(color.FgGreen, color.Bold).PrintlnFunc()
|
||||
yellow := color.New(color.FgYellow, color.Bold).PrintlnFunc()
|
||||
cyan := color.New(color.FgHiCyan, color.Bold).PrintlnFunc()
|
||||
|
||||
if client.debug {
|
||||
dump, _ := httputil.DumpRequestOut(req, true)
|
||||
yellow(string(dump))
|
||||
if req.Header.Get("Content-Type") != "application/octet-stream" {
|
||||
curlCmd, _ := http2curl.GetCurlCommand(req)
|
||||
cyan("CURL:", curlCmd, "\n")
|
||||
}
|
||||
|
||||
dump, _ = httputil.DumpResponse(resp, true)
|
||||
if resp.StatusCode < 300 {
|
||||
green(string(dump))
|
||||
} else if resp.StatusCode < 400 {
|
||||
yellow(string(dump))
|
||||
} else {
|
||||
red(string(dump))
|
||||
}
|
||||
}
|
||||
return resp, nil
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Read body")
|
||||
}
|
||||
|
||||
obj, err := jsonutils.Parse(body)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Parse body %s", string(body))
|
||||
}
|
||||
|
||||
// {"ResponseMetadata":{"RequestId":"202404021200176E2994C9222303CC731B","Action":"CreateUser","Version":"2018-01-01","Service":"iam","Region":"cn-beijing","Error":{"Code":"ParameterNotFound","Message":"The parameter 'UserName' is required."}}}
|
||||
if obj.Contains("ResponseMetadata", "Error") {
|
||||
ve := &sVolcError{StatusCode: resp.StatusCode}
|
||||
obj.Unmarshal(ve, "ResponseMetadata")
|
||||
return nil, ve
|
||||
}
|
||||
|
||||
if obj.Contains("Result") {
|
||||
return obj.Get("Result")
|
||||
}
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) getSdkCredential(region string, service string, token string) sdk.Credentials {
|
||||
@@ -381,19 +437,16 @@ func (self *sVolcError) Error() string {
|
||||
return jsonutils.Marshal(self).String()
|
||||
}
|
||||
|
||||
func (self *sVolcError) ParseErrorFromJsonResponse(statusCode int, status string, body jsonutils.JSONObject) error {
|
||||
if body != nil {
|
||||
body.Unmarshal(self, "ResponseMetadata")
|
||||
}
|
||||
self.StatusCode = statusCode
|
||||
return self
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) ecsRequest(region string, apiName string, params map[string]string) (jsonutils.JSONObject, error) {
|
||||
cred := client.getDefaultCredential(region, VOLCENGINE_SERVICE_ECS)
|
||||
return client.jsonRequest(cred, VOLCENGINE_API, VOLCENGINE_API_VERSION, apiName, params)
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) iam20210801Request(region string, apiName string, params map[string]string) (jsonutils.JSONObject, error) {
|
||||
cred := client.getDefaultCredential(region, VOLCENGINE_SERVICE_IAM)
|
||||
return client.jsonRequest(cred, VOLCENGINE_IAM_API, "2021-08-01", apiName, params)
|
||||
}
|
||||
|
||||
func (client *SVolcEngineClient) iamRequest(region string, apiName string, params map[string]string) (jsonutils.JSONObject, error) {
|
||||
cred := client.getDefaultCredential(region, VOLCENGINE_SERVICE_IAM)
|
||||
return client.jsonRequest(cred, VOLCENGINE_IAM_API, VOLCENGINE_IAM_API_VERSION, apiName, params)
|
||||
@@ -477,6 +530,8 @@ func (region *SVolcEngineClient) GetCapabilities() []string {
|
||||
cloudprovider.CLOUD_CAPABILITY_NETWORK,
|
||||
cloudprovider.CLOUD_CAPABILITY_SECURITY_GROUP,
|
||||
cloudprovider.CLOUD_CAPABILITY_EIP,
|
||||
cloudprovider.CLOUD_CAPABILITY_CLOUDID,
|
||||
cloudprovider.CLOUD_CAPABILITY_SAML_AUTH,
|
||||
cloudprovider.CLOUD_CAPABILITY_OBJECTSTORE,
|
||||
}
|
||||
return caps
|
||||
|
||||
Reference in New Issue
Block a user