yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aliyun/ram_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 aliyun
    16  
    17  import (
    18  	"fmt"
    19  	"strings"
    20  	"time"
    21  
    22  	"yunion.io/x/pkg/errors"
    23  
    24  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    25  )
    26  
    27  type SGroup struct {
    28  	client *SAliyunClient
    29  
    30  	Comments    string
    31  	CreatedDate time.Time
    32  	GroupName   string
    33  	UpdateDate  time.Time
    34  }
    35  
    36  type sGroups struct {
    37  	Group []SGroup
    38  }
    39  
    40  type SGroups struct {
    41  	Groups      sGroups
    42  	Marker      string
    43  	IsTruncated bool
    44  }
    45  
    46  func (self *SGroup) GetName() string {
    47  	return self.GroupName
    48  }
    49  
    50  func (self *SGroup) GetGlobalId() string {
    51  	return self.GroupName
    52  }
    53  
    54  func (self *SGroup) GetDescription() string {
    55  	return self.Comments
    56  }
    57  
    58  func (self *SGroup) GetICloudusers() ([]cloudprovider.IClouduser, error) {
    59  	ret := []cloudprovider.IClouduser{}
    60  	offset := ""
    61  	for {
    62  		part, err := self.client.ListUsersForGroup(self.GroupName, offset, 1000)
    63  		if err != nil {
    64  			return nil, errors.Wrapf(err, "ListUsersForGroup")
    65  		}
    66  		for i := range part.Users.User {
    67  			part.Users.User[i].client = self.client
    68  			ret = append(ret, &part.Users.User[i])
    69  		}
    70  		offset = part.Marker
    71  		if len(offset) == 0 || !part.IsTruncated {
    72  			break
    73  		}
    74  	}
    75  	return ret, nil
    76  }
    77  
    78  func (self *SGroup) GetISystemCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
    79  	policies, err := self.client.ListPoliciesForGroup(self.GroupName)
    80  	if err != nil {
    81  		return nil, errors.Wrapf(err, "ListPoliciesForGroup")
    82  	}
    83  	ret := []cloudprovider.ICloudpolicy{}
    84  	for i := range policies {
    85  		if policies[i].PolicyType == POLICY_TYPE_SYSTEM {
    86  			policies[i].client = self.client
    87  			ret = append(ret, &policies[i])
    88  		}
    89  	}
    90  	return ret, nil
    91  }
    92  
    93  func (self *SGroup) GetICustomCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
    94  	policies, err := self.client.ListPoliciesForGroup(self.GroupName)
    95  	if err != nil {
    96  		return nil, errors.Wrapf(err, "ListPoliciesForGroup")
    97  	}
    98  	ret := []cloudprovider.ICloudpolicy{}
    99  	for i := range policies {
   100  		if policies[i].PolicyType == POLICY_TYPE_CUSTOM {
   101  			policies[i].client = self.client
   102  			ret = append(ret, &policies[i])
   103  		}
   104  	}
   105  	return ret, nil
   106  }
   107  
   108  func (self *SGroup) AddUser(name string) error {
   109  	return self.client.AddUserToGroup(self.GroupName, name)
   110  }
   111  
   112  func (self *SGroup) RemoveUser(name string) error {
   113  	return self.client.RemoveUserFromGroup(self.GroupName, name)
   114  }
   115  
   116  func (self *SGroup) AttachSystemPolicy(policyName string) error {
   117  	return self.client.AttachPolicyToGroup(POLICY_TYPE_SYSTEM, policyName, self.GroupName)
   118  }
   119  
   120  func (self *SGroup) AttachCustomPolicy(policyName string) error {
   121  	return self.client.AttachPolicyToGroup(POLICY_TYPE_CUSTOM, policyName, self.GroupName)
   122  }
   123  
   124  func (self *SGroup) DetachSystemPolicy(policyName string) error {
   125  	return self.client.DetachPolicyFromGroup(POLICY_TYPE_SYSTEM, policyName, self.GroupName)
   126  }
   127  
   128  func (self *SGroup) DetachCustomPolicy(policyName string) error {
   129  	return self.client.DetachPolicyFromGroup(POLICY_TYPE_CUSTOM, policyName, self.GroupName)
   130  }
   131  
   132  func (self *SGroup) Delete() error {
   133  	return self.client.DeleteGroup(self.GroupName)
   134  }
   135  
   136  func (self *SAliyunClient) GetICloudgroupByName(name string) (cloudprovider.ICloudgroup, error) {
   137  	group, err := self.GetGroup(name)
   138  	if err != nil {
   139  		return nil, errors.Wrapf(err, "GetGroup(%s)", name)
   140  	}
   141  	return group, nil
   142  }
   143  
   144  func (self *SAliyunClient) CreateICloudgroup(name string, desc string) (cloudprovider.ICloudgroup, error) {
   145  	group, err := self.CreateGroup(name, desc)
   146  	if err != nil {
   147  		return nil, errors.Wrapf(err, "CreateGroup")
   148  	}
   149  	return group, nil
   150  }
   151  
   152  func (self *SAliyunClient) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) {
   153  	ret := []cloudprovider.ICloudgroup{}
   154  	offset := ""
   155  	for {
   156  		part, err := self.ListGroups(offset, 100)
   157  		if err != nil {
   158  			return nil, errors.Wrap(err, "ListGroups")
   159  		}
   160  		for i := range part.Groups.Group {
   161  			part.Groups.Group[i].client = self
   162  			ret = append(ret, &part.Groups.Group[i])
   163  		}
   164  		offset = part.Marker
   165  		if len(offset) == 0 || !part.IsTruncated {
   166  			break
   167  		}
   168  	}
   169  	return ret, nil
   170  }
   171  
   172  func (self *SAliyunClient) ListGroups(offset string, limit int) (*SGroups, error) {
   173  	if limit < 1 || limit > 1000 {
   174  		limit = 1000
   175  	}
   176  	params := map[string]string{
   177  		"MaxItems": fmt.Sprintf("%d", limit),
   178  	}
   179  	if len(offset) > 0 {
   180  		params["Marker"] = offset
   181  	}
   182  	groups := SGroups{}
   183  	resp, err := self.ramRequest("ListGroups", params)
   184  	if err != nil {
   185  		return nil, errors.Wrap(err, "ramRequest.ListGroups")
   186  	}
   187  	err = resp.Unmarshal(&groups)
   188  	if err != nil {
   189  		return nil, errors.Wrap(err, "resp.Unmarshal")
   190  	}
   191  	return &groups, nil
   192  }
   193  
   194  // https://help.aliyun.com/document_detail/28732.html?spm=a2c4g.11186623.6.777.580735b2m2xUh8
   195  func (self *SAliyunClient) ListPoliciesForGroup(groupName string) ([]SPolicy, error) {
   196  	params := map[string]string{
   197  		"GroupName": groupName,
   198  	}
   199  	resp, err := self.ramRequest("ListPoliciesForGroup", params)
   200  	if err != nil {
   201  		return nil, errors.Wrap(err, "ramRequest.ListPoliciesForGroup")
   202  	}
   203  	policies := []SPolicy{}
   204  	err = resp.Unmarshal(&policies, "Policies", "Policy")
   205  	if err != nil {
   206  		return nil, errors.Wrap(err, "resp.Unmarshal")
   207  	}
   208  	return policies, nil
   209  }
   210  
   211  func (self *SAliyunClient) ListUsersForGroup(groupName string, offset string, limit int) (*SUsers, error) {
   212  	if limit < 1 || limit > 1000 {
   213  		limit = 1000
   214  	}
   215  	params := map[string]string{
   216  		"GroupName": groupName,
   217  		"MaxItems":  fmt.Sprintf("%d", limit),
   218  	}
   219  	if len(offset) > 0 {
   220  		params["Marker"] = offset
   221  	}
   222  	resp, err := self.ramRequest("ListUsersForGroup", params)
   223  	if err != nil {
   224  		return nil, errors.Wrap(err, "ramRequest.ListUserForGroup")
   225  	}
   226  	users := &SUsers{}
   227  	err = resp.Unmarshal(users)
   228  	if err != nil {
   229  		return nil, errors.Wrap(err, "resp.Unmarshal")
   230  	}
   231  	return users, nil
   232  }
   233  
   234  func (self *SAliyunClient) DeleteGroup(groupName string) error {
   235  	params := map[string]string{
   236  		"GroupName": groupName,
   237  	}
   238  	_, err := self.ramRequest("DeleteGroup", params)
   239  	return err
   240  }
   241  
   242  func (self *SAliyunClient) CreateGroup(groupName, comments string) (*SGroup, error) {
   243  	params := map[string]string{
   244  		"GroupName": groupName,
   245  	}
   246  	if len(comments) > 0 {
   247  		params["Comments"] = comments
   248  	}
   249  	resp, err := self.ramRequest("CreateGroup", params)
   250  	if err != nil {
   251  		return nil, errors.Wrap(err, "ramRequest.CreateGroup")
   252  	}
   253  	group := &SGroup{client: self}
   254  	err = resp.Unmarshal(group, "Group")
   255  	if err != nil {
   256  		return nil, errors.Wrap(err, "resp.Unmarshal")
   257  	}
   258  	return group, nil
   259  }
   260  
   261  func (self *SAliyunClient) GetGroup(groupName string) (*SGroup, error) {
   262  	params := map[string]string{
   263  		"GroupName": groupName,
   264  	}
   265  	resp, err := self.ramRequest("GetGroup", params)
   266  	if err != nil {
   267  		return nil, errors.Wrap(err, "GetGroup")
   268  	}
   269  	group := &SGroup{client: self}
   270  	err = resp.Unmarshal(group, "Group")
   271  	if err != nil {
   272  		return nil, errors.Wrap(err, "resp.Unmarshal")
   273  	}
   274  	return group, nil
   275  }
   276  
   277  func (self *SAliyunClient) RemoveUserFromGroup(groupName, userName string) error {
   278  	params := map[string]string{
   279  		"GroupName": groupName,
   280  		"UserName":  userName,
   281  	}
   282  	_, err := self.ramRequest("RemoveUserFromGroup", params)
   283  	if err != nil && errors.Cause(err) != cloudprovider.ErrNotFound {
   284  		return errors.Wrap(err, "RemoveUserFromGroup")
   285  	}
   286  	return nil
   287  }
   288  
   289  func (self *SAliyunClient) DetachPolicyFromGroup(policyType, policyName, groupName string) error {
   290  	params := map[string]string{
   291  		"GroupName":  groupName,
   292  		"PolicyName": policyName,
   293  		"PolicyType": policyType,
   294  	}
   295  	_, err := self.ramRequest("DetachPolicyFromGroup", params)
   296  	if err != nil && errors.Cause(err) != cloudprovider.ErrNotFound {
   297  		return errors.Wrap(err, "DetachPolicyFromGroup")
   298  	}
   299  	return nil
   300  }
   301  
   302  func (self *SAliyunClient) AddUserToGroup(groupName, userName string) error {
   303  	params := map[string]string{
   304  		"GroupName": groupName,
   305  		"UserName":  userName,
   306  	}
   307  	_, err := self.ramRequest("AddUserToGroup", params)
   308  	if err != nil && !strings.Contains(err.Error(), "EntityAlreadyExists.User.Group") {
   309  		return errors.Wrap(err, "AddUserToGroup")
   310  	}
   311  	return nil
   312  }
   313  
   314  func (self *SAliyunClient) AttachPolicyToGroup(policyType, policyName, groupName string) error {
   315  	params := map[string]string{
   316  		"GroupName":  groupName,
   317  		"PolicyName": policyName,
   318  		"PolicyType": policyType,
   319  	}
   320  	_, err := self.ramRequest("AttachPolicyToGroup", params)
   321  	if err != nil && !strings.Contains(err.Error(), "EntityAlreadyExists.Group.Policy") {
   322  		return errors.Wrap(err, "AttachPolicyToGroup")
   323  	}
   324  	return nil
   325  }