yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/azure/cloudpolicy.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 "yunion.io/x/pkg/util/stringutils" 25 26 "yunion.io/x/cloudmux/pkg/cloudprovider" 27 ) 28 29 type SPermission struct { 30 Actions []string 31 NotActions []string 32 DataActions []string 33 NotDataActions []string 34 } 35 36 type SRoleProperties struct { 37 RoleName string 38 Type string 39 Description string 40 AssignableScopes []string 41 Permissions []SPermission 42 } 43 44 type SCloudpolicy struct { 45 Id string 46 Type string 47 Name string 48 Properties SRoleProperties 49 } 50 51 func (role *SCloudpolicy) GetName() string { 52 return role.Properties.RoleName 53 } 54 55 func (role *SCloudpolicy) GetGlobalId() string { 56 return role.Properties.RoleName 57 } 58 59 func (role *SCloudpolicy) GetDescription() string { 60 return role.Properties.Description 61 } 62 63 func (role *SCloudpolicy) UpdateDocument(document *jsonutils.JSONDict) error { 64 return cloudprovider.ErrNotImplemented 65 } 66 67 func (role *SCloudpolicy) GetDocument() (*jsonutils.JSONDict, error) { 68 return jsonutils.Marshal(role.Properties).(*jsonutils.JSONDict), nil 69 } 70 71 func (role *SCloudpolicy) Delete() error { 72 return cloudprovider.ErrNotImplemented 73 } 74 75 func (cli *SAzureClient) GetRoles(name, policyType string) ([]SCloudpolicy, error) { 76 ret := []SCloudpolicy{} 77 filter := []string{} 78 if len(name) > 0 { 79 filter = append(filter, fmt.Sprintf("roleName eq '%s'", name)) 80 } 81 if len(policyType) > 0 { 82 filter = append(filter, fmt.Sprintf("Type eq '%s'", policyType)) 83 } 84 params := url.Values{} 85 if len(filter) > 0 { 86 params.Set("$filter", strings.Join(filter, " and ")) 87 } 88 resource := "Microsoft.Authorization/roleDefinitions" 89 err := cli.list(resource, params, &ret) 90 if err != nil { 91 return nil, errors.Wrap(err, "list") 92 } 93 return ret, nil 94 } 95 96 func (cli *SAzureClient) GetISystemCloudpolicies() ([]cloudprovider.ICloudpolicy, error) { 97 roles, err := cli.GetRoles("", "BuiltInRole") 98 if err != nil { 99 return nil, errors.Wrap(err, "GetRoles") 100 } 101 ret := []cloudprovider.ICloudpolicy{} 102 for i := range roles { 103 ret = append(ret, &roles[i]) 104 } 105 return ret, nil 106 } 107 108 func (cli *SAzureClient) GetICustomCloudpolicies() ([]cloudprovider.ICloudpolicy, error) { 109 roles, err := cli.GetRoles("", "CustomRole") 110 if err != nil { 111 return nil, errors.Wrap(err, "GetRoles") 112 } 113 ret := []cloudprovider.ICloudpolicy{} 114 for i := range roles { 115 ret = append(ret, &roles[i]) 116 } 117 return ret, nil 118 } 119 120 func (cli *SAzureClient) AssignPolicy(objectId, roleName, subscriptionId string) error { 121 roles, err := cli.GetRoles(roleName, "") 122 if err != nil { 123 return errors.Wrapf(err, "GetRoles(%s)", roleName) 124 } 125 if len(roles) == 0 { 126 return errors.Wrap(cloudprovider.ErrNotFound, roleName) 127 } 128 if len(roles) > 1 { 129 return errors.Wrap(cloudprovider.ErrDuplicateId, roleName) 130 } 131 body := map[string]interface{}{ 132 "properties": map[string]interface{}{ 133 "roleDefinitionId": roles[0].Id, 134 "principalId": objectId, 135 }, 136 } 137 subscriptionIds := []string{} 138 if len(subscriptionId) == 0 { 139 for _, subscription := range cli.subscriptions { 140 subscriptionIds = append(subscriptionIds, subscription.SubscriptionId) 141 } 142 } 143 for _, subscriptionId := range subscriptionIds { 144 resource := fmt.Sprintf("subscriptions/%s/providers/Microsoft.Authorization/roleAssignments/%s", subscriptionId, stringutils.UUID4()) 145 _, err = cli.put(resource, jsonutils.Marshal(body)) 146 if err != nil { 147 if e, ok := err.(*AzureResponseError); ok && e.AzureError.Code == "ReadOnlyDisabledSubscription" || e.AzureError.Code == "PrincipalNotFound" { 148 continue 149 } 150 return errors.Wrapf(err, "AssignPolicy %s for subscription %s", roleName, subscriptionId) 151 } 152 } 153 return nil 154 } 155 156 type SAssignmentProperties struct { 157 RoleDefinitionId string 158 PrincipalId string 159 PrincipalType string 160 Scope string 161 } 162 163 type SAssignment struct { 164 Id string 165 Name string 166 Type string 167 Properties SAssignmentProperties 168 } 169 170 func (cli *SAzureClient) GetAssignments(objectId string) ([]SAssignment, error) { 171 ret := []SAssignment{} 172 params := url.Values{} 173 if len(objectId) > 0 { 174 params.Set("$filter", fmt.Sprintf("principalId eq '%s'", objectId)) 175 } 176 resource := "Microsoft.Authorization/roleAssignments" 177 err := cli.list(resource, params, &ret) 178 if err != nil { 179 return nil, errors.Wrap(err, "list") 180 } 181 return ret, nil 182 } 183 184 func (cli *SAzureClient) GetRole(roleId string) (*SCloudpolicy, error) { 185 role := &SCloudpolicy{} 186 err := cli.get(roleId, nil, role) 187 if err != nil { 188 return nil, errors.Wrapf(err, "GetRole(%s)", roleId) 189 } 190 return role, nil 191 } 192 193 func (cli *SAzureClient) GetCloudpolicies(objectId string) ([]SCloudpolicy, error) { 194 assignments, err := cli.GetAssignments(objectId) 195 if err != nil { 196 return nil, errors.Wrapf(err, "GetAssignments(%s)", objectId) 197 } 198 ret := []SCloudpolicy{} 199 for _, assignment := range assignments { 200 role, err := cli.GetRole(assignment.Properties.RoleDefinitionId) 201 if err != nil { 202 return nil, errors.Wrapf(err, "GetRule(%s)", assignment.Properties.RoleDefinitionId) 203 } 204 ret = append(ret, *role) 205 } 206 return ret, nil 207 }