diff --git a/pkg/multicloud/huaweistack/cloudgroup.go b/pkg/multicloud/huaweistack/cloudgroup.go index c6c3b12608..52481321ad 100644 --- a/pkg/multicloud/huaweistack/cloudgroup.go +++ b/pkg/multicloud/huaweistack/cloudgroup.go @@ -71,7 +71,7 @@ func (group *SCloudgroup) DetachSystemPolicy(roleId string) error { } func (group *SCloudgroup) DetachCustomPolicy(roleId string) error { - return group.client.DetachGroupRole(group.Id, roleId) + return group.client.DetachGroupCustomRole(group.Id, roleId) } func (group *SCloudgroup) AttachSystemPolicy(roleId string) error { @@ -79,7 +79,7 @@ func (group *SCloudgroup) AttachSystemPolicy(roleId string) error { } func (group *SCloudgroup) AttachCustomPolicy(roleId string) error { - return group.client.AttachGroupRole(group.Id, roleId) + return group.client.AttachGroupCustomRole(group.Id, roleId) } func (group *SCloudgroup) GetISystemCloudpolicies() ([]cloudprovider.ICloudpolicy, error) { @@ -89,13 +89,25 @@ func (group *SCloudgroup) GetISystemCloudpolicies() ([]cloudprovider.ICloudpolic } ret := []cloudprovider.ICloudpolicy{} for i := range roles { - ret = append(ret, &roles[i]) + if roles[i].Catelog != "CUSTOMED" { + ret = append(ret, &roles[i]) + } } return ret, nil } func (group *SCloudgroup) GetICustomCloudpolicies() ([]cloudprovider.ICloudpolicy, error) { - return []cloudprovider.ICloudpolicy{}, nil + roles, err := group.client.GetGroupRoles(group.Id) + if err != nil { + return nil, errors.Wrap(err, "GetGroupRoles") + } + ret := []cloudprovider.ICloudpolicy{} + for i := range roles { + if roles[i].Catelog == "CUSTOMED" { + ret = append(ret, &roles[i]) + } + } + return ret, nil } func (group *SCloudgroup) GetICloudusers() ([]cloudprovider.IClouduser, error) { @@ -261,23 +273,70 @@ func (self *SHuaweiClient) DetachGroupRole(groupId, roleId string) error { if err != nil { return errors.Wrapf(err, "GetRole(%s)", roleId) } - err = client.Groups.DeleteRole(self.ownerId, groupId, role.Id) - if err != nil { - return errors.Wrapf(err, "DeleteRole") - } - projects, err := self.GetProjects() - if err != nil { - return errors.Wrapf(err, "GetProjects") - } - for _, project := range projects { - err = client.Groups.DeleteProjectRole(project.ID, groupId, role.Id) + if role.Type == "AX" || role.Type == "AA" { + err = client.Groups.DeleteRole(self.ownerId, groupId, role.Id) if err != nil { - return errors.Wrapf(err, "DeleteProjectRole") + return errors.Wrapf(err, "DeleteRole") + } + } + if role.Type == "XA" || role.Type == "AA" { + projects, err := self.GetProjects() + if err != nil { + return errors.Wrapf(err, "GetProjects") + } + for _, project := range projects { + err = client.Groups.DeleteProjectRole(project.ID, groupId, role.Id) + if err != nil { + return errors.Wrapf(err, "DeleteProjectRole") + } } } return nil } +func (self *SHuaweiClient) DetachGroupCustomRole(groupId, roleId string) error { + client, err := self.newGeneralAPIClient() + if err != nil { + return errors.Wrap(err, "newGeneralAPIClient") + } + role, err := self.GetCustomRole(roleId) + if err != nil { + return errors.Wrapf(err, "GetCustomRole(%s)", roleId) + } + if role.Type == "AX" || role.Type == "AA" { + err = client.Groups.DeleteRole(self.ownerId, groupId, role.Id) + if err != nil { + return errors.Wrapf(err, "DeleteRole") + } + } + if role.Type == "XA" || role.Type == "AA" { + projects, err := self.GetProjects() + if err != nil { + return errors.Wrapf(err, "GetProjects") + } + for _, project := range projects { + err = client.Groups.DeleteProjectRole(project.ID, groupId, role.Id) + if err != nil { + return errors.Wrapf(err, "DeleteProjectRole") + } + } + } + return nil +} + +func (self *SHuaweiClient) GetCustomRole(name string) (*SRole, error) { + roles, err := self.GetCustomRoles() + if err != nil { + return nil, errors.Wrapf(err, "GetCustomRoles(%s)", name) + } + for i := range roles { + if roles[i].DisplayName == name { + return &roles[i], nil + } + } + return nil, errors.Wrapf(cloudprovider.ErrNotFound, name) +} + func (self *SHuaweiClient) GetRole(name string) (*SRole, error) { roles, err := self.GetRoles("", "") if err != nil { @@ -300,18 +359,52 @@ func (self *SHuaweiClient) AttachGroupRole(groupId, roleId string) error { if err != nil { return errors.Wrapf(err, "GetRole(%s)", roleId) } - err = client.Groups.AddRole(self.ownerId, groupId, role.Id) - if err != nil { - return errors.Wrapf(err, "AddRole") - } - projects, err := self.GetProjects() - if err != nil { - return errors.Wrapf(err, "GetProjects") - } - for _, project := range projects { - err = client.Groups.AddProjectRole(project.ID, groupId, role.Id) + if role.Type == "AX" || role.Type == "AA" { + err = client.Groups.AddRole(self.ownerId, groupId, role.Id) if err != nil { - return errors.Wrapf(err, "AddProjectRole") + return errors.Wrapf(err, "AddRole") + } + } + if role.Type == "XA" || role.Type == "AA" { + projects, err := self.GetProjects() + if err != nil { + return errors.Wrapf(err, "GetProjects") + } + for _, project := range projects { + err = client.Groups.AddProjectRole(project.ID, groupId, role.Id) + if err != nil { + return errors.Wrapf(err, "AddProjectRole") + } + } + } + return nil +} + +func (self *SHuaweiClient) AttachGroupCustomRole(groupId, roleId string) error { + client, err := self.newGeneralAPIClient() + if err != nil { + return errors.Wrap(err, "newGeneralAPIClient") + } + role, err := self.GetCustomRole(roleId) + if err != nil { + return errors.Wrapf(err, "GetRole(%s)", roleId) + } + if role.Type == "AX" || role.Type == "AA" { + err = client.Groups.AddRole(self.ownerId, groupId, role.Id) + if err != nil { + return errors.Wrapf(err, "AddRole") + } + } + if role.Type == "XA" || role.Type == "AA" { + projects, err := self.GetProjects() + if err != nil { + return errors.Wrapf(err, "GetProjects") + } + for _, project := range projects { + err = client.Groups.AddProjectRole(project.ID, groupId, role.Id) + if err != nil { + return errors.Wrapf(err, "AddProjectRole") + } } } return nil diff --git a/pkg/multicloud/huaweistack/provider/provider.go b/pkg/multicloud/huaweistack/provider/provider.go index f4eef53006..5bd1fab644 100644 --- a/pkg/multicloud/huaweistack/provider/provider.go +++ b/pkg/multicloud/huaweistack/provider/provider.go @@ -296,7 +296,11 @@ func (self *SHuaweiCloudStackProvider) GetISystemCloudpolicies() ([]cloudprovide } func (self *SHuaweiCloudStackProvider) GetICustomCloudpolicies() ([]cloudprovider.ICloudpolicy, error) { - return []cloudprovider.ICloudpolicy{}, nil + return self.client.GetICustomCloudpolicies() +} + +func (self *SHuaweiCloudStackProvider) CreateICloudpolicy(opts *cloudprovider.SCloudpolicyCreateOptions) (cloudprovider.ICloudpolicy, error) { + return self.client.CreateICloudpolicy(opts) } func (self *SHuaweiCloudStackProvider) GetIClouduserByName(name string) (cloudprovider.IClouduser, error) { diff --git a/pkg/multicloud/huaweistack/roles.go b/pkg/multicloud/huaweistack/roles.go index 267ce49580..d16cc4935c 100644 --- a/pkg/multicloud/huaweistack/roles.go +++ b/pkg/multicloud/huaweistack/roles.go @@ -18,6 +18,7 @@ import ( "yunion.io/x/jsonutils" "yunion.io/x/pkg/errors" + api "yunion.io/x/onecloud/pkg/apis/cloudid" "yunion.io/x/onecloud/pkg/cloudprovider" ) @@ -34,6 +35,7 @@ type SRole struct { CreatedTime string Links SLink Policy jsonutils.JSONDict + roleType string } func (role *SRole) GetName() string { @@ -45,7 +47,7 @@ func (role *SRole) GetDescription() string { } func (role *SRole) GetPolicyType() string { - return "System" + return role.roleType } func (role *SRole) GetGlobalId() string { @@ -71,11 +73,74 @@ func (self *SHuaweiClient) GetISystemCloudpolicies() ([]cloudprovider.ICloudpoli } ret := []cloudprovider.ICloudpolicy{} for i := range roles { + roles[i].roleType = api.CLOUD_POLICY_TYPE_SYSTEM ret = append(ret, &roles[i]) } return ret, nil } +func (self *SHuaweiClient) GetICustomCloudpolicies() ([]cloudprovider.ICloudpolicy, error) { + roles, err := self.GetCustomRoles() + if err != nil { + return nil, errors.Wrap(err, "GetCustomRoles") + } + ret := []cloudprovider.ICloudpolicy{} + for i := range roles { + roles[i].roleType = api.CLOUD_POLICY_TYPE_CUSTOM + ret = append(ret, &roles[i]) + } + return ret, nil +} + +func (self *SHuaweiClient) GetCustomRoles() ([]SRole, error) { + params := map[string]string{} + + client, err := self.newGeneralAPIClient() + if err != nil { + return nil, errors.Wrap(err, "newGeneralAPIClient") + } + + client.Roles.SetVersion("v3.0/OS-ROLE") + defer client.Roles.SetVersion("v3.0") + + roles := []SRole{} + err = doListAllWithNextLink(client.Roles.List, params, &roles) + if err != nil { + return nil, errors.Wrap(err, "doListAllWithOffset") + } + return roles, nil +} + +func (self *SHuaweiClient) CreateICloudpolicy(opts *cloudprovider.SCloudpolicyCreateOptions) (cloudprovider.ICloudpolicy, error) { + client, err := self.newGeneralAPIClient() + if err != nil { + return nil, errors.Wrap(err, "newGeneralAPIClient") + } + + client.Roles.SetVersion("v3.0/OS-ROLE") + defer client.Roles.SetVersion("v3.0") + + params := map[string]interface{}{ + "role": map[string]interface{}{ + "display_name": opts.Name, + "type": "XA", + "description": opts.Desc, + "policy": opts.Document, + }, + } + + resp, err := client.Roles.Create(jsonutils.Marshal(params)) + if err != nil { + return nil, err + } + role := &SRole{roleType: api.CLOUD_POLICY_TYPE_CUSTOM} + err = resp.Unmarshal(role) + if err != nil { + return nil, err + } + return role, nil +} + func (self *SHuaweiClient) GetRoles(domainId, name string) ([]SRole, error) { params := map[string]string{} if len(domainId) > 0 {