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