yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/aliyun/ram_role.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 "time" 20 21 "yunion.io/x/jsonutils" 22 "yunion.io/x/pkg/errors" 23 24 "yunion.io/x/cloudmux/pkg/cloudprovider" 25 ) 26 27 type sRoles struct { 28 Role []SRole 29 } 30 31 type SRoles struct { 32 Roles sRoles 33 Marker string 34 IsTruncated bool 35 } 36 37 type SRole struct { 38 client *SAliyunClient 39 40 Arn string 41 CreateDate time.Time 42 Description string 43 RoleId string 44 RoleName string 45 46 AssumeRolePolicyDocument string 47 } 48 49 func (self *SRole) GetGlobalId() string { 50 return self.Arn 51 } 52 53 func (self *SRole) GetName() string { 54 return self.RoleName 55 } 56 57 func (self *SRole) GetICloudpolicies() ([]cloudprovider.ICloudpolicy, error) { 58 policies, err := self.client.ListPoliciesForRole(self.RoleName) 59 if err != nil { 60 return nil, errors.Wrapf(err, "ListPoliciesForRole") 61 } 62 ret := []cloudprovider.ICloudpolicy{} 63 for i := range policies { 64 policies[i].client = self.client 65 ret = append(ret, &policies[i]) 66 } 67 return ret, nil 68 } 69 70 func (self *SRole) AttachPolicy(policyName string) error { 71 return self.client.AttachPolicy2Role("System", policyName, self.RoleName) 72 } 73 74 func (self *SRole) DetachPolicy(policyName string) error { 75 return self.client.DetachPolicyFromRole("System", policyName, self.RoleName) 76 } 77 78 func (self *SRole) Delete() error { 79 return self.client.DeleteRole(self.RoleName) 80 } 81 82 func (self *SRole) GetDocument() *jsonutils.JSONDict { 83 role, err := self.client.GetRole(self.RoleName) 84 if err != nil { 85 return nil 86 } 87 documet, err := jsonutils.Parse([]byte(role.AssumeRolePolicyDocument)) 88 if err != nil { 89 return nil 90 } 91 return documet.(*jsonutils.JSONDict) 92 } 93 94 func (self *SRole) GetSAMLProvider() string { 95 document := self.GetDocument() 96 if document != nil { 97 statement, err := document.GetArray("Statement") 98 if err == nil { 99 for i := range statement { 100 if action, _ := statement[i].GetString("Action"); action == "sts:AssumeRole" { 101 sp, _ := statement[i].GetString("Principal", "Federated") 102 if len(sp) > 0 { 103 return sp 104 } 105 } 106 } 107 } 108 } 109 return "" 110 } 111 112 func (self *SAliyunClient) GetICloudroles() ([]cloudprovider.ICloudrole, error) { 113 roles := []SRole{} 114 marker := "" 115 for { 116 part, err := self.ListRoles(marker, 1000) 117 if err != nil { 118 return nil, errors.Wrapf(err, "ListRoles(%s)", marker) 119 } 120 roles = append(roles, part.Roles.Role...) 121 if len(part.Marker) == 0 { 122 break 123 } 124 marker = part.Marker 125 } 126 ret := []cloudprovider.ICloudrole{} 127 for i := range roles { 128 roles[i].client = self 129 ret = append(ret, &roles[i]) 130 } 131 return ret, nil 132 } 133 134 func (self *SAliyunClient) ListRoles(offset string, limit int) (*SRoles, error) { 135 if limit < 0 || limit > 1000 { 136 limit = 1000 137 } 138 139 params := map[string]string{} 140 if len(offset) > 0 { 141 params["Marker"] = offset 142 } 143 if limit > 0 { 144 params["MaxItems"] = fmt.Sprintf("%d", limit) 145 } 146 147 body, err := self.ramRequest("ListRoles", params) 148 if err != nil { 149 return nil, errors.Wrapf(err, "ListRoles") 150 } 151 152 roles := &SRoles{} 153 err = body.Unmarshal(roles) 154 if err != nil { 155 return nil, errors.Wrap(err, "body.Unmarshal(&") 156 } 157 return roles, nil 158 } 159 160 func (self *SAliyunClient) CreateRole(roleName string, document string, desc string) (*SRole, error) { 161 params := make(map[string]string) 162 params["RoleName"] = roleName 163 params["AssumeRolePolicyDocument"] = document 164 if len(desc) > 0 { 165 params["Description"] = desc 166 } 167 168 body, err := self.ramRequest("CreateRole", params) 169 if err != nil { 170 return nil, errors.Wrap(err, "CreateRole") 171 } 172 173 role := SRole{client: self} 174 err = body.Unmarshal(&role, "Role") 175 if err != nil { 176 return nil, errors.Wrap(err, "body.Unmarshal") 177 } 178 179 return &role, nil 180 } 181 182 func (self *SAliyunClient) GetRole(roleName string) (*SRole, error) { 183 params := make(map[string]string) 184 params["RoleName"] = roleName 185 186 body, err := self.ramRequest("GetRole", params) 187 if err != nil { 188 return nil, errors.Wrap(err, "GetRole") 189 } 190 191 role := SRole{client: self} 192 err = body.Unmarshal(&role, "Role") 193 if err != nil { 194 return nil, errors.Wrap(err, "body.Unmarshal") 195 } 196 197 return &role, nil 198 } 199 200 func (self *SAliyunClient) ListPoliciesForRole(name string) ([]SPolicy, error) { 201 params := map[string]string{ 202 "RoleName": name, 203 } 204 resp, err := self.ramRequest("ListPoliciesForRole", params) 205 if err != nil { 206 return nil, errors.Wrapf(err, "ListPoliciesForRole") 207 } 208 policies := []SPolicy{} 209 err = resp.Unmarshal(&policies, "Policies", "Policy") 210 if err != nil { 211 return nil, errors.Wrapf(err, "resp.Unmarshal") 212 } 213 return policies, nil 214 } 215 216 func (self *SAliyunClient) DetachPolicyFromRole(policyType, policyName, roleName string) error { 217 params := map[string]string{ 218 "PolicyName": policyName, 219 "PolicyType": policyType, 220 "RoleName": roleName, 221 } 222 _, err := self.ramRequest("DetachPolicyFromRole", params) 223 return err 224 }