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  }