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 }