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 }