From 69780561f9e504524cd381f93a88277cca7d4d9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B1=88=E8=BD=A9?= Date: Wed, 20 Nov 2024 20:15:47 +0800 Subject: [PATCH] fix(cloudid): vendor update for azure iam (#21643) --- go.mod | 2 +- go.sum | 4 +- pkg/cloudid/drivers/azure.go | 87 ++++++++ pkg/cloudid/models/cloudgroup.go | 2 +- vendor/modules.txt | 2 +- .../x/cloudmux/pkg/multicloud/azure/azure.go | 4 +- .../cloudmux/pkg/multicloud/azure/azure_v2.go | 19 +- .../pkg/multicloud/azure/cloudgroup.go | 21 +- .../pkg/multicloud/azure/cloudpolicy.go | 203 ------------------ .../pkg/multicloud/azure/clouduser.go | 27 +-- .../x/cloudmux/pkg/multicloud/azure/policy.go | 141 ------------ .../x/cloudmux/pkg/multicloud/azure/role.go | 152 +++++++++++++ 12 files changed, 277 insertions(+), 387 deletions(-) delete mode 100644 vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/cloudpolicy.go delete mode 100644 vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/policy.go create mode 100644 vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/role.go diff --git a/go.mod b/go.mod index d35d563813..80a1504718 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index c4e4c54ec3..dfac3bef7c 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/pkg/cloudid/drivers/azure.go b/pkg/cloudid/drivers/azure.go index 7b3ca41ca8..a85b704836 100644 --- a/pkg/cloudid/drivers/azure.go +++ b/pkg/cloudid/drivers/azure.go @@ -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 +} diff --git a/pkg/cloudid/models/cloudgroup.go b/pkg/cloudid/models/cloudgroup.go index 4cb49ea233..816c3e03b1 100644 --- a/pkg/cloudid/models/cloudgroup.go +++ b/pkg/cloudid/models/cloudgroup.go @@ -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) diff --git a/vendor/modules.txt b/vendor/modules.txt index 43819bb87f..caaaa029f1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -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 diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/azure.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/azure.go index 3b670ee47a..5384bdc21b 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/azure.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/azure.go @@ -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"` diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/azure_v2.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/azure_v2.go index 93204e088f..6c2fcdc470 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/azure_v2.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/azure_v2.go @@ -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"} { diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/cloudgroup.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/cloudgroup.go index 537e39dac4..db0d2fccb6 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/cloudgroup.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/cloudgroup.go @@ -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 diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/cloudpolicy.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/cloudpolicy.go deleted file mode 100644 index da95887ab9..0000000000 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/cloudpolicy.go +++ /dev/null @@ -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 -} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/clouduser.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/clouduser.go index f5b422027d..6e3d89a6fd 100644 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/clouduser.go +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/clouduser.go @@ -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 diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/policy.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/policy.go deleted file mode 100644 index 135911a06f..0000000000 --- a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/policy.go +++ /dev/null @@ -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 -} diff --git a/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/role.go b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/role.go new file mode 100644 index 0000000000..6d8b8ac26f --- /dev/null +++ b/vendor/yunion.io/x/cloudmux/pkg/multicloud/azure/role.go @@ -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 +}