yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/qcloud/cam_group.go (about)

     1  // Copyright 2019 Yunion
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package qcloud
    16  
    17  import (
    18  	"fmt"
    19  	"time"
    20  
    21  	"yunion.io/x/pkg/errors"
    22  
    23  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    24  )
    25  
    26  type SGroup struct {
    27  	client *SQcloudClient
    28  
    29  	GroupId    int
    30  	GroupName  string
    31  	CreateTime time.Time
    32  }
    33  
    34  func (self *SGroup) GetName() string {
    35  	return self.GroupName
    36  }
    37  
    38  func (self *SGroup) GetGlobalId() string {
    39  	return self.GroupName
    40  }
    41  
    42  func (self *SGroup) GetDescription() string {
    43  	return ""
    44  }
    45  
    46  func (self *SGroup) GetICloudusers() ([]cloudprovider.IClouduser, error) {
    47  	users := []SUser{}
    48  	offset := 1
    49  	for {
    50  		part, total, err := self.client.ListGroupUsers(self.GroupId, offset, 100)
    51  		if err != nil {
    52  			return nil, errors.Wrapf(err, "ListGroupUsers")
    53  		}
    54  		users = append(users, part...)
    55  		if len(users) >= total {
    56  			break
    57  		}
    58  		offset += 1
    59  	}
    60  	ret := []cloudprovider.IClouduser{}
    61  	for i := range users {
    62  		users[i].client = self.client
    63  		ret = append(ret, &users[i])
    64  	}
    65  	return ret, nil
    66  }
    67  
    68  func (self *SGroup) AddUser(name string) error {
    69  	user, err := self.client.GetUser(name)
    70  	if err != nil {
    71  		return errors.Wrapf(err, "GetUser(%s)", name)
    72  	}
    73  	return self.client.AddUserToGroup(self.GroupId, int(user.Uid))
    74  }
    75  
    76  func (self *SGroup) RemoveUser(name string) error {
    77  	user, err := self.client.GetUser(name)
    78  	if err != nil {
    79  		if errors.Cause(err) == cloudprovider.ErrNotFound {
    80  			return nil
    81  		}
    82  		return errors.Wrapf(err, "GetUser(%s)", name)
    83  	}
    84  	return self.client.RemoveUserFromGroup(self.GroupId, int(user.Uid))
    85  }
    86  
    87  func (self *SGroup) AttachSystemPolicy(policyId string) error {
    88  	return self.client.AttachGroupPolicy(self.GroupId, policyId)
    89  }
    90  
    91  func (self *SGroup) AttachCustomPolicy(policyId string) error {
    92  	return self.client.AttachGroupPolicy(self.GroupId, policyId)
    93  }
    94  
    95  func (self *SGroup) DetachSystemPolicy(policyId string) error {
    96  	return self.client.DetachGroupPolicy(self.GroupId, policyId)
    97  }
    98  
    99  func (self *SGroup) DetachCustomPolicy(policyId string) error {
   100  	return self.client.DetachGroupPolicy(self.GroupId, policyId)
   101  }
   102  
   103  func (self *SGroup) ListGroupPolicies() ([]SPolicy, error) {
   104  	policies := []SPolicy{}
   105  	offset := 1
   106  	for {
   107  		part, total, err := self.client.ListAttachedGroupPolicies(self.GroupId, offset, 200)
   108  		if err != nil {
   109  			return nil, errors.Wrapf(err, "ListAttachedGroupPolicies")
   110  		}
   111  		policies = append(policies, part...)
   112  		if len(policies) >= total {
   113  			break
   114  		}
   115  		offset += 1
   116  	}
   117  	return policies, nil
   118  }
   119  
   120  func (self *SGroup) GetICustomCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
   121  	policies, err := self.ListGroupPolicies()
   122  	if err != nil {
   123  		return nil, errors.Wrapf(err, "ListGroupPolicies")
   124  	}
   125  	ret := []cloudprovider.ICloudpolicy{}
   126  	customPolicyMaps, err := self.client.GetCustomPolicyMaps()
   127  	if err != nil {
   128  		return nil, errors.Wrap(err, "GetCustomPolicyIds")
   129  	}
   130  	for i := range policies {
   131  		_, ok := customPolicyMaps[policies[i].PolicyName]
   132  		if ok {
   133  			policies[i].client = self.client
   134  			ret = append(ret, &policies[i])
   135  		}
   136  	}
   137  	return ret, nil
   138  }
   139  
   140  func (self *SQcloudClient) GetCustomPolicyMaps() (map[string]int64, error) {
   141  	policyMaps := map[string]int64{}
   142  	offset := 1
   143  	for {
   144  		part, total, err := self.ListPolicies("", "Local", offset, 50)
   145  		if err != nil {
   146  			return nil, errors.Wrap(err, "ListPolicies")
   147  		}
   148  		for _, policy := range part {
   149  			policyMaps[policy.PolicyName] = policy.PolicyId
   150  		}
   151  		if len(policyMaps) >= total {
   152  			break
   153  		}
   154  		offset += 1
   155  	}
   156  	return policyMaps, nil
   157  }
   158  
   159  func (self *SGroup) GetISystemCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
   160  	policies, err := self.ListGroupPolicies()
   161  	if err != nil {
   162  		return nil, errors.Wrapf(err, "ListGroupPolicies")
   163  	}
   164  	ret := []cloudprovider.ICloudpolicy{}
   165  	customPolicyMaps, err := self.client.GetCustomPolicyMaps()
   166  	if err != nil {
   167  		return nil, errors.Wrap(err, "GetCustomPolicyIds")
   168  	}
   169  	for i := range policies {
   170  		_, ok := customPolicyMaps[policies[i].PolicyName]
   171  		if !ok {
   172  			policies[i].client = self.client
   173  			ret = append(ret, &policies[i])
   174  		}
   175  	}
   176  	return ret, nil
   177  }
   178  
   179  func (self *SGroup) Delete() error {
   180  	return self.client.DeleteGroup(self.GroupId)
   181  }
   182  
   183  func (self *SQcloudClient) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) {
   184  	ret := []cloudprovider.ICloudgroup{}
   185  	offset := 1
   186  	for {
   187  		part, total, err := self.ListGroups("", offset, 50)
   188  		if err != nil {
   189  			return nil, errors.Wrapf(err, "DescribeRoleList")
   190  		}
   191  		for i := range part {
   192  			part[i].client = self
   193  			ret = append(ret, &part[i])
   194  		}
   195  		if total >= len(ret) {
   196  			break
   197  		}
   198  		offset += 1
   199  	}
   200  	return ret, nil
   201  }
   202  
   203  func (self *SQcloudClient) CreateICloudgroup(name, desc string) (cloudprovider.ICloudgroup, error) {
   204  	group, err := self.CreateGroup(name, desc)
   205  	if err != nil {
   206  		return nil, errors.Wrapf(err, "CreateGroup")
   207  	}
   208  	return group, nil
   209  }
   210  
   211  func (self *SQcloudClient) GetICloudgroupByName(name string) (cloudprovider.ICloudgroup, error) {
   212  	groups := []SGroup{}
   213  	offset := 1
   214  	for {
   215  		part, total, err := self.ListGroups(name, offset, 50)
   216  		if err != nil {
   217  			return nil, errors.Wrapf(err, "ListGroups")
   218  		}
   219  		groups = append(groups, part...)
   220  		if len(groups) >= total {
   221  			break
   222  		}
   223  		offset += 1
   224  	}
   225  	for i := range groups {
   226  		if groups[i].GroupName == name {
   227  			groups[i].client = self
   228  			return &groups[i], nil
   229  		}
   230  	}
   231  	return nil, errors.Wrap(cloudprovider.ErrNotFound, name)
   232  }
   233  
   234  func (self *SQcloudClient) ListGroups(keyword string, offset int, limit int) ([]SGroup, int, error) {
   235  	if offset < 1 {
   236  		offset = 1
   237  	}
   238  	if limit <= 0 || limit > 50 {
   239  		limit = 50
   240  	}
   241  	params := map[string]string{
   242  		"Page": fmt.Sprintf("%d", offset),
   243  		"Rp":   fmt.Sprintf("%d", limit),
   244  	}
   245  	if len(keyword) > 0 {
   246  		params["Keyword"] = keyword
   247  	}
   248  
   249  	resp, err := self.camRequest("ListGroups", params)
   250  	if err != nil {
   251  		return nil, 0, errors.Wrap(err, "camRequest.ListGroups")
   252  	}
   253  	groups := []SGroup{}
   254  	err = resp.Unmarshal(&groups, "GroupInfo")
   255  	if err != nil {
   256  		return nil, 0, errors.Wrap(err, "resp.Unmarshal")
   257  	}
   258  	total, _ := resp.Float("TotalNum")
   259  	return groups, int(total), nil
   260  }
   261  
   262  func (self *SQcloudClient) CreateGroup(name string, remark string) (*SGroup, error) {
   263  	params := map[string]string{
   264  		"GroupName": name,
   265  	}
   266  	if len(remark) > 0 {
   267  		params["Remark"] = remark
   268  	}
   269  	resp, err := self.camRequest("CreateGroup", params)
   270  	if err != nil {
   271  		return nil, errors.Wrap(err, "camRequest.CreateGroup")
   272  	}
   273  	groupId, _ := resp.Float("GroupId")
   274  	return self.GetGroup(int(groupId))
   275  }
   276  
   277  func (self *SQcloudClient) GetGroup(groupId int) (*SGroup, error) {
   278  	params := map[string]string{
   279  		"GroupId": fmt.Sprintf("%d", groupId),
   280  	}
   281  	resp, err := self.camRequest("GetGroup", params)
   282  	if err != nil {
   283  		return nil, errors.Wrap(err, "camRequest.GetGroup")
   284  	}
   285  	group := &SGroup{client: self}
   286  	err = resp.Unmarshal(group)
   287  	if err != nil {
   288  		return nil, errors.Wrap(err, "resp.Unmarshal")
   289  	}
   290  	return group, nil
   291  }
   292  
   293  func (self *SQcloudClient) DeleteGroup(id int) error {
   294  	params := map[string]string{
   295  		"GroupId": fmt.Sprintf("%d", id),
   296  	}
   297  	_, err := self.camRequest("DeleteGroup", params)
   298  	return err
   299  }
   300  
   301  func (self *SQcloudClient) ListAttachedGroupPolicies(groupId int, offset int, limit int) ([]SPolicy, int, error) {
   302  	if offset < 1 {
   303  		offset = 1
   304  	}
   305  	if limit <= 0 || limit > 50 {
   306  		limit = 50
   307  	}
   308  	params := map[string]string{
   309  		"TargetGroupId": fmt.Sprintf("%d", groupId),
   310  		"Page":          fmt.Sprintf("%d", offset),
   311  		"Rp":            fmt.Sprintf("%d", limit),
   312  	}
   313  	resp, err := self.camRequest("ListAttachedGroupPolicies", params)
   314  	if err != nil {
   315  		return nil, 0, errors.Wrap(err, "iamRequest.ListAttachedGroupPolicies")
   316  	}
   317  	policies := []SPolicy{}
   318  	err = resp.Unmarshal(&policies, "List")
   319  	if err != nil {
   320  		return nil, 0, errors.Wrap(err, "resp.Unmarshal")
   321  	}
   322  	total, _ := resp.Float("TotalNum")
   323  	return policies, int(total), nil
   324  }
   325  
   326  func (self *SQcloudClient) ListGroupUsers(groupId int, offset int, limit int) ([]SUser, int, error) {
   327  	if offset < 1 {
   328  		offset = 1
   329  	}
   330  	if limit <= 0 || limit > 50 {
   331  		limit = 50
   332  	}
   333  	params := map[string]string{
   334  		"GroupId": fmt.Sprintf("%d", groupId),
   335  		"Page":    fmt.Sprintf("%d", offset),
   336  		"Rp":      fmt.Sprintf("%d", limit),
   337  	}
   338  	resp, err := self.camRequest("ListUsersForGroup", params)
   339  	if err != nil {
   340  		return nil, 0, errors.Wrap(err, "iamRequest.ListUserForGroup")
   341  	}
   342  	users := []SUser{}
   343  	err = resp.Unmarshal(&users, "UserInfo")
   344  	if err != nil {
   345  		return nil, 0, errors.Wrap(err, "resp.Unmarshal")
   346  	}
   347  	total, _ := resp.Float("TotalNum")
   348  	return users, int(total), nil
   349  }
   350  
   351  func (self *SQcloudClient) RemoveUserFromGroup(groupId, userId int) error {
   352  	params := map[string]string{
   353  		"Info.0.Uid":     fmt.Sprintf("%d", userId),
   354  		"Info.0.GroupId": fmt.Sprintf("%d", groupId),
   355  	}
   356  	_, err := self.camRequest("RemoveUserFromGroup", params)
   357  	return err
   358  }
   359  
   360  func (self *SQcloudClient) AddUserToGroup(groupId, userId int) error {
   361  	params := map[string]string{
   362  		"Info.0.Uid":     fmt.Sprintf("%d", userId),
   363  		"Info.0.GroupId": fmt.Sprintf("%d", groupId),
   364  	}
   365  	_, err := self.camRequest("AddUserToGroup", params)
   366  	return err
   367  }
   368  
   369  func (self *SQcloudClient) AttachGroupPolicy(groupId int, policyId string) error {
   370  	params := map[string]string{
   371  		"PolicyId":      policyId,
   372  		"AttachGroupId": fmt.Sprintf("%d", groupId),
   373  	}
   374  	_, err := self.camRequest("AttachGroupPolicy", params)
   375  	return err
   376  }
   377  
   378  func (self *SQcloudClient) DetachGroupPolicy(groupId int, policyId string) error {
   379  	params := map[string]string{
   380  		"PolicyId":      policyId,
   381  		"DetachGroupId": fmt.Sprintf("%d", groupId),
   382  	}
   383  	_, err := self.camRequest("DetachGroupPolicy", params)
   384  	return err
   385  }