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 }