yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/azure/cloudgroup.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 azure
    16  
    17  import (
    18  	"fmt"
    19  	"net/url"
    20  	"strings"
    21  
    22  	"yunion.io/x/jsonutils"
    23  	"yunion.io/x/pkg/errors"
    24  
    25  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    26  )
    27  
    28  type SCloudgroup struct {
    29  	client *SAzureClient
    30  
    31  	Id                string
    32  	DeletionTimestamp string
    33  	Description       string
    34  	DirSyncEnabled    string
    35  	DisplayName       string
    36  	LastDirSyncTime   string
    37  	Mail              string
    38  	MailNickname      string
    39  	MailEnabled       bool
    40  	ProxyAddresses    []string
    41  }
    42  
    43  func (group *SCloudgroup) GetName() string {
    44  	return group.DisplayName
    45  }
    46  
    47  func (group *SCloudgroup) GetGlobalId() string {
    48  	return group.Id
    49  }
    50  
    51  func (group *SCloudgroup) GetDescription() string {
    52  	return group.Description
    53  }
    54  
    55  func (group *SCloudgroup) GetISystemCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
    56  	policies, err := group.client.GetCloudpolicies(group.Id)
    57  	if err != nil {
    58  		return nil, errors.Wrapf(err, "GetCloudpolicies(%s)", group.Id)
    59  	}
    60  	ret := []cloudprovider.ICloudpolicy{}
    61  	for i := range policies {
    62  		if policies[i].Properties.Type == "BuiltInRole" {
    63  			ret = append(ret, &policies[i])
    64  		}
    65  	}
    66  	return ret, nil
    67  }
    68  
    69  func (group *SCloudgroup) GetICustomCloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
    70  	policies, err := group.client.GetCloudpolicies(group.Id)
    71  	if err != nil {
    72  		return nil, errors.Wrapf(err, "GetCloudpolicies(%s)", group.Id)
    73  	}
    74  	ret := []cloudprovider.ICloudpolicy{}
    75  	for i := range policies {
    76  		if policies[i].Properties.Type != "BuiltInRole" {
    77  			ret = append(ret, &policies[i])
    78  		}
    79  	}
    80  	return ret, nil
    81  }
    82  
    83  func (group *SCloudgroup) GetICloudusers() ([]cloudprovider.IClouduser, error) {
    84  	users, err := group.client.ListGroupMemebers(group.Id)
    85  	if err != nil {
    86  		return nil, errors.Wrap(err, "ListGroupMemebers")
    87  	}
    88  	ret := []cloudprovider.IClouduser{}
    89  	for i := range users {
    90  		users[i].client = group.client
    91  		ret = append(ret, &users[i])
    92  	}
    93  	return ret, nil
    94  }
    95  
    96  func (group *SCloudgroup) AddUser(name string) error {
    97  	return group.client.AddGroupUser(group.Id, name)
    98  }
    99  
   100  func (group *SCloudgroup) RemoveUser(name string) error {
   101  	return group.client.RemoveGroupUser(group.Id, name)
   102  }
   103  
   104  func (group *SCloudgroup) AttachSystemPolicy(policyId string) error {
   105  	return group.client.AssignPolicy(group.Id, policyId, "")
   106  }
   107  
   108  func (group *SCloudgroup) AttachCustomPolicy(policyId string) error {
   109  	return group.client.AssignPolicy(group.Id, policyId, "")
   110  }
   111  
   112  func (group *SCloudgroup) DetachSystemPolicy(policyId string) error {
   113  	assignments, err := group.client.GetAssignments(group.Id)
   114  	if err != nil {
   115  		return errors.Wrapf(err, "GetAssignments(%s)", group.Id)
   116  	}
   117  	for _, assignment := range assignments {
   118  		role, err := group.client.GetRole(assignment.Properties.RoleDefinitionId)
   119  		if err != nil {
   120  			return errors.Wrapf(err, "GetRule(%s)", assignment.Properties.RoleDefinitionId)
   121  		}
   122  		if role.Properties.RoleName == policyId {
   123  			return group.client.gdel(assignment.Id)
   124  		}
   125  	}
   126  	return nil
   127  }
   128  
   129  func (group *SCloudgroup) DetachCustomPolicy(policyId string) error {
   130  	return group.DetachSystemPolicy(policyId)
   131  }
   132  
   133  func (group *SCloudgroup) Delete() error {
   134  	return group.client.DeleteGroup(group.Id)
   135  }
   136  
   137  func (self *SAzureClient) GetCloudgroups(name string) ([]SCloudgroup, error) {
   138  	groups := []SCloudgroup{}
   139  	params := url.Values{}
   140  	if len(name) > 0 {
   141  		params.Set("$filter", fmt.Sprintf("displayName eq '%s'", name))
   142  	}
   143  	err := self.glist("groups", params, &groups)
   144  	if err != nil {
   145  		return nil, err
   146  	}
   147  	return groups, nil
   148  }
   149  
   150  func (self *SAzureClient) GetICloudgroups() ([]cloudprovider.ICloudgroup, error) {
   151  	groups, err := self.GetCloudgroups("")
   152  	if err != nil {
   153  		return nil, errors.Wrap(err, "GetCloudgroups")
   154  	}
   155  	ret := []cloudprovider.ICloudgroup{}
   156  	for i := range groups {
   157  		groups[i].client = self
   158  		ret = append(ret, &groups[i])
   159  	}
   160  	return ret, nil
   161  }
   162  
   163  func (self *SAzureClient) GetICloudgroupByName(name string) (cloudprovider.ICloudgroup, error) {
   164  	groups, err := self.GetCloudgroups(name)
   165  	if err != nil {
   166  		return nil, errors.Wrapf(err, "GetCloudgroups(%s)", name)
   167  	}
   168  	if len(groups) == 0 {
   169  		return nil, cloudprovider.ErrNotFound
   170  	}
   171  	if len(groups) > 1 {
   172  		return nil, cloudprovider.ErrDuplicateId
   173  	}
   174  	groups[0].client = self
   175  	return &groups[0], nil
   176  }
   177  
   178  func (self *SAzureClient) ListGroupMemebers(id string) ([]SClouduser, error) {
   179  	users := []SClouduser{}
   180  	resource := fmt.Sprintf("groups/%s/members", id)
   181  	err := self.glist(resource, nil, &users)
   182  	if err != nil {
   183  		return nil, err
   184  	}
   185  	return users, nil
   186  }
   187  
   188  func (self *SAzureClient) DeleteGroup(id string) error {
   189  	return self.gdel(fmt.Sprintf("groups/%s", id))
   190  }
   191  
   192  func (self *SAzureClient) CreateGroup(name, desc string) (*SCloudgroup, error) {
   193  	params := map[string]interface{}{
   194  		"displayName":     name,
   195  		"mailEnabled":     false,
   196  		"securityEnabled": true,
   197  	}
   198  	nickName := ""
   199  	for _, s := range name {
   200  		if s >= 0 && s <= 127 {
   201  			nickName += string(s)
   202  		}
   203  	}
   204  	params["mailNickname"] = nickName
   205  	if len(desc) > 0 {
   206  		params["Description"] = desc
   207  	}
   208  	group := SCloudgroup{client: self}
   209  	err := self.gcreate("groups", jsonutils.Marshal(params), &group)
   210  	if err != nil {
   211  		return nil, errors.Wrap(err, "Create")
   212  	}
   213  	return &group, nil
   214  }
   215  
   216  func (self *SAzureClient) RemoveGroupUser(id, userName string) error {
   217  	user, err := self.GetClouduser(userName)
   218  	if err != nil {
   219  		return errors.Wrapf(err, "GetCloudusers(%s)", userName)
   220  	}
   221  	return self.gdel(fmt.Sprintf("/groups/%s/members/%s/$ref", id, user.Id))
   222  }
   223  
   224  func (self *SAzureClient) CreateICloudgroup(name, desc string) (cloudprovider.ICloudgroup, error) {
   225  	group, err := self.CreateGroup(name, desc)
   226  	if err != nil {
   227  		return nil, errors.Wrap(err, "CreateGroup")
   228  	}
   229  	group.client = self
   230  	return group, nil
   231  }
   232  
   233  func (self *SAzureClient) AddGroupUser(id, userName string) error {
   234  	user, err := self.GetClouduser(userName)
   235  	if err != nil {
   236  		return errors.Wrapf(err, "GetCloudusers(%s)", userName)
   237  	}
   238  	resource := fmt.Sprintf("groups/%s/members/$ref", id)
   239  	params := map[string]string{
   240  		"@odata.id": fmt.Sprintf("https://graph.microsoft.com/v1.0/directoryObjects/%s", user.Id),
   241  	}
   242  	err = self.gcreate(resource, jsonutils.Marshal(params), nil)
   243  	if err != nil && !strings.Contains(err.Error(), "One or more added object references already exist for the following modified properties") {
   244  		return err
   245  	}
   246  	return nil
   247  }