fix(cloudid): vendor update for azure iam (#21643)

This commit is contained in:
屈轩
2024-11-20 20:15:47 +08:00
committed by GitHub
parent 38e82e262a
commit 69780561f9
12 changed files with 277 additions and 387 deletions
+1 -1
View File
@@ -87,7 +87,7 @@ require (
k8s.io/client-go v0.19.3
k8s.io/cluster-bootstrap v0.19.3
moul.io/http2curl/v2 v2.3.0
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241120063047-cb7d8075945b
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241120113554-51d92bf12bc3
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32
yunion.io/x/jsonutils v1.0.1-0.20240930100528-1671a2d0d22f
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
+2 -2
View File
@@ -1274,8 +1274,8 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241120063047-cb7d8075945b h1:n4cMdSOdGQJrbHwzYMQ+4hTKmm7R6g6y+iCfV2lYQLY=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241120063047-cb7d8075945b/go.mod h1:rj/pb3DitJlQaQD8UW1oxx/KD+PzDZqoywzqRJaFE9A=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241120113554-51d92bf12bc3 h1:OQQI9k3WLC6OFNpVncPIC5w6MJVPU8BkrnW5J5lYma8=
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241120113554-51d92bf12bc3/go.mod h1:rj/pb3DitJlQaQD8UW1oxx/KD+PzDZqoywzqRJaFE9A=
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32 h1:v7POYkQwo1XzOxBoIoRVr/k0V9Y5JyjpshlIFa9raug=
yunion.io/x/executor v0.0.0-20230705125604-c5ac3141db32/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
+87
View File
@@ -15,8 +15,16 @@
package drivers
import (
"context"
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudid/models"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SAzureDriver struct {
@@ -30,3 +38,82 @@ func (driver SAzureDriver) GetProvider() string {
func init() {
models.RegisterProviderDriver(&SAzureDriver{})
}
func (base SAzureDriver) RequestSyncCloudaccountResources(ctx context.Context, userCred mcclient.TokenCredential, account *models.SCloudaccount, provider cloudprovider.ICloudProvider) error {
func() {
lockman.LockRawObject(ctx, account.Id, models.SAMLProviderManager.Keyword())
defer lockman.ReleaseRawObject(ctx, account.Id, models.SAMLProviderManager.Keyword())
samls, err := provider.GetICloudSAMLProviders()
if err != nil {
if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
log.Errorf("get saml providers for account %s error: %v", account.Name, err)
}
return
}
result := account.SyncSAMLProviders(ctx, userCred, samls, "")
log.Infof("Sync SAMLProviders for account %s(%s) result: %s", account.Name, account.Provider, result.Result())
}()
func() {
policies, err := provider.GetICloudpolicies()
if err != nil {
if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
log.Errorf("get system policies for account %s error: %v", account.Name, err)
}
return
}
result := account.SyncPolicies(ctx, userCred, policies, "")
log.Infof("Sync policies for account %s(%s) result: %s", account.Name, account.Provider, result.Result())
}()
func() {
iGroups, err := provider.GetICloudgroups()
if err != nil {
if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
log.Errorf("get groups for account %s error: %v", account.Name, err)
}
return
}
localGroups, remoteGroups, result := account.SyncCloudgroups(ctx, userCred, iGroups, "")
log.Infof("SyncCloudgroups for account %s(%s) result: %s", account.Name, account.Provider, result.Result())
for i := 0; i < len(localGroups); i += 1 {
func() {
// lock cloudgroup
lockman.LockObject(ctx, &localGroups[i])
defer lockman.ReleaseObject(ctx, &localGroups[i])
localGroups[i].SyncCloudpolicies(ctx, userCred, remoteGroups[i])
}()
}
}()
func() {
iUsers, err := provider.GetICloudusers()
if err != nil {
if errors.Cause(err) != cloudprovider.ErrNotSupported && errors.Cause(err) != cloudprovider.ErrNotImplemented {
log.Errorf("get users for account %s error: %v", account.Name, err)
}
return
}
localUsers, remoteUsers, result := account.SyncCloudusers(ctx, userCred, iUsers, "")
log.Infof("SyncCloudusers for account %s(%s) result: %s", account.Name, account.Provider, result.Result())
for i := 0; i < len(localUsers); i += 1 {
func() {
// lock clouduser
lockman.LockObject(ctx, &localUsers[i])
defer lockman.ReleaseObject(ctx, &localUsers[i])
localUsers[i].SyncCloudpolicies(ctx, userCred, remoteUsers[i])
localUsers[i].SyncCloudgroups(ctx, userCred, remoteUsers[i])
}()
}
}()
return nil
}
func (base SAzureDriver) RequestSyncCloudproviderResources(ctx context.Context, userCred mcclient.TokenCredential, cp *models.SCloudprovider, provider cloudprovider.ICloudProvider) error {
return nil
}
+1 -1
View File
@@ -642,7 +642,7 @@ func (self *SCloudgroup) PerformSetPolicies(ctx context.Context, userCred mcclie
return nil, err
}
policy := policObj.(*SCloudpolicy)
if policy.ManagerId != self.ManagerId || policy.CloudaccountId != self.CloudaccountId {
if (policy.ManagerId != self.ManagerId && len(self.ManagerId) > 0) || policy.CloudaccountId != self.CloudaccountId {
return nil, httperrors.NewConflictError("Policies and groups do not belong to the same account")
}
newP.Add(policy.Id)
+1 -1
View File
@@ -1576,7 +1576,7 @@ sigs.k8s.io/structured-merge-diff/v4/value
# sigs.k8s.io/yaml v1.2.0
## explicit; go 1.12
sigs.k8s.io/yaml
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241120063047-cb7d8075945b
# yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20241120113554-51d92bf12bc3
## explicit; go 1.21
yunion.io/x/cloudmux/pkg/apis
yunion.io/x/cloudmux/pkg/apis/billing
+3 -1
View File
@@ -468,7 +468,7 @@ func (self *SAzureClient) _apiVersion(resource string, params url.Values) string
} else if utils.IsInStringArray("microsoft.insights", info) {
return "2017-03-01-preview"
} else if utils.IsInStringArray("microsoft.authorization", info) {
return "2018-01-01-preview"
return "2022-04-01"
} else if utils.IsInStringArray("microsoft.cache", info) {
if utils.IsInStringArray("redisenterprise", info) {
return "2021-03-01"
@@ -675,12 +675,14 @@ type sMessage struct {
Lang string
Value string
}
type sOdataError struct {
Code string
Message sMessage
RequestId string
Date time.Time
}
type AzureResponseError struct {
OdataError sOdataError `json:"odata.error"`
AzureError AzureError `json:"error"`
+14 -5
View File
@@ -11,6 +11,7 @@ import (
"yunion.io/x/cloudmux/pkg/cloudprovider"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/util/httputils"
)
@@ -151,24 +152,32 @@ func (self *SAzureClient) _request_v2(service string, method httputils.THttpMeth
if err != nil {
return nil, err
}
if gotypes.IsNil(resp) {
return jsonutils.NewDict(), nil
}
if !resp.Contains("value") {
return resp, nil
}
part := struct {
Value []jsonutils.JSONObject
NextLink string
Value []jsonutils.JSONObject
NextLink string
OdataNextLink string `json:"@odata.nextLink"`
}{}
err = resp.Unmarshal(&part)
if err != nil {
return nil, errors.Wrapf(err, "resp.Unmarshal")
}
value = append(value, part.Value...)
if len(part.Value) == 0 || len(part.NextLink) == 0 {
if len(part.Value) == 0 || (len(part.NextLink) == 0 && len(part.OdataNextLink) == 0) {
break
}
link, err := url.Parse(part.NextLink)
nextLink := part.NextLink
if len(nextLink) == 0 {
nextLink = part.OdataNextLink
}
link, err := url.Parse(nextLink)
if err != nil {
return nil, errors.Wrapf(err, "url.Parse(%s)", part.NextLink)
return nil, errors.Wrapf(err, "url.Parse(%s)", nextLink)
}
token := ""
for _, key := range []string{"$skipToken", "$skiptoken"} {
+8 -13
View File
@@ -54,13 +54,13 @@ func (group *SCloudgroup) GetDescription() string {
}
func (group *SCloudgroup) GetICloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
policies, err := group.client.GetCloudpolicies(group.Id)
policies, err := group.client.GetPrincipalPolicy(group.Id)
if err != nil {
return nil, errors.Wrapf(err, "GetCloudpolicies(%s)", group.Id)
}
ret := []cloudprovider.ICloudpolicy{}
for i := range policies {
ret = append(ret, &policies[i])
ret = append(ret, &SCloudpolicy{Id: policies[i].RoleDefinitionId})
}
return ret, nil
}
@@ -87,22 +87,17 @@ func (group *SCloudgroup) RemoveUser(name string) error {
}
func (group *SCloudgroup) AttachPolicy(policyId string, policyType api.TPolicyType) error {
return group.client.AssignPolicy(group.Id, policyId, "")
return group.client.AssignPolicy(group.Id, policyId)
}
func (group *SCloudgroup) DetachPolicy(policyId string, policyType api.TPolicyType) error {
assignments, err := group.client.GetAssignments(group.Id)
policys, err := group.client.GetPrincipalPolicy(group.Id)
if err != nil {
return errors.Wrapf(err, "GetAssignments(%s)", group.Id)
return err
}
for _, assignment := range assignments {
role, err := group.client.GetRole(assignment.Properties.RoleDefinitionId)
if err != nil {
return errors.Wrapf(err, "GetRule(%s)", assignment.Properties.RoleDefinitionId)
}
if role.Properties.RoleName == policyId {
_, err := group.client._delete_v2(SERVICE_GRAPH, assignment.Id, "")
return err
for _, policy := range policys {
if policy.RoleDefinitionId == policyId {
return group.client.DeletePrincipalPolicy(policy.Id)
}
}
return nil
-203
View File
@@ -1,203 +0,0 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package azure
import (
"fmt"
"net/url"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/stringutils"
api "yunion.io/x/cloudmux/pkg/apis/cloudid"
"yunion.io/x/cloudmux/pkg/cloudprovider"
)
type SPermission struct {
Actions []string
NotActions []string
DataActions []string
NotDataActions []string
}
type SRoleProperties struct {
RoleName string
Type string
Description string
AssignableScopes []string
Permissions []SPermission
}
type SCloudpolicy struct {
Id string
Type string
Name string
Properties SRoleProperties
}
func (role *SCloudpolicy) GetName() string {
return role.Properties.RoleName
}
func (role *SCloudpolicy) GetGlobalId() string {
return role.Properties.RoleName
}
func (role *SCloudpolicy) GetDescription() string {
return role.Properties.Description
}
func (role *SCloudpolicy) GetPolicyType() api.TPolicyType {
if role.Properties.Type == "BuiltInRole" {
return api.PolicyTypeSystem
}
return api.PolicyTypeCustom
}
func (role *SCloudpolicy) UpdateDocument(document *jsonutils.JSONDict) error {
return cloudprovider.ErrNotImplemented
}
func (role *SCloudpolicy) GetDocument() (*jsonutils.JSONDict, error) {
return jsonutils.Marshal(role.Properties).(*jsonutils.JSONDict), nil
}
func (role *SCloudpolicy) Delete() error {
return cloudprovider.ErrNotImplemented
}
func (cli *SAzureClient) GetRoles(name, policyType string) ([]SCloudpolicy, error) {
ret := []SCloudpolicy{}
filter := []string{}
if len(name) > 0 {
filter = append(filter, fmt.Sprintf("roleName eq '%s'", name))
}
if len(policyType) > 0 {
filter = append(filter, fmt.Sprintf("Type eq '%s'", policyType))
}
params := url.Values{}
if len(filter) > 0 {
params.Set("$filter", strings.Join(filter, " and "))
}
resource := "Microsoft.Authorization/roleDefinitions"
err := cli.list(resource, params, &ret)
if err != nil {
return nil, errors.Wrap(err, "list")
}
return ret, nil
}
func (cli *SAzureClient) GetICloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
roles, err := cli.GetRoles("", "")
if err != nil {
return nil, errors.Wrap(err, "GetRoles")
}
ret := []cloudprovider.ICloudpolicy{}
for i := range roles {
ret = append(ret, &roles[i])
}
return ret, nil
}
func (cli *SAzureClient) AssignPolicy(objectId, roleName, subscriptionId string) error {
roles, err := cli.GetRoles(roleName, "")
if err != nil {
return errors.Wrapf(err, "GetRoles(%s)", roleName)
}
if len(roles) == 0 {
return errors.Wrap(cloudprovider.ErrNotFound, roleName)
}
if len(roles) > 1 {
return errors.Wrap(cloudprovider.ErrDuplicateId, roleName)
}
body := map[string]interface{}{
"properties": map[string]interface{}{
"roleDefinitionId": roles[0].Id,
"principalId": objectId,
},
}
subscriptionIds := []string{}
if len(subscriptionId) == 0 {
for _, subscription := range cli.subscriptions {
subscriptionIds = append(subscriptionIds, subscription.SubscriptionId)
}
}
for _, subscriptionId := range subscriptionIds {
resource := fmt.Sprintf("subscriptions/%s/providers/Microsoft.Authorization/roleAssignments/%s", subscriptionId, stringutils.UUID4())
_, err = cli.put(resource, jsonutils.Marshal(body))
if err != nil {
if e, ok := err.(*AzureResponseError); ok && e.AzureError.Code == "ReadOnlyDisabledSubscription" || e.AzureError.Code == "PrincipalNotFound" {
continue
}
return errors.Wrapf(err, "AssignPolicy %s for subscription %s", roleName, subscriptionId)
}
}
return nil
}
type SAssignmentProperties struct {
RoleDefinitionId string
PrincipalId string
PrincipalType string
Scope string
}
type SAssignment struct {
Id string
Name string
Type string
Properties SAssignmentProperties
}
func (cli *SAzureClient) GetAssignments(objectId string) ([]SAssignment, error) {
ret := []SAssignment{}
params := url.Values{}
if len(objectId) > 0 {
params.Set("$filter", fmt.Sprintf("principalId eq '%s'", objectId))
}
resource := "Microsoft.Authorization/roleAssignments"
err := cli.list(resource, params, &ret)
if err != nil {
return nil, errors.Wrap(err, "list")
}
return ret, nil
}
func (cli *SAzureClient) GetRole(roleId string) (*SCloudpolicy, error) {
role := &SCloudpolicy{}
err := cli.get(roleId, nil, role)
if err != nil {
return nil, errors.Wrapf(err, "GetRole(%s)", roleId)
}
return role, nil
}
func (cli *SAzureClient) GetCloudpolicies(objectId string) ([]SCloudpolicy, error) {
assignments, err := cli.GetAssignments(objectId)
if err != nil {
return nil, errors.Wrapf(err, "GetAssignments(%s)", objectId)
}
ret := []SCloudpolicy{}
for _, assignment := range assignments {
role, err := cli.GetRole(assignment.Properties.RoleDefinitionId)
if err != nil {
return nil, errors.Wrapf(err, "GetRule(%s)", assignment.Properties.RoleDefinitionId)
}
ret = append(ret, *role)
}
return ret, nil
}
+8 -19
View File
@@ -103,40 +103,29 @@ func (user *SClouduser) GetInviteUrl() string {
}
func (user *SClouduser) GetICloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
policies, err := user.client.GetCloudpolicies(user.Id)
policies, err := user.client.GetPrincipalPolicy(user.Id)
if err != nil {
return nil, errors.Wrapf(err, "GetCloudpolicies(%s)", user.Id)
}
ret := []cloudprovider.ICloudpolicy{}
for i := range policies {
ret = append(ret, &policies[i])
ret = append(ret, &SCloudpolicy{Id: policies[i].RoleDefinitionId})
}
return ret, nil
}
func (user *SClouduser) AttachPolicy(policyId string, policyType api.TPolicyType) error {
for _, subscription := range user.client.subscriptions {
err := user.client.AssignPolicy(user.Id, policyId, subscription.SubscriptionId)
if err != nil {
return errors.Wrapf(err, "AssignPolicy for subscription %s", subscription.SubscriptionId)
}
}
return nil
return user.client.AssignPolicy(user.Id, policyId)
}
func (user *SClouduser) DetachPolicy(policyId string, policyType api.TPolicyType) error {
assignments, err := user.client.GetAssignments(user.Id)
policys, err := user.client.GetPrincipalPolicy(user.Id)
if err != nil {
return errors.Wrapf(err, "GetAssignments(%s)", user.Id)
return err
}
for _, assignment := range assignments {
role, err := user.client.GetRole(assignment.Properties.RoleDefinitionId)
if err != nil {
return errors.Wrapf(err, "GetRule(%s)", assignment.Properties.RoleDefinitionId)
}
if role.Properties.RoleName == policyId {
_, err := user.client._delete_v2(SERVICE_GRAPH, assignment.Id, "")
return err
for _, policy := range policys {
if policy.RoleDefinitionId == policyId {
return user.client.DeletePrincipalPolicy(policy.Id)
}
}
return nil
-141
View File
@@ -1,141 +0,0 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package azure
import (
"fmt"
"net/url"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
)
type SPolicyDefinitonPropertieParameterMetadata struct {
DisplayName string
Description string
StrongType string
AssignPermissions bool
}
type SPolicyDefinitonPropertieParameter struct {
Type string
Metadata SPolicyDefinitonPropertieParameterMetadata
AllowedValues []string
DefaultValue []string
}
type SPolicyDefinitonProperties struct {
DisplayName string
PolicyType string
Mode string
Description string
Metadata SPolicyDefinitonPropertieMetadata
Parameters map[string]SPolicyDefinitonPropertieParameter
PolicyRule SPolicyDefinitonPropertieRule
}
type SPolicyDefinitonPropertieRuleThen struct {
Effect string
}
type SPolicyDefinitonPropertieRuleInfo jsonutils.JSONDict
type SPolicyDefinitonPropertieRule struct {
If jsonutils.JSONObject
Then SPolicyDefinitonPropertieRuleThen
}
type SPolicyDefinitonPropertieMetadata struct {
Version string
Category string
}
type SPolicyDefinition struct {
Properties SPolicyDefinitonProperties
Id string
Name string
Type string
}
func (client *SAzureClient) GetPolicyDefinitions() ([]SPolicyDefinition, error) {
definitions := []SPolicyDefinition{}
err := client.list("Microsoft.Authorization/policyDefinitions", url.Values{}, &definitions)
if err != nil {
return nil, errors.Wrap(err, "Microsoft.Authorization/policyDefinitions.List")
}
return definitions, nil
}
func (client *SAzureClient) GetPolicyDefinition(id string) (*SPolicyDefinition, error) {
definition := &SPolicyDefinition{}
err := client.get(id, url.Values{}, definition)
if err != nil {
return nil, errors.Wrapf(err, "get %s", id)
}
return definition, nil
}
type PolicyAssignmentPropertiesParameter struct {
Value []string
}
type PolicyAssignmentProperties struct {
DisplayName string
Parameters map[string]PolicyAssignmentPropertiesParameter
}
type SPolicyAssignment struct {
Id string
Properties PolicyAssignmentProperties
values []string
category string
condition string
parameters *jsonutils.JSONDict
}
func (assignment *SPolicyAssignment) GetName() string {
return assignment.Properties.DisplayName
}
func (assignment *SPolicyAssignment) GetGlobalId() string {
return strings.ToLower(assignment.Id)
}
func (assignment *SPolicyAssignment) GetCategory() string {
return assignment.category
}
func (assignment *SPolicyAssignment) GetCondition() string {
return assignment.condition
}
func (assignment *SPolicyAssignment) GetParameters() *jsonutils.JSONDict {
return assignment.parameters
}
func (client *SAzureClient) GetPolicyAssignments(defineId string) ([]SPolicyAssignment, error) {
assignments := []SPolicyAssignment{}
resource := "Microsoft.Authorization/policyAssignments"
params := url.Values{}
if len(defineId) > 0 {
params.Set("$filter", fmt.Sprintf(`policyDefinitionId eq '%s'`, defineId))
}
err := client.list(resource, params, &assignments)
if err != nil {
return nil, errors.Wrap(err, "Microsoft.Authorization/policyAssignments.List")
}
return assignments, nil
}
+152
View File
@@ -0,0 +1,152 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package azure
import (
"fmt"
"net/url"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/cloudmux/pkg/apis/cloudid"
"yunion.io/x/cloudmux/pkg/cloudprovider"
)
type SCloudpolicy struct {
Id string
Description string
DisplayName string
IsBuildIn bool
IsEnabled bool
ResourceScopes []string
TemplateId string
Version string
RolePermissions []struct {
allowedResourceActions []string
Condition string
}
InheritsPermissionsFrom []struct {
Id string
}
}
func (role *SCloudpolicy) GetName() string {
return role.DisplayName
}
func (role *SCloudpolicy) GetGlobalId() string {
return role.Id
}
func (role *SCloudpolicy) GetDescription() string {
return role.Description
}
func (role *SCloudpolicy) GetPolicyType() api.TPolicyType {
if role.IsBuildIn {
return api.PolicyTypeSystem
}
return api.PolicyTypeCustom
}
func (role *SCloudpolicy) UpdateDocument(document *jsonutils.JSONDict) error {
return cloudprovider.ErrNotImplemented
}
func (role *SCloudpolicy) GetDocument() (*jsonutils.JSONDict, error) {
return jsonutils.Marshal(role).(*jsonutils.JSONDict), nil
}
func (role *SCloudpolicy) Delete() error {
return cloudprovider.ErrNotImplemented
}
func (cli *SAzureClient) GetRoles(name string) ([]SCloudpolicy, error) {
ret := []SCloudpolicy{}
filter := []string{}
if len(name) > 0 {
filter = append(filter, fmt.Sprintf("displayName eq '%s'", name))
}
params := url.Values{}
if len(filter) > 0 {
params.Set("$filter", strings.Join(filter, " and "))
}
resp, err := cli._list_v2(SERVICE_GRAPH, "rolemanagement/directory/roleDefinitions", "", nil)
if err != nil {
return nil, errors.Wrap(err, "list")
}
err = resp.Unmarshal(&ret, "value")
if err != nil {
return nil, err
}
return ret, nil
}
func (cli *SAzureClient) GetICloudpolicies() ([]cloudprovider.ICloudpolicy, error) {
roles, err := cli.GetRoles("")
if err != nil {
return nil, errors.Wrap(err, "GetRoles")
}
ret := []cloudprovider.ICloudpolicy{}
for i := range roles {
ret = append(ret, &roles[i])
}
return ret, nil
}
func (cli *SAzureClient) AssignPolicy(objectId, roleId string) error {
body := map[string]interface{}{
"roleDefinitionId": roleId,
"principalId": objectId,
"directoryScopeId": "/",
}
_, err := cli._post_v2(SERVICE_GRAPH, "roleManagement/directory/roleAssignments", "", body)
return err
}
type SPrincipalPolicy struct {
RoleDefinitionId string
PrincipalId string
Id string
}
func (cli *SAzureClient) GetPrincipalPolicy(principalId string) ([]SPrincipalPolicy, error) {
params := url.Values{}
filter := []string{}
if len(principalId) > 0 {
filter = append(filter, fmt.Sprintf("principalId eq '%s'", principalId))
}
if len(filter) > 0 {
params.Set("$filter", strings.Join(filter, " and "))
}
resp, err := cli._list_v2(SERVICE_GRAPH, "rolemanagement/directory/roleAssignments", "", params)
if err != nil {
return nil, err
}
ret := []SPrincipalPolicy{}
err = resp.Unmarshal(&ret, "value")
if err != nil {
return nil, err
}
return ret, nil
}
func (cli *SAzureClient) DeletePrincipalPolicy(assignmentId string) error {
res := fmt.Sprintf("roleManagement/directory/roleAssignments/%s", assignmentId)
_, err := cli._delete_v2(SERVICE_GRAPH, res, "")
return err
}