feature: CloudId服务支持

This commit is contained in:
Qu Xuan
2020-04-13 17:44:44 +08:00
parent b426505662
commit a07b112be1
319 changed files with 42553 additions and 21185 deletions

View File

@@ -36,7 +36,7 @@ jobs:
make cmd/ansibleserver cmd/cloudnet cmd/notify
make cmd/host-deployer && ./scripts/bundle_libraries.sh _output/bin/bundles/host-deployer _output/bin/host-deployer
make cmd/baremetal-agent && ./scripts/bundle_libraries.sh _output/bin/bundles/baremetal-agent _output/bin/baremetal-agent
make cmd/cloudevent cmd/devtool
make cmd/cloudevent cmd/devtool cmd/cloudid
make cmd/*cli
make cmd/esxi-agent
make docker-alpine-build F='-j4 cmd/host cmd/vpcagent cmd/region-dns'
@@ -211,6 +211,16 @@ jobs:
snapshot: true
dockerfile: build/docker/Dockerfile.cloudevent
- name: Image cloudid
uses: elgohr/Publish-Docker-Github-Action@master
with:
name: registry.cn-beijing.aliyuncs.com/yunionio/cloudid
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
registry: registry.cn-beijing.aliyuncs.com
snapshot: true
dockerfile: build/docker/Dockerfile.cloudid
- name: Image devtool
uses: elgohr/Publish-Docker-Github-Action@master
with:

1
build/cloudid/vars Normal file
View File

@@ -0,0 +1 @@
DESCRIPTION="Yunion CloudId"

View File

@@ -0,0 +1,3 @@
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:latest
ADD ./_output/bin/cloudid /opt/yunion/bin/cloudid

View File

@@ -19,6 +19,7 @@ import (
_ "yunion.io/x/onecloud/cmd/climc/shell"
_ "yunion.io/x/onecloud/cmd/climc/shell/ansible"
_ "yunion.io/x/onecloud/cmd/climc/shell/cloudevent"
_ "yunion.io/x/onecloud/cmd/climc/shell/cloudid"
_ "yunion.io/x/onecloud/cmd/climc/shell/cloudnet"
_ "yunion.io/x/onecloud/cmd/climc/shell/compute"
_ "yunion.io/x/onecloud/cmd/climc/shell/etcd"

View File

@@ -0,0 +1,167 @@
// 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 cloudid
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
func init() {
type CloudgroupListOptions struct {
options.BaseListOptions
ClouduserId string `json:"clouduser_id"`
CloudpolicyId string `json:"cloudpolicy_id"`
}
R(&CloudgroupListOptions{}, "cloud-group-list", "List cloud groups", func(s *mcclient.ClientSession, opts *CloudgroupListOptions) error {
params, err := options.ListStructToParams(opts)
if err != nil {
return err
}
result, err := modules.Cloudgroups.List(s, params)
if err != nil {
return err
}
printList(result, modules.Cloudgroups.GetColumns(s))
return nil
})
type CloudgroupCreateOptions struct {
NAME string `json:"name"`
PROVIDER string `json:"provider" choices:"Google|Aliyun|Aws|Huawei|Qcloud"`
CloudpolicyIds []string `json:"cloudpolicy_ids"`
Desc string `json:"description"`
}
R(&CloudgroupCreateOptions{}, "cloud-group-create", "Create cloud group", func(s *mcclient.ClientSession, opts *CloudgroupCreateOptions) error {
params := jsonutils.Marshal(opts)
result, err := modules.Cloudgroups.Create(s, params)
if err != nil {
return err
}
printObject(result)
return nil
})
type CloudgroupIdOptions struct {
ID string `help:"Cloudgroup Id"`
}
R(&CloudgroupIdOptions{}, "cloud-group-delete", "Delete cloud group", func(s *mcclient.ClientSession, opts *CloudgroupIdOptions) error {
result, err := modules.Cloudgroups.Delete(s, opts.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&CloudgroupIdOptions{}, "cloud-group-show", "Show cloud group", func(s *mcclient.ClientSession, opts *CloudgroupIdOptions) error {
result, err := modules.Cloudgroups.Get(s, opts.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&CloudgroupIdOptions{}, "cloud-group-syncstatus", "Sync cloud group status", func(s *mcclient.ClientSession, opts *CloudgroupIdOptions) error {
result, err := modules.Cloudgroups.PerformAction(s, opts.ID, "syncstatus", nil)
if err != nil {
return err
}
printObject(result)
return nil
})
type CloudgroupPolicyOptions struct {
ID string `help:"Cloudgroup Id"`
CLOUDPOLICY_ID string `help:"Cloudpolicy Id"`
}
R(&CloudgroupPolicyOptions{}, "cloud-group-attach-policy", "Attach policy for cloud group", func(s *mcclient.ClientSession, opts *CloudgroupPolicyOptions) error {
result, err := modules.Cloudgroups.PerformAction(s, opts.ID, "attach-policy", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
R(&CloudgroupPolicyOptions{}, "cloud-group-detach-policy", "Detach policy from cloud group", func(s *mcclient.ClientSession, opts *CloudgroupPolicyOptions) error {
result, err := modules.Cloudgroups.PerformAction(s, opts.ID, "detach-policy", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
type CloudgroupUserOptions struct {
ID string `help:"Cloudgroup Id"`
CLOUDUSER_ID string `help:"Clouduser Id"`
}
R(&CloudgroupUserOptions{}, "cloud-group-add-user", "Add user to cloud group", func(s *mcclient.ClientSession, opts *CloudgroupUserOptions) error {
result, err := modules.Cloudgroups.PerformAction(s, opts.ID, "add-user", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
R(&CloudgroupUserOptions{}, "cloud-group-remove-user", "Remove user from cloud group", func(s *mcclient.ClientSession, opts *CloudgroupUserOptions) error {
result, err := modules.Cloudgroups.PerformAction(s, opts.ID, "remove-user", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
type CloudgroupPoliciesOptions struct {
ID string `help:"Cloudgroup Id"`
CloudpolicyIds []string `json:"cloudpolicy_ids"`
}
R(&CloudgroupPoliciesOptions{}, "cloud-group-set-policies", "Set cloudpolicies for cloud group", func(s *mcclient.ClientSession, opts *CloudgroupPoliciesOptions) error {
result, err := modules.Cloudgroups.PerformAction(s, opts.ID, "set-policies", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
type CloudgroupUsersOptions struct {
ID string `help:"Cloudgroup Id"`
ClouduserIds []string `json:"clouduser_ids"`
}
R(&CloudgroupUsersOptions{}, "cloud-group-set-users", "Set users for cloud group", func(s *mcclient.ClientSession, opts *CloudgroupUsersOptions) error {
result, err := modules.Cloudgroups.PerformAction(s, opts.ID, "set-users", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
}

View File

@@ -0,0 +1,73 @@
// 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 cloudid
import (
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
func init() {
type CloudgroupcacheListOptions struct {
options.BaseListOptions
CloudgroupId string `json:"cloudgroup_id"`
}
R(&CloudgroupcacheListOptions{}, "cloud-group-cache-list", "List cloud group caches", func(s *mcclient.ClientSession, opts *CloudgroupcacheListOptions) error {
params, err := options.ListStructToParams(opts)
if err != nil {
return err
}
result, err := modules.Cloudgroupcaches.List(s, params)
if err != nil {
return err
}
printList(result, modules.Cloudgroupcaches.GetColumns(s))
return nil
})
type CloudgroupcacheIdOption struct {
ID string `help:"Cloudgroup Id"`
}
R(&CloudgroupcacheIdOption{}, "cloud-group-cache-show", "Show cloud groupcache details", func(s *mcclient.ClientSession, opts *CloudgroupcacheIdOption) error {
result, err := modules.Cloudgroupcaches.Get(s, opts.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&CloudgroupcacheIdOption{}, "cloud-group-cache-syncstatus", "Sync cloudgroupcache", func(s *mcclient.ClientSession, opts *CloudgroupcacheIdOption) error {
result, err := modules.Cloudgroupcaches.PerformAction(s, opts.ID, "syncstatus", nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&CloudgroupcacheIdOption{}, "cloud-group-cache-delete", "Delete cloudgroupcache", func(s *mcclient.ClientSession, opts *CloudgroupcacheIdOption) error {
result, err := modules.Cloudgroupcaches.Delete(s, opts.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
}

View File

@@ -0,0 +1,72 @@
// 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 cloudid
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
func init() {
type CloudgroupPolicyListOptions struct {
options.BaseListOptions
Cloudgroup string `help:"ID or Name of Cloudgroup"`
Cloudpolicy string `help:"Policy ID or name"`
}
R(&CloudgroupPolicyListOptions{}, "cloud-group-policy-list", "List cloudgroup cloudpolicy pairs", func(s *mcclient.ClientSession, args *CloudgroupPolicyListOptions) error {
var params *jsonutils.JSONDict
{
var err error
params, err = args.BaseListOptions.Params()
if err != nil {
return err
}
}
var result *modulebase.ListResult
var err error
if len(args.Cloudgroup) > 0 {
result, err = modules.Cloudgrouppolicies.ListDescendent(s, args.Cloudgroup, params)
} else if len(args.Cloudpolicy) > 0 {
result, err = modules.Cloudgrouppolicies.ListDescendent2(s, args.Cloudpolicy, params)
} else {
result, err = modules.Cloudgrouppolicies.List(s, params)
}
if err != nil {
return err
}
printList(result, modules.Cloudgrouppolicies.GetColumns(s))
return nil
})
type CloudgroupPolicyDetailOptions struct {
CLOUDUSER string `help:"ID or Name of Cloudgroup"`
CLOUDPOLICY string `help:"ID or Name of Cloudpolicy"`
}
R(&CloudgroupPolicyDetailOptions{}, "cloud-group-policy-show", "Show cloudgrouppolicy details", func(s *mcclient.ClientSession, args *CloudgroupPolicyDetailOptions) error {
query := jsonutils.NewDict()
result, err := modules.Cloudgrouppolicies.Get(s, args.CLOUDUSER, args.CLOUDPOLICY, query)
if err != nil {
return err
}
printObject(result)
return nil
})
}

View File

@@ -0,0 +1,72 @@
// 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 cloudid
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
func init() {
type CloudgroupUserListOptions struct {
options.BaseListOptions
Cloudgroup string `help:"ID or Name of Cloudgroup"`
Clouduser string `help:"User ID or name"`
}
R(&CloudgroupUserListOptions{}, "cloud-group-user-list", "List cloudgroup clouduser pairs", func(s *mcclient.ClientSession, args *CloudgroupUserListOptions) error {
var params *jsonutils.JSONDict
{
var err error
params, err = args.BaseListOptions.Params()
if err != nil {
return err
}
}
var result *modulebase.ListResult
var err error
if len(args.Cloudgroup) > 0 {
result, err = modules.Cloudgroupusers.ListDescendent(s, args.Cloudgroup, params)
} else if len(args.Clouduser) > 0 {
result, err = modules.Cloudgroupusers.ListDescendent2(s, args.Clouduser, params)
} else {
result, err = modules.Cloudgroupusers.List(s, params)
}
if err != nil {
return err
}
printList(result, modules.Cloudgroupusers.GetColumns(s))
return nil
})
type CloudgroupUserDetailOptions struct {
CLOUDUSER string `help:"ID or Name of Cloudgroup"`
CLOUDPOLICY string `help:"ID or Name of Clouduser"`
}
R(&CloudgroupUserDetailOptions{}, "cloud-group-user-show", "Show cloudgroupuser details", func(s *mcclient.ClientSession, args *CloudgroupUserDetailOptions) error {
query := jsonutils.NewDict()
result, err := modules.Cloudgroupusers.Get(s, args.CLOUDUSER, args.CLOUDPOLICY, query)
if err != nil {
return err
}
printObject(result)
return nil
})
}

View File

@@ -0,0 +1,81 @@
// 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 cloudid
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
func init() {
type CloudpolicyListOptions struct {
options.BaseListOptions
ClouduserId string `json:"clouduser_id"`
CloudgroupId string `json:"cloudgroup_id"`
}
R(&CloudpolicyListOptions{}, "cloud-policy-list", "List cloud policies", func(s *mcclient.ClientSession, opts *CloudpolicyListOptions) error {
params, err := options.ListStructToParams(opts)
if err != nil {
return err
}
result, err := modules.Cloudpolicies.List(s, params)
if err != nil {
return err
}
printList(result, modules.Cloudpolicies.GetColumns(s))
return nil
})
type CloudpolicyIdOptions struct {
ID string `help:"Cloudpolicy Id"`
}
R(&CloudpolicyIdOptions{}, "cloud-policy-show", "Sow cloud policiy details", func(s *mcclient.ClientSession, opts *CloudpolicyIdOptions) error {
result, err := modules.Cloudpolicies.Get(s, opts.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
type CloudpolicyGroupOptions struct {
ID string `help:"Cloudpolicy Id"`
CLOUDGROUP_ID string `help:"Cloudgroup Id" json:"cloudgroup_id"`
}
R(&CloudpolicyGroupOptions{}, "cloud-policy-assign-group", "Assign cloud policiy to group", func(s *mcclient.ClientSession, opts *CloudpolicyGroupOptions) error {
result, err := modules.Cloudpolicies.PerformAction(s, opts.ID, "assign-group", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
R(&CloudpolicyGroupOptions{}, "cloud-policy-revoke-group", "Revoke cloud policiy from group", func(s *mcclient.ClientSession, opts *CloudpolicyGroupOptions) error {
result, err := modules.Cloudpolicies.PerformAction(s, opts.ID, "revoke-group", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
}

View File

@@ -0,0 +1,72 @@
// 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 cloudid
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
func init() {
type ClouduserPolicyListOptions struct {
options.BaseListOptions
Clouduser string `help:"ID or Name of Clouduser"`
Cloudpolicy string `help:"Policy ID or name"`
}
R(&ClouduserPolicyListOptions{}, "cloud-user-policy-list", "List clouduser cloudpolicy pairs", func(s *mcclient.ClientSession, args *ClouduserPolicyListOptions) error {
var params *jsonutils.JSONDict
{
var err error
params, err = args.BaseListOptions.Params()
if err != nil {
return err
}
}
var result *modulebase.ListResult
var err error
if len(args.Clouduser) > 0 {
result, err = modules.Clouduserpolicies.ListDescendent(s, args.Clouduser, params)
} else if len(args.Cloudpolicy) > 0 {
result, err = modules.Clouduserpolicies.ListDescendent2(s, args.Cloudpolicy, params)
} else {
result, err = modules.Clouduserpolicies.List(s, params)
}
if err != nil {
return err
}
printList(result, modules.Clouduserpolicies.GetColumns(s))
return nil
})
type ClouduserPolicyDetailOptions struct {
CLOUDUSER string `help:"ID or Name of Clouduser"`
CLOUDPOLICY string `help:"ID or Name of Cloudpolicy"`
}
R(&ClouduserPolicyDetailOptions{}, "cloud-user-policy-show", "Show clouduserpolicy details", func(s *mcclient.ClientSession, args *ClouduserPolicyDetailOptions) error {
query := jsonutils.NewDict()
result, err := modules.Clouduserpolicies.Get(s, args.CLOUDUSER, args.CLOUDPOLICY, query)
if err != nil {
return err
}
printObject(result)
return nil
})
}

View File

@@ -0,0 +1,197 @@
// 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 cloudid
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
func init() {
type ClouduserListOptions struct {
options.BaseListOptions
CloudaccountId string `help:"Cloudaccount Id"`
CloudproviderId string `help:"Cloudprovider Id"`
CloudpolicyId string `help:"filter cloudusers by cloudpolicy"`
CloudgroupId string `help:"filter cloudusers by cloudgroup"`
}
R(&ClouduserListOptions{}, "cloud-user-list", "List cloud users", func(s *mcclient.ClientSession, opts *ClouduserListOptions) error {
params, err := options.ListStructToParams(opts)
if err != nil {
return err
}
result, err := modules.Cloudusers.List(s, params)
if err != nil {
return err
}
printList(result, modules.Cloudusers.GetColumns(s))
return nil
})
type ClouduserCreateOptions struct {
Name string
CloudaccountId string `help:"Cloudaccount Id"`
CloudproviderId string `help:"Cloudprovider Id"`
OwnerId string `help:"Owner Id"`
CloudpolicyIds []string `help:"cloudpolicy ids"`
CloudgroupIds []string `help:"cloudgroup ids"`
Email string `help:"email address"`
MobilePhone string `help:"phone number"`
IsConsoleLogin *bool `help:"is console login"`
Password string `help:"clouduser password"`
}
R(&ClouduserCreateOptions{}, "cloud-user-create", "Create cloud user", func(s *mcclient.ClientSession, opts *ClouduserCreateOptions) error {
params := jsonutils.Marshal(opts)
result, err := modules.Cloudusers.Create(s, params)
if err != nil {
return err
}
printObject(result)
return nil
})
type ClouduserIdOptions struct {
ID string `help:"Clouduser Id"`
}
R(&ClouduserIdOptions{}, "cloud-user-delete", "Delete cloud user", func(s *mcclient.ClientSession, opts *ClouduserIdOptions) error {
result, err := modules.Cloudusers.Delete(s, opts.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&ClouduserIdOptions{}, "cloud-user-logininfo", "Show cloud user login info", func(s *mcclient.ClientSession, opts *ClouduserIdOptions) error {
result, err := modules.Cloudusers.GetLoginInfo(s, opts.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
R(&ClouduserIdOptions{}, "cloud-user-show", "Show cloud user", func(s *mcclient.ClientSession, opts *ClouduserIdOptions) error {
result, err := modules.Cloudusers.Get(s, opts.ID, nil)
if err != nil {
return err
}
printObject(result)
return nil
})
type ClouduserSyncOptions struct {
ID string `help:"Clouduser Id"`
PolicyOnly bool `help:"Ony sync clouduser policies for cloud"`
}
R(&ClouduserSyncOptions{}, "cloud-user-sync", "Sync cloud user policies", func(s *mcclient.ClientSession, opts *ClouduserSyncOptions) error {
result, err := modules.Cloudusers.PerformAction(s, opts.ID, "sync", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
R(&ClouduserIdOptions{}, "cloud-user-syncstatus", "Sync cloud user status", func(s *mcclient.ClientSession, opts *ClouduserIdOptions) error {
result, err := modules.Cloudusers.PerformAction(s, opts.ID, "syncstatus", nil)
if err != nil {
return err
}
printObject(result)
return nil
})
type ClouduserPolicyOptions struct {
ID string `help:"Clouduser Id"`
CLOUDPOLICY_ID string `help:"cloudpolicy Id"`
}
R(&ClouduserPolicyOptions{}, "cloud-user-attach-policy", "Attach policy for cloud user", func(s *mcclient.ClientSession, opts *ClouduserPolicyOptions) error {
result, err := modules.Cloudusers.PerformAction(s, opts.ID, "attach-policy", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
R(&ClouduserPolicyOptions{}, "cloud-user-detach-policy", "Detach policy from cloud user", func(s *mcclient.ClientSession, opts *ClouduserPolicyOptions) error {
result, err := modules.Cloudusers.PerformAction(s, opts.ID, "detach-policy", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
type ClouduserPasswordOptions struct {
ID string `help:"Clouduser Id"`
Password string `help:"clouduser password"`
}
R(&ClouduserPasswordOptions{}, "cloud-user-reset-password", "Reset clouduser password", func(s *mcclient.ClientSession, opts *ClouduserPasswordOptions) error {
result, err := modules.Cloudusers.PerformAction(s, opts.ID, "reset-password", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
type ClouduserChangeOwnerOptions struct {
ID string `help:"clouduser id"`
USER_ID string `help:"local user id"`
}
R(&ClouduserChangeOwnerOptions{}, "cloud-user-change-owner", "Change clouduser owner", func(s *mcclient.ClientSession, opts *ClouduserChangeOwnerOptions) error {
result, err := modules.Cloudusers.PerformAction(s, opts.ID, "change-owner", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
type ClouduserGroupOptions struct {
ID string `help:"clouduser id"`
CLOUDGROUP_ID string `help:"cloudgroup id" json:"cloudgroup_id"`
}
R(&ClouduserGroupOptions{}, "cloud-user-join-group", "Join user to cloudgroup", func(s *mcclient.ClientSession, opts *ClouduserGroupOptions) error {
result, err := modules.Cloudusers.PerformAction(s, opts.ID, "join-group", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
R(&ClouduserGroupOptions{}, "cloud-user-leave-group", "Leave from cloudgroup", func(s *mcclient.ClientSession, opts *ClouduserGroupOptions) error {
result, err := modules.Cloudusers.PerformAction(s, opts.ID, "leave-group", jsonutils.Marshal(opts))
if err != nil {
return err
}
printObject(result)
return nil
})
}

View File

@@ -0,0 +1,26 @@
// 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 cloudid
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/util/printutils"
)
var (
R = shell.R
printList = printutils.PrintJSONList
printObject = printutils.PrintJSONObject
)

View File

@@ -22,11 +22,11 @@ import (
)
func init() {
type ProjectResourceOptions struct {
type ScopeResourceOptions struct {
SERVICE string `help:"Service type"`
}
R(&ProjectResourceOptions{}, "project-resource-show", "query backend service for its project resource count", func(s *mcclient.ClientSession, args *ProjectResourceOptions) error {
body, err := modules.GetProjectResources(s, args.SERVICE)
R(&ScopeResourceOptions{}, "scope-resource-show", "query backend service for its scope resource count", func(s *mcclient.ClientSession, args *ScopeResourceOptions) error {
body, err := modules.GetScopeResources(s, args.SERVICE)
if err != nil {
return err
}

23
cmd/cloudid/main.go Normal file
View File

@@ -0,0 +1,23 @@
// 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 main
import (
"yunion.io/x/onecloud/pkg/cloudid/service"
)
func main() {
service.StartService()
}

6
go.mod
View File

@@ -108,19 +108,23 @@ require (
go.etcd.io/etcd v0.5.0-alpha.5.0.20191023171146-3cf2f69b5738
go.uber.org/atomic v1.4.0 // indirect
golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8
golang.org/x/tools v0.0.0-20200515220128-d3bf790afa53 // indirect
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20191008142428-8d021180e987
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb
google.golang.org/grpc v1.26.0
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/fatih/set.v0 v0.2.1
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.44.0 // indirect
gopkg.in/ldap.v3 v3.0.3
gopkg.in/yaml.v2 v2.2.8
honnef.co/go/tools v0.0.1-2020.1.4 // indirect
k8s.io/api v0.17.3
k8s.io/apimachinery v0.17.3
k8s.io/client-go v9.0.0+incompatible

15
go.sum
View File

@@ -769,6 +769,7 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yunionio/go-ceph v0.0.0-20190912101231-6f05a06b3859 h1:wu596gn6sV3j5wy+GDfiG8nwtzIDpalJihfmC/TjoYc=
github.com/yunionio/go-ceph v0.0.0-20190912101231-6f05a06b3859/go.mod h1:8XuBae5AzsgotLArJSewMruYVaQs8AlfsK5jBCG8T9Y=
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
@@ -836,6 +837,8 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180524181706-dfa909b99c79/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -869,6 +872,8 @@ golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -952,10 +957,14 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4 h1:Toz2IK7k8rbltAXwNAxKcn9OzqyNfMUhUNjz3sL0NMk=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200515220128-d3bf790afa53 h1:vmsb6v0zUdmUlXfwKaYrHPPRCV0lHq/IwNIf0ASGjyQ=
golang.org/x/tools v0.0.0-20200515220128-d3bf790afa53/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
@@ -1013,8 +1022,12 @@ gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUy
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fatih/set.v0 v0.2.1 h1:Xvyyp7LXu34P0ROhCyfXkmQCAoOUKb1E2JS9I7SE5CY=
gopkg.in/fatih/set.v0 v0.2.1/go.mod h1:5eLWEndGL4zGGemXWrKuts+wTJR0y+w+auqUJZbmyBg=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
@@ -1054,6 +1067,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.2/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.0.0-20190918155943-95b840bb6a1f h1:8FRUST8oUkEI45WYKyD8ed7Ad0Kg5v11zHyPkEVb2xo=
k8s.io/api v0.0.0-20190918155943-95b840bb6a1f/go.mod h1:uWuOHnjmNrtQomJrvEBg0c0HRNyQ+8KTEERVsK0PW48=
k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783/go.mod h1:xvae1SZB3E17UpV59AWc271W/Ph25N+bjPyR63X6tPY=

View File

@@ -14,8 +14,10 @@
package cloudevent
import "yunion.io/x/onecloud/pkg/apis"
const (
SERVICE_TYPE = "cloudevent"
SERVICE_TYPE = apis.SERVICE_TYPE_CLOUDEVENT
CLOUD_EVENT_SERVICE_COMPUTE = "compute"
CLOUD_EVENT_SERVICE_UNKNOWN = "unknown"

View File

@@ -0,0 +1,51 @@
// 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 cloudid
type CloudaccountResourceListInput struct {
// 根据云账号名称过滤资源
Cloudaccount string `json:"cloudaccount"`
// 根据平台过滤
Provider []string `json:"provider"`
// swagger:ignore
CloudaccountId string `json:"cloudaccount_id" "yunion:deprecated-by":"cloudaccount"`
}
type CloudproviderResourceListInput struct {
// 根据云订阅过滤资源
Cloudprovider string `json:"cloudprovider"`
// swagger:ignore
CloudproviderId string `json:"cloudprovider_id" "yunion:deprecated-by":"cloudprovider"`
}
type CloudaccountResourceDetails struct {
// 云账号名称
Cloudaccount string `json:"cloudaccount"`
// 平台信息
Provider string `json:"provider"`
// 品牌信息
Brand string `json:"brand"`
// 公有云账号登录地址
IamLoginUrl string `json:"iam_login_url"`
}
type CloudproviderResourceDetails struct {
// 云订阅名称
Cloudprovider string `json:"cloudprovider"`
}

View File

@@ -0,0 +1,214 @@
// 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 cloudid
import "yunion.io/x/onecloud/pkg/apis"
const (
CLOUD_GROUP_STATUS_AVAILABLE = "available" // 可用
CLOUD_GROUP_STATUS_DELETING = "deleting" // 删除中
CLOUD_GROUP_STATUS_DELETE_FAILED = "delete_failed" // 删除失败
CLOUD_GROUP_STATUS_SYNC_POLICIES = "sync_policies" // 同步权限中
CLOUD_GROUP_STATUS_SYNC_USERS = "sync_users" // 同步用户中
)
type CloudgroupJointResourceDetails struct {
apis.JointResourceBaseDetails
// 公有云用户组名称
Cloudgroup string `json:"cloudgroup"`
}
type CloudgroupJointsListInput struct {
apis.JointResourceBaseListInput
// 根据公有云用户组过滤资源
Cloudgroup string `json:"cloudgroup"`
// swagger:ignore
CloudgroupId string `json:"cloudgroup_id" "yunion:deprecated-by":"cloudgroup"`
}
type CloudgroupJointBaseUpdateInput struct {
apis.JointResourceBaseUpdateInput
}
type CloudgroupUserDetails struct {
CloudgroupJointResourceDetails
SCloudgroup
ClouduserResourceDetails
}
type CloudgroupUserListInput struct {
CloudgroupJointsListInput
ClouduserResourceListInput
}
type CloudgroupPolicyDetails struct {
CloudgroupJointResourceDetails
CloudpolicyResourceDetails
}
type CloudgroupPolicyListInput struct {
CloudgroupJointsListInput
CloudpolicyResourceListInput
}
type CloudgroupListInput struct {
apis.StatusInfrasResourceBaseListInput
// 根据平台过滤
Provider []string `json:"provider"`
// 过滤子账号所在的权限组
ClouduserId string `json:"clouduser_id"`
// 根据权限过滤权限组
CloudpolicyId string `json:"cloudpolicy_id"`
}
type SCloudIdBaseResource struct {
Id string `json:"id"`
Name string `json:"name"`
}
type CloudgroupDetails struct {
apis.StatusInfrasResourceBaseDetails
SCloudgroup
// 公有云子用户数量
ClouduserCount int `json:"clouduser_count"`
// 权限数量
CloudpolicyCount int `json:"cloudpolicy_count"`
// 公有云权限组缓存数量
CloudgroupcacheCount int `json:"cloudgroupcache_count"`
Cloudpolicies []SCloudIdBaseResource `json:"cloudpolicies"`
Cloudusers []SCloudIdBaseResource `json:"cloudusers"`
}
type CloudgroupCreateInput struct {
apis.StatusInfrasResourceBaseCreateInput
// 平台
//
// | 云平台 | 说明 |
// |----------|---------------------------------------------|
// | Google | 支持 |
// | Aliyun | 支持 |
// | Huawei | 支持 |
// | Azure | 支持 |
// | Qcloud | 支持 |
Provider string `json:"provider"`
// 权限Id列表, 权限provider必须和权限组provider一致
CloudpolicyIds []string `json:"cloudpolicy_ids"`
}
type CloudgroupAddUserInput struct {
// 用户Id
//
// | 云平台 | 说明 |
// |----------|---------------------------------------------|
// | Google | 不支持 |
// | Aliyun | 支持 |
// | Huawei | 支持 |
// | Azure | 支持 |
// | 腾讯云 | 支持 |
ClouduserId string `json:"clouduser_id"`
}
type CloudgroupRemoveUserInput struct {
// 用户Id
//
// | 云平台 | 说明 |
// |----------|---------------------------------------------|
// | Google | 不支持 |
// | Aliyun | 支持 |
// | Huawei | 支持 |
// | Azure | 支持 |
// | 腾讯云 | 支持 |
ClouduserId string `json:"clouduser_id"`
}
type CloudgroupAttachPolicyInput struct {
// 权限Id
//
// | 云平台 | 说明 |
// |----------|---------------------------------------------|
// | Google | 不支持 |
// | Aliyun | 支持 |
// | Huawei | 支持 |
// | Azure | 不支持 |
// | 腾讯云 | 支持 |
CloudpolicyId string `json:"cloudpolicy_id"`
}
type CloudgroupSetUsersInput struct {
// 公有云子账号Ids
//
// | 云平台 | 说明 |
// |----------|---------------------------------------------|
// | Google | 支持 |
// | Aliyun | 支持 |
// | Huawei | 支持 |
// | Azure | 支持 |
// | 腾讯云 | 支持 |
ClouduserIds []string `json:"clouduser_ids"`
}
type CloudgroupSetPoliciesInput struct {
// 权限Ids
//
// | 云平台 | 说明 |
// |----------|---------------------------------------------|
// | Google | 支持 |
// | Aliyun | 支持 |
// | Huawei | 支持 |
// | Azure | 不支持 |
// | 腾讯云 | 支持 |
CloudpolicyIds []string `json:"cloudpolicy_ids"`
}
type CloudgroupDetachPolicyInput struct {
// 权限Id
//
// | 云平台 | 说明 |
// |----------|---------------------------------------------|
// | Google | 不支持 |
// | Aliyun | 支持 |
// | Huawei | 支持 |
// | Azure | 不支持 |
// | 腾讯云 | 支持 |
CloudpolicyId string `json:"cloudpolicy_id"`
}
type CloudgroupSyncstatusInput struct {
}
type CloudgroupSyncInput struct {
}
type CloudgroupUpdateInput struct {
}

View File

@@ -0,0 +1,47 @@
// 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 cloudid
import "yunion.io/x/onecloud/pkg/apis"
const (
CLOUD_GROUP_CACHE_STATUS_CREATING = "creating" // 创建中
CLOUD_GROUP_CACHE_STATUS_CREATE_FAILED = "create_failed" // 创建失败
CLOUD_GROUP_CACHE_STATUS_DELETING = "deleting" // 删除中
CLOUD_GROUP_CACHE_STATUS_DELETE_FAILED = "delete_failed" // 删除失败
CLOUD_GROUP_CACHE_STATUS_SYNC_STATUS = "sync_status" // 同步状态中
CLOUD_GROUP_CACHE_STATUS_UNKNOWN = "unknown" // 未知
)
type CloudgroupcacheListInput struct {
apis.StatusStandaloneResourceListInput
CloudaccountResourceListInput
// 根据权限组过滤
CloudgroupId string `json:"cloudgroup_id"`
}
type CloudgroupcacheCreateInput struct {
}
type CloudgroupcacheSyncstatusInput struct {
}
type CloudgroupcacheDetails struct {
apis.StatusStandaloneResourceDetails
SCloudgroupcache
CloudaccountResourceDetails
}

View File

@@ -0,0 +1,80 @@
// 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 cloudid
import "yunion.io/x/onecloud/pkg/apis"
const (
CLOUD_POLICY_STATUS_AVAILABLE = "available"
CLOUD_POLICY_TYPE_SYSTEM = "system"
CLOUD_POLICY_TYPE_CUSTOM = "custom"
)
type CloudpolicyListInput struct {
apis.StatusStandaloneResourceListInput
// 根据平台过滤
Provider []string `json:"provider"`
// 根据子账号过滤权限
ClouduserId string `json:"clouduser_id"`
// 根据权限组过滤权限
CloudgroupId string `json:"cloudgroup_id"`
}
type CloudpolicyDetails struct {
apis.StatusStandaloneResourceDetails
SCloudpolicy
}
type CloudpolicyCreateInput struct {
apis.StatusStandaloneResourceCreateInput
// 云账号Id
CloudaccountId string `json:"cloudaccount_id"`
// 权限类型
PolicyType string `json:"policy_type"`
}
type CloudpolicyResourceListInput struct {
// 根据公有云权限过滤资源
Cloudpolicy string `json:"cloudpolicy"`
// swagger:ignore
CloudpolicyId string `json:"cloudpolicy_id" "yunion:deprecated-by":"cloudpolicy"`
}
type CloudpolicyResourceDetails struct {
// 公有云权限名称
Cloudpolicy string `json:"cloudpolicy"`
}
type CloudpolicyUpdateInput struct {
}
type CloudpolicyAssignGroupInput struct {
// 权限组Id
CloudgroupId string `json:"cloudgroup_id"`
}
type CloudpolicyRevokeGroupInput struct {
// 权限组Id
CloudgroupId string `json:"cloudgroup_id"`
}

View File

@@ -0,0 +1,254 @@
// 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 cloudid
import "yunion.io/x/onecloud/pkg/apis"
const (
CLOUD_USER_STATUS_CREATING = "creating" // 创建中
CLOUD_USER_STATUS_CREATE_FAILED = "create_failed" //创建失败
CLOUD_USER_STATUS_AVAILABLE = "available" // 可用
CLOUD_USER_STATUS_UNKNOWN = "unknown" // 未知
CLOUD_USER_STATUS_DELETING = "deleting" // 删除中
CLOUD_USER_STATUS_DELETE_FAILED = "delete_failed" // 删除失败
CLOUD_USER_STATUS_SYNC_STATUS = "sync_status" // 同步状态中
CLOUD_USER_STATUS_SYNC = "sync" // 同步配置中
CLOUD_USER_STATUS_SYNC_FAILED = "sync_failed" // 同步配置失败
CLOUD_USER_STATUS_SYNC_POLICIES = "sync_policies" // 同步权限中
CLOUD_USER_STATUS_SYNC_POLICIES_FAILED = "sync_policies_failed" // 同步权限失败
CLOUD_USER_STATUS_SYNC_GROUPS = "sync_groups" // 同步权限组中
CLOUD_USER_STATUS_SYNC_GROUPS_FAILED = "sync_groups_failed" // 同步权限组失败
CLOUD_USER_STATUS_RESET_PASSWORD = "reset_password" // 重置密码中
CLOUD_USER_STATUS_RESET_PASSWORD_FAILED = "reset_password_failed" // 重置密码失败
)
type ClouduserCreateInput struct {
apis.StatusUserResourceCreateInput
apis.StatusBaseResourceCreateInput
// 云订阅ID
//
// | 云平台 | 说明 |
// |----------|---------------------------------------------|
// | Google | 必填 |
// | Aliyun | 为空 |
// | Huawei | 为空 |
// | Azure | 为空 |
// | 腾讯云 | 为空 |
CloudproviderId string `json:"cloudprovider_id"`
// 云账号ID
// Azure云账号需要有User administrator权限否则删操作会出现Insufficient privileges to complete the operation错误信息
//
// | 云平台 | 说明 |
// |----------|---------------------------------------------|
// | Google | 为空 |
// | Aliyun | 必填 |
// | Huawei | 必填 |
// | Azure | 必填 |
// | 腾讯云 | 必填 |
CloudaccountId string `json:"cloudaccount_id"`
// 用户密码, 若is_console_login = true时, 此参数不传时会生成12位随机密码
//
// | 云平台 | 说明 |
// |----------|---------------------------------------------|
// | Google | 不支持此参数 |
// | Aliyun | 支持 |
// | Huawei | 支持 |
// | Azure | 支持 |
// | 腾讯云 | 支持 |
Password string `json:"password"`
// 是否可控制台登录
// default: false
IsConsoleLogin *bool `json:"is_console_login"`
// 邮箱地址
// example: test@example.com
Email string `json:"email"`
// 手机号码
// example: 86-1868888****
MobilePhone string `json:"mobile_phone"`
// 初始的权限Id列表, 权限必须属于指定的云账号
//
// | 云平台 | 说明 |
// |----------|---------------------------------------------|
// | Google | 至少需要一个初始权限 |
// | Aliyun | 支持 |
// | Huawei | 不支持 |
// | Azure | 不支持 |
// | 腾讯云 | 支持 |
CloudpolicyIds []string `json:"cloudpolicy_ids"`
// 初始化权限组Id列表, 权限组必须和云账号平台属性相同
CloudgroupIds []string `json:"cloudgroup_ids"`
// swagger:ignore
ExternalId string `json:"external_id"`
}
type ClouduserListInput struct {
apis.StatusUserResourceListInput
CloudaccountResourceListInput
CloudproviderResourceListInput
// 过滤绑定权限的子账号
CloudpolicyId string `json:"cloudpolicy_id"`
// 过滤属于指定权限组的子账号
CloudgroupId string `json:"cloudgroup_id"`
}
type ClouduserDetails struct {
apis.StatusUserResourceDetails
SClouduser
CloudaccountResourceDetails
CloudproviderResourceDetails
// 权限数量
CloudpolicyCount int `json:"cloudpolicy_count"`
// 权限组数量
CloudgroupCount int `json:"cloudgroup_count"`
Cloudgroups []SCloudIdBaseResource `json:"cloudgroups"`
Cloudpolicies []SCloudIdBaseResource `json:"cloudpolicies"`
}
type ClouduserJointResourceDetails struct {
apis.JointResourceBaseDetails
ClouduserResourceDetails
}
type ClouduserJointsListInput struct {
apis.JointResourceBaseListInput
ClouduserResourceListInput
}
type ClouduserJointBaseUpdateInput struct {
apis.JointResourceBaseUpdateInput
}
type ClouduserPolicyDetails struct {
ClouduserJointResourceDetails
CloudpolicyResourceDetails
}
type ClouduserPolicyListInput struct {
ClouduserJointsListInput
CloudpolicyResourceListInput
}
type ClouduserResourceListInput struct {
// 根据公有云用户过滤资源
Clouduser string `json:"clouduser"`
// swagger:ignore
ClouduserId string `json:"clouduser_id" "yunion:deprecated-by":"clouduser"`
}
type ClouduserResourceDetails struct {
// 公有云用户名称
Clouduser string `json:"clouduser"`
// 云账号名称
Cloudaccount string `json:"cloudaccount"`
// 云订阅名称
Cloudprovider string `json:"cloudprovider"`
}
type ClouduserAttachPolicyInput struct {
// 权限Id
//
// | 云平台 | 说明 |
// |----------|---------------------------------------------|
// | Google | 支持 |
// | Aliyun | 支持 |
// | Huawei | 不支持 |
// | Azure | 不支持 |
// | 腾讯云 | 支持 |
CloudpolicyId string `json:"cloudpolicy_id"`
}
type ClouduserSetPoliciesInput struct {
// 权限Ids
CloudpolicyIds []string `json:"cloudpolicy_ids"`
}
type ClouduserSetGroupsInput struct {
// 权限组Ids
CloudgroupIds []string `json:"cloudgroup_ids"`
}
type ClouduserJoinGroupInput struct {
// 权限组Id
CloudgroupId string `json:"cloudgroup_id"`
}
type ClouduserLeaveGroupInput struct {
// 权限组Id
CloudgroupId string `json:"cloudgroup_id"`
}
type ClouduserDetachPolicyInput struct {
// 权限Id
//
// | 云平台 | 说明 |
// |----------|---------------------------------------------|
// | Google | 支持,但最少需要保留一个权限 |
// | Aliyun | 支持 |
// | Huawei | 不支持 |
// | Azure | 不支持 |
// | 腾讯云 | 支持 |
CloudpolicyId string `json:"cloudpolicy_id"`
}
type ClouduserSyncstatusInput struct {
}
type ClouduserSyncInput struct {
}
type ClouduserUpdateInput struct {
}
type ClouduserResetPasswordInput struct {
// 若此参数为空, 默认会生成随机12位密码
//
// | 云平台 | 说明 |
// |----------|---------------------------------------------|
// | Google | 不支持 |
// | Aliyun | 支持 |
// | Huawei | 支持 |
// | Azure | 支持 |
// | 腾讯云 | 支持 |
Password string `json:"password"`
}
type ClouduserChangeOwnerInput struct {
// 本地用户Id
UserId string `json:"user_id"`
}

1
pkg/apis/cloudid/doc.go Normal file
View File

@@ -0,0 +1 @@
package cloudid // import "yunion.io/x/onecloud/pkg/apis/cloudid"

View File

@@ -0,0 +1,134 @@
// 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.
// Code generated by model-api-gen. DO NOT EDIT.
package cloudid
import (
"yunion.io/x/onecloud/pkg/apis"
)
// SCloudaccount is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SCloudaccount.
type SCloudaccount struct {
apis.SStandaloneResourceBase
apis.SDomainizedResourceBase
Provider string `json:"provider"`
Brand string `json:"brand"`
IamLoginUrl string `json:"iam_login_url"`
IsSupportCloudId *bool `json:"is_support_cloud_id,omitempty"`
}
// SCloudaccountResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SCloudaccountResourceBase.
type SCloudaccountResourceBase struct {
// 云账号Id
CloudaccountId string `json:"cloudaccount_id"`
}
// SCloudgroup is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SCloudgroup.
type SCloudgroup struct {
apis.SStatusInfrasResourceBase
Provider string `json:"provider"`
}
// SCloudgroupJointsBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SCloudgroupJointsBase.
type SCloudgroupJointsBase struct {
apis.SJointResourceBase
// 用户组Id
CloudgroupId string `json:"cloudgroup_id"`
}
// SCloudgroupPolicy is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SCloudgroupPolicy.
type SCloudgroupPolicy struct {
SCloudgroupJointsBase
SCloudpolicyResourceBase
}
// SCloudgroupUser is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SCloudgroupUser.
type SCloudgroupUser struct {
SCloudgroupJointsBase
SClouduserResourceBase
}
// SCloudgroupcache is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SCloudgroupcache.
type SCloudgroupcache struct {
apis.SStatusStandaloneResourceBase
apis.SExternalizedResourceBase
SCloudaccountResourceBase
// 用户组Id
CloudgroupId string `json:"cloudgroup_id"`
}
// SCloudpolicy is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SCloudpolicy.
type SCloudpolicy struct {
apis.SStatusStandaloneResourceBase
apis.SExternalizedResourceBase
// 权限类型
// | 权限类型 | 说明 |
// |---------------|----------------------|
// | system | 平台内置权限 |
// | custom | 目前不支持 |
PolicyType string `json:"policy_type"`
// 平台
Provider string `json:"provider"`
}
// SCloudpolicyResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SCloudpolicyResourceBase.
type SCloudpolicyResourceBase struct {
// 权限Id
CloudpolicyId string `json:"cloudpolicy_id"`
}
// SCloudprovider is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SCloudprovider.
type SCloudprovider struct {
apis.SStandaloneResourceBase
Provider string `json:"provider"`
CloudaccountId string `json:"cloudaccount_id"`
}
// SCloudproviderResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SCloudproviderResourceBase.
type SCloudproviderResourceBase struct {
// 子订阅Id
CloudproviderId string `json:"cloudprovider_id"`
}
// SClouduser is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SClouduser.
type SClouduser struct {
apis.SStatusUserResourceBase
apis.SExternalizedResourceBase
SCloudproviderResourceBase
SCloudaccountResourceBase
Secret string `json:"secret"`
// 是否可以控制台登录
IsConsoleLogin *bool `json:"is_console_login,omitempty"`
// 手机号码
MobilePhone string `json:"mobile_phone"`
// 邮箱地址
Email string `json:"email"`
}
// SClouduserJointsBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SClouduserJointsBase.
type SClouduserJointsBase struct {
apis.SJointResourceBase
SClouduserResourceBase
}
// SClouduserPolicy is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SClouduserPolicy.
type SClouduserPolicy struct {
SClouduserJointsBase
SCloudpolicyResourceBase
}
// SClouduserResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudid/models.SClouduserResourceBase.
type SClouduserResourceBase struct {
ClouduserId string `json:"clouduser_id"`
}

View File

@@ -14,7 +14,9 @@
package compute
import "yunion.io/x/onecloud/pkg/apis"
const (
SERVICE_TYPE = "compute"
SERVICE_TYPE = apis.SERVICE_TYPE_REGION
SERVICE_VERSION = "v2"
)

View File

@@ -37,13 +37,8 @@ type DeletePreventableCreateInput struct {
}
type KeypairListInput struct {
apis.StandaloneResourceListInput
apis.UserResourceListInput
// list in admin mode
Admin *bool `json:"admin"`
// 加密类型
// example: RSA
Scheme []string `json:"scheme"`

View File

@@ -21,7 +21,7 @@ var KEYPAIR_SCHEMAS = []string{
}
type KeypairCreateInput struct {
apis.StandaloneResourceCreateInput
apis.UserResourceCreateInput
// 公钥内容,若为空则自动生成公钥
PublicKey string `json:"public_key"`
@@ -32,9 +32,6 @@ type KeypairCreateInput struct {
// swagger:ignore
Fingerprint string
// swagger:ignore
OwnerId string
// 秘钥类型
// enum: RSA
// default: RSA
@@ -42,14 +39,11 @@ type KeypairCreateInput struct {
}
type KeypairDetails struct {
apis.StandaloneResourceDetails
apis.UserResourceDetails
SKeypair
// 私钥长度
PrivateKeyLen int `json:"private_key_len"`
// 关联云主机次数
LinkedGuestCount int `json:"linked_guest_count"`
// 用户名称
OwnerName string `json:"owner_name"`
}

View File

@@ -200,6 +200,10 @@ type SCloudaccount struct {
ShareMode string `json:"share_mode"`
// 默认值proxyapi.ProxySettingId_DIRECT
ProxySettingId string `json:"proxy_setting_id"`
// 公有云子账号登录地址
IamLoginUrl string `json:"iam_login_url"`
// 是否支持创建公有云子账号
IsSupportCloudId *bool `json:"is_support_cloud_id,omitempty"`
}
// SCloudprovider is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SCloudprovider.
@@ -865,20 +869,6 @@ type SGuestTemplateResourceBase struct {
GuestTemplateId string `json:"guest_template_id"`
}
// SGuestcdrom is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SGuestcdrom.
type SGuestcdrom struct {
Id string `json:"id"`
// = Column(VARCHAR(36, charset='ascii'), primary_key=True)
ImageId string `json:"image_id"`
// Column(VARCHAR(36, charset='ascii'), nullable=True)
Name string `json:"name"`
// Column(VARCHAR(64, charset='ascii'), nullable=True)
Path string `json:"path"`
// Column(VARCHAR(256, charset='ascii'), nullable=True)
Size int `json:"size"`
UpdateVersion int `json:"update_version"`
}
// SGuestdisk is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SGuestdisk.
type SGuestdisk struct {
SGuestJointsBase
@@ -998,10 +988,11 @@ type SHost struct {
OvnVersion string `json:"ovn_version"`
IsBaremetal bool `json:"is_baremetal"`
// 是否处于维护状态
IsMaintenance bool `json:"is_maintenance"`
EnableHealthCheck bool `json:"enable_health_check"`
ResourceType string `json:"resource_type"`
RealExternalId string `json:"real_external_id"`
IsMaintenance bool `json:"is_maintenance"`
LastPingAt time.Time `json:"last_ping_at"`
EnableHealthCheck bool `json:"enable_health_check"`
ResourceType string `json:"resource_type"`
RealExternalId string `json:"real_external_id"`
// 是否为导入的宿主机
IsImport bool `json:"is_import"`
// 是否允许PXE启动
@@ -1157,7 +1148,7 @@ type SIsolatedDevice struct {
// SKeypair is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SKeypair.
type SKeypair struct {
apis.SStandaloneResourceBase
apis.SUserResourceBase
// 加密类型
// example: RSA
Scheme string `json:"scheme"`
@@ -1168,8 +1159,6 @@ type SKeypair struct {
PrivateKey string `json:"private_key"`
// 公钥
PublicKey string `json:"public_key"`
// 用户Id
OwnerId string `json:"owner_id"`
}
// SLoadbalancer is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SLoadbalancer.
@@ -1258,9 +1247,12 @@ type SLoadbalancerAgentDeployment struct {
// SLoadbalancerAgentParams is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SLoadbalancerAgentParams.
type SLoadbalancerAgentParams struct {
KeepalivedConfTmpl string `json:"keepalived_conf_tmpl"`
HaproxyConfTmpl string `json:"haproxy_conf_tmpl"`
TelegrafConfTmpl string `json:"telegraf_conf_tmpl"`
KeepalivedConfTmpl string `json:"keepalived_conf_tmpl"`
HaproxyConfTmpl string `json:"haproxy_conf_tmpl"`
TelegrafConfTmpl string `json:"telegraf_conf_tmpl"`
Vrrp SLoadbalancerAgentParamsVrrp `json:"vrrp"`
Haproxy SLoadbalancerAgentParamsHaproxy `json:"haproxy"`
Telegraf SLoadbalancerAgentParamsTelegraf `json:"telegraf"`
}
// SLoadbalancerAgentParamsHaproxy is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SLoadbalancerAgentParamsHaproxy.
@@ -1502,16 +1494,6 @@ type SManagedResourceBase struct {
ManagerId string `json:"manager_id"`
}
// SNatDEntry is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SNatDEntry.
type SNatDEntry struct {
SNatEntry
ExternalIP string `json:"external_ip"`
ExternalPort int `json:"external_port"`
InternalIP string `json:"internal_ip"`
InternalPort int `json:"internal_port"`
IpProtocol string `json:"ip_protocol"`
}
// SNatEntry is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SNatEntry.
type SNatEntry struct {
apis.SStatusInfrasResourceBase
@@ -1542,25 +1524,6 @@ type SNatgatewayResourceBase struct {
NatgatewayId string `json:"natgateway_id"`
}
// SNetInterface is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SNetInterface.
type SNetInterface struct {
Mac string `json:"mac"`
// Column(VARCHAR(36, charset='ascii'), primary_key=True)
BaremetalId string `json:"baremetal_id"`
// Column(VARCHAR(36, charset='ascii'), nullable=True)
WireId string `json:"wire_id"`
// Column(VARCHAR(36, charset='ascii'), nullable=True)
Rate int `json:"rate"`
// Column(Integer, nullable=True) # Mbps
NicType string `json:"nic_type"`
// Column(VARCHAR(36, charset='ascii'), nullable=True)
Index byte `json:"index"`
// Column(TINYINT, nullable=True)
LinkUp bool `json:"link_up"`
// Column(Boolean, nullable=True)
Mtu int16 `json:"mtu"`
}
// SNetwork is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SNetwork.
type SNetwork struct {
apis.SSharableVirtualResourceBase
@@ -1735,6 +1698,8 @@ type SScalingAlarm struct {
Value float64 `json:"value"`
// Real-time cumulate number
RealCumulate int `json:"real_cumulate"`
// Last trigger time
LastTriggerTime time.Time `json:"last_trigger_time"`
}
// SScalingGroup is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SScalingGroup.
@@ -1765,6 +1730,10 @@ type SScalingGroup struct {
HealthCheckGov int `json:"health_check_gov"`
LoadbalancerBackendPort int `json:"loadbalancer_backend_port"`
LoadbalancerBackendWeight int `json:"loadbalancer_backend_weight"`
// Time to allow scale
AllowScaleTime time.Time `json:"allow_scale_time"`
// NextCheckTime descripe the next time to check instance's health
NextCheckTime time.Time `json:"next_check_time"`
}
// SScalingGroupGuest is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SScalingGroupGuest.
@@ -1852,6 +1821,7 @@ type SScheduledTask struct {
apis.SEnabledResourceBase
ScheduledType string `json:"scheduled_type"`
STimer
TimerDesc string `json:"timer_desc"`
ResourceType string `json:"resource_type"`
Operation string `json:"operation"`
LabelType string `json:"label_type"`

40
pkg/apis/const.go Normal file
View File

@@ -0,0 +1,40 @@
// 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 apis
const (
SERVICE_TYPE_IMAGE = "image"
SERVICE_TYPE_OFFLINE_CLOUDMETA = "offlinecloudmeta"
SERVICE_TYPE_CLOUDID = "cloudid"
SERVICE_TYPE_CLOUDEVENT = "cloudevent"
SERVICE_TYPE_DEVTOOL = "devtool"
SERVICE_TYPE_ANSIBLE = "ansible"
SERVICE_TYPE_CLOUDMETA = "cloudmeta"
SERVICE_TYPE_WEBSOCKET = "websocket"
SERVICE_TYPE_AUTOUPDATE = "autoupdate"
SERVICE_TYPE_YUNIONCONF = "yunionconf"
SERVICE_TYPE_YUNIONAGENT = "yunionagent"
SERVICE_TYPE_METER = "meter"
SERVICE_TYPE_SCHEDULER = "scheduler"
SERVICE_TYPE_ITSM = "itsm"
SERVICE_TYPE_VNCPROXY = "vncproxy"
SERVICE_TYPE_KEYSTONE = "identity"
SERVICE_TYPE_NOTIFY = "notify"
SERVICE_TYPE_CLOUDWATCHER = "cloudwatcher"
SERVICE_TYPE_MONITOR = "monitor"
SERVICE_TYPE_SERVICETREE = "servicetree"
SERVICE_TYPE_LOG = "log"
SERVICE_TYPE_REGION = "compute"
)

View File

@@ -14,8 +14,10 @@
package identity
import "yunion.io/x/onecloud/pkg/apis"
const (
SERVICE_TYPE = "identity"
SERVICE_TYPE = apis.SERVICE_TYPE_KEYSTONE
DEFAULT_DOMAIN_ID = "default"
DEFAULT_DOMAIN_NAME = "Default"

View File

@@ -30,4 +30,6 @@ type UserDetails struct {
FailedAuthCount int `json:"failed_auth_count"`
FailedAuthAt time.Time `json:"failed_auth_at"`
PasswordExpiresAt time.Time `json:"password_expires_at"`
ExternalResourceInfo
}

View File

@@ -92,20 +92,6 @@ type SFederatedUser struct {
DisplayName string `json:"display_name"`
}
// SFederationProtocol is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SFederationProtocol.
type SFederationProtocol struct {
Id string `json:"id"`
IdpId string `json:"idp_id"`
MappingId string `json:"mapping_id"`
}
// SFernetKey is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SFernetKey.
type SFernetKey struct {
Type string `json:"type"`
Index int `json:"index"`
Key string `json:"key"`
}
// SGroup is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SGroup.
type SGroup struct {
SIdentityBaseResource
@@ -143,45 +129,28 @@ type SIdmapping struct {
EntityType string `json:"entity_type"`
}
// SIdpRemoteIds is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SIdpRemoteIds.
type SIdpRemoteIds struct {
IdpId string `json:"idp_id"`
RemoteId string `json:"remote_id"`
}
// SImpliedRole is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SImpliedRole.
type SImpliedRole struct {
PriorRoleId string `json:"prior_role_id"`
ImpliedRoleId string `json:"implied_role_id"`
}
// SLocalUser is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SLocalUser.
type SLocalUser struct {
apis.SResourceBase
Id int `json:"id"`
UserId string `json:"user_id"`
DomainId string `json:"domain_id"`
Name string `json:"name"`
FailedAuthCount int `json:"failed_auth_count"`
}
// SNonlocalUser is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SNonlocalUser.
type SNonlocalUser struct {
DomainId string `json:"domain_id"`
Name string `json:"name"`
UserId string `json:"user_id"`
Id int `json:"id"`
UserId string `json:"user_id"`
DomainId string `json:"domain_id"`
Name string `json:"name"`
FailedAuthCount int `json:"failed_auth_count"`
FailedAuthAt time.Time `json:"failed_auth_at"`
}
// SPassword is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SPassword.
type SPassword struct {
apis.SResourceBase
Id int `json:"id"`
LocalUserId int `json:"local_user_id"`
Password string `json:"password"`
SelfService bool `json:"self_service"`
PasswordHash string `json:"password_hash"`
CreatedAtInt int64 `json:"created_at_int"`
ExpiresAtInt int64 `json:"expires_at_int"`
Id int `json:"id"`
LocalUserId int `json:"local_user_id"`
Password string `json:"password"`
ExpiresAt time.Time `json:"expires_at"`
SelfService bool `json:"self_service"`
PasswordHash string `json:"password_hash"`
CreatedAtInt int64 `json:"created_at_int"`
ExpiresAtInt int64 `json:"expires_at_int"`
}
// SPolicy is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SPolicy.
@@ -199,21 +168,6 @@ type SProject struct {
IsDomain *bool `json:"is_domain,omitempty"`
}
// SProjectExtended is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SProjectExtended.
type SProjectExtended struct {
SProject
DomainName string `json:"domain_name"`
}
// SProjectResource is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SProjectResource.
type SProjectResource struct {
ProjectId string `json:"project_id"`
RegionId string `json:"region_id"`
ServiceId string `json:"service_id"`
Resource string `json:"resource"`
Count int `json:"count"`
}
// SRegion is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SRegion.
type SRegion struct {
apis.SStandaloneResourceBase
@@ -259,13 +213,6 @@ type SUser struct {
EnableMfa *bool `json:"enable_mfa,omitempty"`
}
// SUserOption is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SUserOption.
type SUserOption struct {
UserId string `json:"user_id"`
OptionId string `json:"option_id"`
OptionValue string `json:"option_value"`
}
// SUsergroupMembership is an autogenerated struct via yunion.io/x/onecloud/pkg/keystone/models.SUsergroupMembership.
type SUsergroupMembership struct {
apis.SResourceBase

View File

@@ -14,10 +14,12 @@
package image
import "yunion.io/x/onecloud/pkg/apis"
type TImageType string
const (
SERVICE_TYPE = "image"
SERVICE_TYPE = apis.SERVICE_TYPE_IMAGE
SERVICE_VERSION = ""
// https://docs.openstack.org/glance/pike/user/statuses.html

View File

@@ -62,44 +62,9 @@ type SImage struct {
OssChecksum string `json:"oss_checksum"`
}
// SImageMember is an autogenerated struct via yunion.io/x/onecloud/pkg/image/models.SImageMember.
type SImageMember struct {
SImagePeripheral
Member string `json:"member"`
CanShare bool `json:"can_share"`
}
// SImagePeripheral is an autogenerated struct via yunion.io/x/onecloud/pkg/image/models.SImagePeripheral.
type SImagePeripheral struct {
apis.SResourceBase
Id int `json:"id"`
ImageId string `json:"image_id"`
}
// SImageProperty is an autogenerated struct via yunion.io/x/onecloud/pkg/image/models.SImageProperty.
type SImageProperty struct {
SImagePeripheral
Name string `json:"name"`
Value string `json:"value"`
}
// SImageSubformat is an autogenerated struct via yunion.io/x/onecloud/pkg/image/models.SImageSubformat.
type SImageSubformat struct {
SImagePeripheral
Format string `json:"format"`
Size int64 `json:"size"`
Location string `json:"location"`
Checksum string `json:"checksum"`
FastHash string `json:"fast_hash"`
Status string `json:"status"`
TorrentSize int64 `json:"torrent_size"`
TorrentLocation string `json:"torrent_location"`
TorrentChecksum string `json:"torrent_checksum"`
TorrentStatus string `json:"torrent_status"`
}
// SImageTag is an autogenerated struct via yunion.io/x/onecloud/pkg/image/models.SImageTag.
type SImageTag struct {
SImagePeripheral
Value string `json:"value"`
}

View File

@@ -75,6 +75,18 @@ type SharableVirtualResourceCreateInput struct {
SharableResourceBaseCreateInput
}
type StatusUserResourceCreateInput struct {
StatusBaseResourceCreateInput
UserResourceCreateInput
}
type UserResourceCreateInput struct {
StandaloneResourceCreateInput
// 本地用户Id若为空则使用当前用户Id作为此参数值
OwnerId string `json:"owner_id"`
}
type VirtualResourceCreateInput struct {
StatusStandaloneResourceCreateInput
ProjectizedResourceCreateInput

View File

@@ -53,7 +53,18 @@ type ProjectizedResourceListInput struct {
OrderByTenant string `json:"order_by_tenant" "yunion:deprecated-by":"order_by_project"`
}
type StatusUserResourceListInput struct {
StatusResourceBaseListInput
UserResourceListInput
}
type UserResourceListInput struct {
StandaloneResourceListInput
ScopedResourceInput
// list in admin mode
Admin *bool `json:"admin"`
// 查询指定的用户ID或名称拥有的资源
User string `json:"user"`
// swagger:ignore

View File

@@ -14,6 +14,8 @@
package logger
import "yunion.io/x/onecloud/pkg/apis"
const (
SERVICE_TYPE = "log"
SERVICE_TYPE = apis.SERVICE_TYPE_LOG
)

View File

@@ -72,16 +72,6 @@ type SDataSource struct {
IsDefault *bool `json:"is_default,omitempty"`
}
// SMeterAlert is an autogenerated struct via yunion.io/x/onecloud/pkg/monitor/models.SMeterAlert.
type SMeterAlert struct {
SV1Alert
}
// SNodeAlert is an autogenerated struct via yunion.io/x/onecloud/pkg/monitor/models.SNodeAlert.
type SNodeAlert struct {
SV1Alert
}
// SNotification is an autogenerated struct via yunion.io/x/onecloud/pkg/monitor/models.SNotification.
type SNotification struct {
apis.SVirtualResourceBase
@@ -111,6 +101,10 @@ type SSuggestSysAlert struct {
Provider string `json:"provider"`
Project string `json:"project"`
Cloudaccount string `json:"cloudaccount"`
// 费用
Amount float64 `json:"amount"`
// 币种
Currency string `json:"currency"`
}
// SSuggestSysRule is an autogenerated struct via yunion.io/x/onecloud/pkg/monitor/models.SSuggestSysRule.
@@ -123,8 +117,3 @@ type SSuggestSysRule struct {
Setting interface{} `json:"setting"`
ExecTime time.Time `json:"exec_time"`
}
// SV1Alert is an autogenerated struct via yunion.io/x/onecloud/pkg/monitor/models.SV1Alert.
type SV1Alert struct {
SAlert
}

View File

@@ -14,7 +14,9 @@
package notify
import "yunion.io/x/onecloud/pkg/apis"
const (
SERVICE_TYPE = "notify"
SERVICE_TYPE = apis.SERVICE_TYPE_NOTIFY
SERVICE_VERSION = ""
)

View File

@@ -121,6 +121,17 @@ type MetadataResourceInfo struct {
Metadata map[string]string `json:"metadata"`
}
type StatusUserResourceDetails struct {
UserResourceDetails
}
type UserResourceDetails struct {
StandaloneResourceDetails
// 用户名称
OwnerName string `json:"owner_name"`
}
type StandaloneResourceDetails struct {
ResourceBaseDetails

View File

@@ -14,6 +14,8 @@
package yunionconf
import "yunion.io/x/onecloud/pkg/apis"
const (
SERVICE_TYPE = "yunionconf"
SERVICE_TYPE = apis.SERVICE_TYPE_YUNIONCONF
)

View File

@@ -99,60 +99,9 @@ type SJointResourceBase struct {
// SKeystoneCacheObject is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SKeystoneCacheObject.
type SKeystoneCacheObject struct {
SStandaloneResourceBase
DomainId string `json:"domain_id"`
Domain string `json:"domain"`
}
// SMetadata is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SMetadata.
type SMetadata struct {
// 资源类型
// example: network
ObjType string `json:"obj_type"`
// 资源ID
// example: 87321a70-1ecb-422a-8b0c-c9aa632a46a7
ObjId string `json:"obj_id"`
// 资源组合ID
// example: network::87321a70-1ecb-422a-8b0c-c9aa632a46a7
Id string `json:"id"`
// 标签KEY
// exmaple: 部门
Key string `json:"key"`
// 标签值
// example: 技术部
Value string `json:"value"`
// 是否被删除
Deleted bool `json:"deleted"`
}
// SOpsLog is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SOpsLog.
type SOpsLog struct {
Id int64 `json:"id"`
// = Column(BigInteger, primary_key=True)
ObjType string `json:"obj_type"`
// = Column(VARCHAR(40, charset='ascii'), nullable=False)
ObjId string `json:"obj_id"`
// = Column(VARCHAR(ID_LENGTH, charset='ascii'), nullable=False)
ObjName string `json:"obj_name"`
// = Column(VARCHAR(128, charset='utf8'), nullable=False)
Action string `json:"action"`
// = Column(VARCHAR(32, charset='ascii'), nullable=False)
Notes string `json:"notes"`
ProjectId string `json:"tenant_id"`
// = Column(VARCHAR(ID_LENGTH, charset='ascii'))
Project string `json:"tenant"`
ProjectDomainId string `json:"project_domain_id"`
ProjectDomain string `json:"project_domain"`
UserId string `json:"user_id"`
// = Column(VARCHAR(ID_LENGTH, charset='ascii'))
User string `json:"user"`
// = Column(VARCHAR(128, charset='utf8'))
DomainId string `json:"domain_id"`
Domain string `json:"domain"`
Roles string `json:"roles"`
// BillingType string `width:"64" charset:"ascii" default:"postpaid" list:"user" create:"user"` // billing_type = Column(VARCHAR(64, charset='ascii'), nullable=True)
OpsTime time.Time `json:"ops_time"`
OwnerDomainId string `json:"owner_domain_id"`
OwnerProjectId string `json:"owner_tenant_id"`
DomainId string `json:"domain_id"`
Domain string `json:"domain"`
LastCheck time.Time `json:"last_check"`
}
// SProjectizedResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SProjectizedResourceBase.
@@ -247,14 +196,17 @@ type SStatusStandaloneResourceBase struct {
SStatusResourceBase
}
// STenant is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.STenant.
type STenant struct {
SKeystoneCacheObject
// SStatusUserResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SStatusUserResourceBase.
type SStatusUserResourceBase struct {
SUserResourceBase
SStatusResourceBase
}
// SUser is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SUser.
type SUser struct {
SKeystoneCacheObject
// SUserResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SUserResourceBase.
type SUserResourceBase struct {
SStandaloneResourceBase
// 本地用户Id
OwnerId string `json:"owner_id"`
}
// SVirtualJointResourceBase is an autogenerated struct via yunion.io/x/onecloud/pkg/cloudcommon/db.SVirtualJointResourceBase.

View File

@@ -323,6 +323,13 @@ type IVirtualModelManager interface {
GetResourceCount() ([]SScopeResourceCount, error)
}
type IUserModelManager interface {
IStandaloneModelManager
GetIUserModelManager() IUserModelManager
GetResourceCount() ([]SScopeResourceCount, error)
}
type IVirtualModel interface {
IStandaloneModel
IPendingDeletable

View File

@@ -29,13 +29,13 @@ import (
"yunion.io/x/onecloud/pkg/mcclient/auth"
)
func AddProjectResourceCountHandler(prefix string, app *appsrv.Application) {
prefix = fmt.Sprintf("%s/project-resources", prefix)
app.AddHandler2("GET", prefix, auth.Authenticate(getAllProjectResourceCountsHandler), nil, "get_project_resources", nil)
func AddScopeResourceCountHandler(prefix string, app *appsrv.Application) {
prefix = fmt.Sprintf("%s/scope-resources", prefix)
app.AddHandler2("GET", prefix, auth.Authenticate(getAllScopeResourceCountsHandler), nil, "get_scope_resources", nil)
}
func getAllProjectResourceCountsHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
cnt, err := getAllProjectResourceCounts()
func getAllScopeResourceCountsHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
cnt, err := getAllScopeResourceCounts()
if err != nil {
httperrors.GeneralServerError(w, err)
return
@@ -43,7 +43,7 @@ func getAllProjectResourceCountsHandler(ctx context.Context, w http.ResponseWrit
appsrv.SendJSON(w, jsonutils.Marshal(cnt))
}
func getAllProjectResourceCounts() (map[string][]SScopeResourceCount, error) {
func getAllScopeResourceCounts() (map[string][]SScopeResourceCount, error) {
ret := make(map[string][]SScopeResourceCount)
for _, manager := range globalTables {
if virtman, ok := manager.(IVirtualModelManager); ok {
@@ -58,6 +58,12 @@ func getAllProjectResourceCounts() (map[string][]SScopeResourceCount, error) {
return nil, errors.Wrap(err, "getDomainResourceCount")
}
ret[domainMan.KeywordPlural()] = resCnt
} else if userMan, ok := manager.(IUserModelManager); ok {
resCnt, err := userMan.GetResourceCount()
if err != nil {
return nil, errors.Wrap(err, "getUserResourceCount")
}
ret[userMan.KeywordPlural()] = resCnt
}
}
return ret, nil
@@ -66,39 +72,30 @@ func getAllProjectResourceCounts() (map[string][]SScopeResourceCount, error) {
type SScopeResourceCount struct {
TenantId string `json:"tenant_id"`
DomainId string `json:"domain_id"`
OwnerId string `json:"owner_id"`
ResCount int `json:"res_count"`
}
func (virtman *SVirtualResourceBaseManager) GetResourceCount() ([]SScopeResourceCount, error) {
virts := virtman.GetIVirtualModelManager().Query()
// log.Debugf("GetResourceCount: %s", virtman.keywordPlural)
return CalculateProjectResourceCount(virts)
}
func CalculateProjectResourceCount(query *sqlchemy.SQuery) ([]SScopeResourceCount, error) {
virts := query.SubQuery()
q := virts.Query(virts.Field("tenant_id"), sqlchemy.COUNT("res_count"))
q = q.IsNotEmpty("tenant_id")
q = q.GroupBy(virts.Field("tenant_id"))
cnts := make([]SScopeResourceCount, 0)
err := q.All(&cnts)
if err != nil && err != sql.ErrNoRows {
return nil, errors.Wrap(err, "q.All")
}
return cnts, nil
return CalculateResourceCount(virts, "tenant_id")
}
func (domainman *SDomainLevelResourceBaseManager) GetResourceCount() ([]SScopeResourceCount, error) {
virts := domainman.GetIDomainLevelModelManager().Query()
// log.Debugf("GetResourceCount: %s", virtman.keywordPlural)
return CalculateDomainResourceCount(virts)
return CalculateResourceCount(virts, "domain_id")
}
func CalculateDomainResourceCount(query *sqlchemy.SQuery) ([]SScopeResourceCount, error) {
func (userman *SUserResourceBaseManager) GetResourceCount() ([]SScopeResourceCount, error) {
virts := userman.GetIUserModelManager().Query()
return CalculateResourceCount(virts, "owner_id")
}
func CalculateResourceCount(query *sqlchemy.SQuery, field string) ([]SScopeResourceCount, error) {
virts := query.SubQuery()
q := virts.Query(virts.Field("domain_id"), sqlchemy.COUNT("res_count"))
q = q.IsNotEmpty("domain_id")
q = q.GroupBy(virts.Field("domain_id"))
q := virts.Query(virts.Field(field), sqlchemy.COUNT("res_count"))
q = q.IsNotEmpty(field)
q = q.GroupBy(virts.Field(field))
cnts := make([]SScopeResourceCount, 0)
err := q.All(&cnts)
if err != nil && err != sql.ErrNoRows {

View File

@@ -0,0 +1,121 @@
// 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 db
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SStatusUserResourceBase struct {
SUserResourceBase
SStatusResourceBase
}
type SStatusUserResourceBaseManager struct {
SUserResourceBaseManager
SStatusResourceBaseManager
}
func NewStatusUserResourceBaseManager(dt interface{}, tableName string, keyword string, keywordPlural string) SStatusUserResourceBaseManager {
return SStatusUserResourceBaseManager{
SUserResourceBaseManager: NewUserResourceBaseManager(dt, tableName, keyword, keywordPlural),
}
}
func (model *SStatusUserResourceBase) SetStatus(userCred mcclient.TokenCredential, status string, reason string) error {
return statusBaseSetStatus(model, userCred, status, reason)
}
func (manager *SStatusUserResourceBaseManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input apis.StatusUserResourceCreateInput) (apis.StatusUserResourceCreateInput, error) {
var err error
input.UserResourceCreateInput, err = manager.SUserResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.UserResourceCreateInput)
if err != nil {
return input, err
}
return input, nil
}
func (manager *SStatusUserResourceBaseManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query apis.StatusUserResourceListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SUserResourceBaseManager.ListItemFilter(ctx, q, userCred, query.UserResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SUserResourceBaseManager.ListItemFilter")
}
q, err = manager.SStatusResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SStatusUserResourceBaseManager) OrderByExtraFields(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query apis.StatusUserResourceListInput) (*sqlchemy.SQuery, error) {
q, err := manager.SUserResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.UserResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SUserResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SStatusResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SStatusUserResourceBaseManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
q, err := manager.SUserResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SStatusUserResourceBaseManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []apis.StatusUserResourceDetails {
rows := make([]apis.StatusUserResourceDetails, len(objs))
userRows := manager.SUserResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = apis.StatusUserResourceDetails{
UserResourceDetails: userRows[i],
}
}
return rows
}
func (model *SStatusUserResourceBase) GetExtraDetails(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
isList bool,
) (apis.StatusUserResourceDetails, error) {
return apis.StatusUserResourceDetails{}, nil
}

View File

@@ -0,0 +1,202 @@
// 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 db
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/reflectutils"
"yunion.io/x/sqlchemy"
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/rbacutils"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SUserResourceBaseManager struct {
SStandaloneResourceBaseManager
}
func NewUserResourceBaseManager(dt interface{}, tableName string, keyword string, keywordPlural string) SUserResourceBaseManager {
return SUserResourceBaseManager{
SStandaloneResourceBaseManager: NewStandaloneResourceBaseManager(dt,
tableName, keyword, keywordPlural),
}
}
type SUserResourceBase struct {
SStandaloneResourceBase
// 本地用户Id
OwnerId string `width:"128" charset:"ascii" index:"true" list:"user" nullable:"false" create:"required"`
}
func (manager *SUserResourceBaseManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query apis.UserResourceListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StandaloneResourceListInput)
if err != nil {
return nil, err
}
if ((query.Admin != nil && *query.Admin) || query.Scope == string(rbacutils.ScopeSystem)) && IsAdminAllowList(userCred, manager) {
user := query.User
if len(user) > 0 {
uc, _ := UserCacheManager.FetchUserByIdOrName(ctx, user)
if uc == nil {
return nil, httperrors.NewUserNotFoundError("user %s not found", user)
}
q = q.Equals("owner_id", uc.Id)
}
} else {
q = q.Equals("owner_id", userCred.GetUserId())
}
return q, nil
}
func (manager *SUserResourceBaseManager) OrderByExtraFields(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query apis.UserResourceListInput) (*sqlchemy.SQuery, error) {
q, err := manager.SStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StandaloneResourceListInput)
if err != nil {
return nil, err
}
return q, nil
}
func (manager *SUserResourceBaseManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
q, err := manager.SStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SUserResourceBaseManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []apis.UserResourceDetails {
rows := make([]apis.UserResourceDetails, len(objs))
stdRows := manager.SStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
userIds := make([]string, len(objs))
for i := range rows {
rows[i] = apis.UserResourceDetails{
StandaloneResourceDetails: stdRows[i],
}
var base *SUserResourceBase
reflectutils.FindAnonymouStructPointer(objs[i], &base)
if base != nil && len(base.OwnerId) > 0 {
userIds[i] = base.OwnerId
}
}
userMaps, err := FetchIdNameMap2(UserCacheManager, userIds)
if err != nil {
log.Errorf("FetchIdNameMap2 fail: %v", err)
return rows
}
for i := range rows {
rows[i].OwnerName, _ = userMaps[userIds[i]]
}
return rows
}
func (manager *SUserResourceBaseManager) FilterByOwner(q *sqlchemy.SQuery, owner mcclient.IIdentityProvider, scope rbacutils.TRbacScope) *sqlchemy.SQuery {
if owner != nil {
if scope == rbacutils.ScopeUser {
if len(owner.GetUserId()) > 0 {
q = q.Equals("owner_id", owner.GetUserId())
}
}
}
return q
}
func (self *SUserResourceBase) GetOwnerId() mcclient.IIdentityProvider {
owner := SOwnerId{UserId: self.OwnerId}
return &owner
}
func (model *SUserResourceBase) IsOwner(userCred mcclient.TokenCredential) bool {
return userCred.GetProjectId() == model.OwnerId
}
func (manager *SUserResourceBaseManager) GetIUserModelManager() IUserModelManager {
return manager.GetVirtualObject().(IUserModelManager)
}
func (manager *SUserResourceBaseManager) FetchByName(userCred mcclient.IIdentityProvider, idStr string) (IModel, error) {
return FetchByName(manager, userCred, idStr)
}
func (manager *SUserResourceBaseManager) FetchByIdOrName(userCred mcclient.IIdentityProvider, idStr string) (IModel, error) {
return FetchByIdOrName(manager, userCred, idStr)
}
func (manager *SUserResourceBaseManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input apis.UserResourceCreateInput) (apis.UserResourceCreateInput, error) {
if len(input.OwnerId) == 0 {
input.OwnerId = userCred.GetUserId()
}
var err error
input.StandaloneResourceCreateInput, err = manager.SStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.StandaloneResourceCreateInput)
if err != nil {
return input, errors.Wrap(err, "SStandaloneResourceBaseManager.ValidateCreateData")
}
return input, nil
}
func (manager *SUserResourceBaseManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return true
}
func (manager *SUserResourceBaseManager) AllowCreateItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return true
}
func (self *SUserResourceBase) AllowUpdateItem(ctx context.Context, userCred mcclient.TokenCredential) bool {
return self.IsOwner(userCred) || IsAdminAllowUpdate(userCred, self)
}
func (self *SUserResourceBase) AllowDeleteItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || IsAdminAllowDelete(userCred, self)
}
func (self *SUserResourceBase) AllowGetDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || IsAdminAllowGet(userCred, self)
}
func (manager *SUserResourceBaseManager) FetchOwnerId(ctx context.Context, data jsonutils.JSONObject) (mcclient.IIdentityProvider, error) {
return FetchUserInfo(ctx, data)
}
func (manager *SUserResourceBaseManager) NamespaceScope() rbacutils.TRbacScope {
return rbacutils.ScopeUser
}
func (manager *SUserResourceBaseManager) ResourceScope() rbacutils.TRbacScope {
return rbacutils.ScopeUser
}

View File

@@ -0,0 +1,837 @@
// 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 models
import (
"context"
"database/sql"
"net/http"
"net/url"
"golang.org/x/net/http/httpproxy"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/utils"
proxyapi "yunion.io/x/onecloud/pkg/apis/cloudcommon/proxy"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/options"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/util/httputils"
)
// +onecloud:swagger-gen-ignore
type SCloudaccountManager struct {
db.SDomainLevelResourceBaseManager
}
var CloudaccountManager *SCloudaccountManager
func init() {
CloudaccountManager = &SCloudaccountManager{
SDomainLevelResourceBaseManager: db.NewDomainLevelResourceBaseManager(
SCloudaccount{},
"cloudaccounts_tbl",
"cloudaccount",
"cloudaccounts",
),
}
CloudaccountManager.SetVirtualObject(CloudaccountManager)
}
type SCloudaccount struct {
db.SStandaloneResourceBase
db.SDomainizedResourceBase
Provider string `width:"64" charset:"ascii" list:"domain"`
Brand string `width:"64" charset:"utf8" nullable:"true" list:"domain"`
IamLoginUrl string `width:"512" charset:"ascii"`
IsSupportCloudId tristate.TriState `nullable:"false" get:"domain" list:"domain" default:"false"`
}
func (manager *SCloudaccountManager) GetICloudaccounts() ([]SCloudaccount, error) {
s := auth.GetAdminSession(context.Background(), options.Options.Region, "")
params := jsonutils.NewDict()
result, err := modules.Cloudaccounts.List(s, params)
if err != nil {
return nil, errors.Wrap(err, "modules.Cloudaccounts.List")
}
accounts := []SCloudaccount{}
err = jsonutils.Update(&accounts, result.Data)
if err != nil {
return nil, errors.Wrap(err, "jsonutils.Update")
}
return accounts, nil
}
func (manager *SCloudaccountManager) GetCloudaccounts() ([]SCloudaccount, error) {
accounts := []SCloudaccount{}
q := manager.Query()
err := db.FetchModelObjects(manager, q, &accounts)
if err != nil {
return nil, err
}
return accounts, nil
}
func (manager *SCloudaccountManager) syncCloudaccounts(ctx context.Context, userCred mcclient.TokenCredential) (localAccounts []SCloudaccount, result compare.SyncResult) {
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
accounts, err := manager.GetICloudaccounts()
if err != nil {
result.Error(errors.Wrap(err, "GetRegionCloudaccounts"))
return
}
dbAccounts, err := manager.GetCloudaccounts()
if err != nil {
result.Error(errors.Wrap(err, "GetLocalCloudaccounts"))
return
}
removed := make([]SCloudaccount, 0)
commondb := make([]SCloudaccount, 0)
commonext := make([]SCloudaccount, 0)
added := make([]SCloudaccount, 0)
err = compare.CompareSets(dbAccounts, accounts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(errors.Wrap(err, "compare.CompareSets"))
return
}
for i := 0; i < len(removed); i++ {
err = removed[i].syncRemoveCloudaccount(ctx, userCred)
if err != nil {
result.AddError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err = commondb[i].syncWithICloudaccount(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
localAccounts = append(localAccounts, commondb[i])
result.Update()
}
for i := 0; i < len(added); i++ {
account, err := manager.newFromICloudaccount(ctx, userCred, &added[i])
if err != nil {
result.AddError(err)
continue
}
localAccounts = append(localAccounts, *account)
result.Add()
}
return
}
func (self *SCloudaccount) removeCloudproviders(ctx context.Context, userCred mcclient.TokenCredential) error {
providers, err := self.GetCloudproviders()
if err != nil {
return errors.Wrap(err, "GetCloudproviders")
}
for i := range providers {
err = providers[i].Delete(ctx, userCred)
if err != nil {
return errors.Wrap(err, "provider.Delete")
}
}
return nil
}
func (self *SCloudaccount) GetCloudproviderId() string {
return ""
}
func (self *SCloudaccount) removeCloudgroupcaches(ctx context.Context, userCred mcclient.TokenCredential) error {
caches, err := self.GetCloudgroupcaches()
if err != nil {
return errors.Wrap(err, "GetCloudgroupcaches")
}
for i := range caches {
err = caches[i].Delete(ctx, userCred)
if err != nil {
return errors.Wrap(err, "caches[i].Delete")
}
}
return nil
}
func (self *SCloudaccount) syncRemoveCloudaccount(ctx context.Context, userCred mcclient.TokenCredential) error {
err := self.syncRemoveClouduser(ctx, userCred)
if err != nil {
return errors.Wrap(err, "syncRemoveClouduser")
}
err = self.removeCloudproviders(ctx, userCred)
if err != nil {
return errors.Wrap(err, "removeCloudproviders")
}
err = self.removeCloudgroupcaches(ctx, userCred)
if err != nil {
return errors.Wrap(err, "removeCloudgroupcaches")
}
return nil
}
func (self *SCloudaccount) syncRemoveClouduser(ctx context.Context, userCred mcclient.TokenCredential) error {
users, err := self.getCloudusers()
if err != nil {
return errors.Wrap(err, "getCloudusers")
}
for i := range users {
err = users[i].RealDelete(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "RealDelete user %s(%s)", users[i].Name, users[i].Id)
}
}
return self.Delete(ctx, userCred)
}
func (manager *SCloudaccountManager) newFromICloudaccount(ctx context.Context, userCred mcclient.TokenCredential, account *SCloudaccount) (*SCloudaccount, error) {
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
account.SetModelManager(manager, account)
err := manager.TableSpec().Insert(ctx, account)
if err != nil {
return nil, errors.Wrap(err, "Insert")
}
return account, nil
}
func (self *SCloudaccount) syncWithICloudaccount(ctx context.Context, userCred mcclient.TokenCredential, account SCloudaccount) error {
_, err := db.UpdateWithLock(ctx, self, func() error {
self.Name = account.Name
self.DomainId = account.DomainId
self.Brand = account.Brand
self.IamLoginUrl = account.IamLoginUrl
self.IsSupportCloudId = account.IsSupportCloudId
return nil
})
if err != nil {
return errors.Wrap(err, "db.UpdateWithLock")
}
return nil
}
func (manager *SCloudaccountManager) SyncCloudaccounts(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
localAccounts, result := manager.syncCloudaccounts(ctx, userCred)
log.Infof("SyncCloudaccounts: %s", result.Result())
for i, account := range localAccounts {
lockman.LockObject(ctx, &localAccounts[i])
defer lockman.ReleaseObject(ctx, &localAccounts[i])
factory, err := account.GetProviderFactory()
if err != nil {
log.Errorf("GetProviderFactory: %v", err)
continue
}
if !factory.IsClouduserBelongCloudprovider() {
continue
}
result = account.syncCloudprovider(ctx, userCred)
log.Infof("sync cloudprovider for cloudaccount %s(%s) result: %s", account.Name, account.Id, result.Result())
}
}
func (self SCloudaccount) GetGlobalId() string {
return self.Id
}
func (self SCloudaccount) GetExternalId() string {
return self.Id
}
func (manager *SCloudaccountManager) FetchAccount(ctx context.Context, id string) (*SCloudaccount, error) {
account, err := manager.FetchById(id)
if err != nil {
if err == sql.ErrNoRows {
session := auth.GetAdminSession(context.Background(), options.Options.Region, "")
result, err := modules.Cloudaccounts.Get(session, id, nil)
if err != nil {
return nil, errors.Wrap(err, "Cloudaccounts.Get")
}
_account := &SCloudaccount{}
_account.SetModelManager(manager, _account)
err = result.Unmarshal(_account)
if err != nil {
return nil, errors.Wrap(err, "result.Unmarshal")
}
lockman.LockRawObject(ctx, manager.KeywordPlural(), id)
defer lockman.ReleaseRawObject(ctx, manager.KeywordPlural(), id)
return _account, manager.TableSpec().InsertOrUpdate(ctx, _account)
}
return nil, errors.Wrap(err, "manager.FetchById")
}
return account.(*SCloudaccount), nil
}
type SCloudDelegate struct {
Id string
Name string
Enabled bool
Status string
SyncStatus string
AccessUrl string
Account string
Secret string
Provider string
Brand string
ProxySetting proxyapi.SProxySetting
}
func (self *SCloudaccount) getCloudDelegate(ctx context.Context) (*SCloudDelegate, error) {
s := auth.GetAdminSession(ctx, options.Options.Region, "")
result, err := modules.Cloudaccounts.Get(s, self.Id, nil)
if err != nil {
return nil, errors.Wrap(err, "Cloudaccounts.Get")
}
account := &SCloudDelegate{}
err = result.Unmarshal(account)
if err != nil {
return nil, errors.Wrap(err, "result.Unmarshal")
}
return account, nil
}
func (self *SCloudaccount) GetProvider() (cloudprovider.ICloudProvider, error) {
delegate, err := self.getCloudDelegate(context.Background())
if err != nil {
return nil, errors.Wrap(err, "getCloudDelegate")
}
return delegate.GetProvider()
}
func (self *SCloudaccount) GetCloudDelegaes(ctx context.Context) ([]SCloudDelegate, error) {
s := auth.GetAdminSession(ctx, options.Options.Region, "")
params := map[string]string{"cloudaccount": self.Id}
result, err := modules.Cloudproviders.List(s, jsonutils.Marshal(params))
if err != nil {
return nil, errors.Wrap(err, "Cloudproviders.List")
}
providers := []SCloudDelegate{}
err = jsonutils.Update(&providers, result.Data)
if err != nil {
return nil, errors.Wrap(err, "jsonutils.Update")
}
return providers, nil
}
func (account *SCloudDelegate) getPassword() (string, error) {
return utils.DescryptAESBase64(account.Id, account.Secret)
}
func (account *SCloudDelegate) getAccessUrl() string {
return account.AccessUrl
}
func (self *SCloudaccount) GetProviderFactory() (cloudprovider.ICloudProviderFactory, error) {
return cloudprovider.GetProviderFactory(self.Provider)
}
func (account *SCloudDelegate) GetProvider() (cloudprovider.ICloudProvider, error) {
if !account.Enabled {
return nil, errors.Errorf("Cloud account %s is not enabled", account.Name)
}
accessUrl := account.getAccessUrl()
passwd, err := account.getPassword()
if err != nil {
return nil, err
}
var proxyFunc httputils.TransportProxyFunc
{
cfg := &httpproxy.Config{
HTTPProxy: account.ProxySetting.HTTPProxy,
HTTPSProxy: account.ProxySetting.HTTPSProxy,
NoProxy: account.ProxySetting.NoProxy,
}
cfgProxyFunc := cfg.ProxyFunc()
proxyFunc = func(req *http.Request) (*url.URL, error) {
return cfgProxyFunc(req.URL)
}
}
return cloudprovider.GetProvider(cloudprovider.ProviderConfig{
Id: account.Id,
Name: account.Name,
Vendor: account.Provider,
URL: accessUrl,
Account: account.Account,
Secret: passwd,
ProxyFunc: proxyFunc,
})
}
func (manager *SCloudaccountManager) SyncCloudusers(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
accounts, err := manager.GetCloudaccounts()
if err != nil {
log.Errorf("GetLocalCloudaccounts: %v", err)
return
}
for i := range accounts {
factory, err := accounts[i].GetProviderFactory()
if err != nil {
continue
}
if factory.IsSupportClouduser() {
err = accounts[i].StartSyncCloudusersTask(ctx, userCred, "")
if err != nil {
log.Errorf("StartSyncCloudusersTask for account %s(%s) error: %v", accounts[i].Name, accounts[i].Provider, err)
}
}
}
}
func (self *SCloudaccount) StartSyncCloudusersTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
params := jsonutils.NewDict()
task, err := taskman.TaskManager.NewTask(ctx, "SyncCloudusersTask", self, userCred, params, parentTaskId, "", nil)
if err != nil {
return errors.Wrap(err, "NewTask")
}
task.ScheduleRun(nil)
return nil
}
func (self *SCloudaccount) StartSyncCloudgroupsTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
params := jsonutils.NewDict()
task, err := taskman.TaskManager.NewTask(ctx, "SyncCloudgroupsTask", self, userCred, params, parentTaskId, "", nil)
if err != nil {
return errors.Wrap(err, "NewTask")
}
task.ScheduleRun(nil)
return nil
}
func (self *SCloudaccount) StartSyncCloudpoliciesTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
params := jsonutils.NewDict()
task, err := taskman.TaskManager.NewTask(ctx, "SyncCloudpoliciesTask", self, userCred, params, parentTaskId, "", nil)
if err != nil {
return errors.Wrap(err, "NewTask")
}
task.ScheduleRun(nil)
return nil
}
func (self *SCloudaccount) getCloudusers() ([]SClouduser, error) {
users := []SClouduser{}
q := ClouduserManager.Query().Equals("cloudaccount_id", self.Id)
err := db.FetchModelObjects(ClouduserManager, q, &users)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
return users, nil
}
func (self *SCloudaccount) GetCloudusersByProviderId(cloudproviderId string) ([]SClouduser, error) {
users := []SClouduser{}
q := ClouduserManager.Query().Equals("status", api.CLOUD_USER_STATUS_AVAILABLE).Equals("cloudaccount_id", self.Id)
if len(cloudproviderId) > 0 {
q = q.Equals("cloudprovider_id", cloudproviderId)
}
err := db.FetchModelObjects(ClouduserManager, q, &users)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
return users, nil
}
func (self *SCloudaccount) SyncCloudusers(ctx context.Context, userCred mcclient.TokenCredential, cloudproviderId string, iUsers []cloudprovider.IClouduser) ([]SClouduser, []cloudprovider.IClouduser, compare.SyncResult) {
result := compare.SyncResult{}
dbUsers, err := self.GetCloudusersByProviderId(cloudproviderId)
if err != nil {
result.Error(errors.Wrap(err, "GetCloudusersByProviderId"))
return nil, nil, result
}
localUsers := []SClouduser{}
remoteUsers := []cloudprovider.IClouduser{}
removed := make([]SClouduser, 0)
commondb := make([]SClouduser, 0)
commonext := make([]cloudprovider.IClouduser, 0)
added := make([]cloudprovider.IClouduser, 0)
err = compare.CompareSets(dbUsers, iUsers, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(errors.Wrap(err, "compare.CompareSets"))
return nil, nil, result
}
for i := 0; i < len(removed); i++ {
if len(removed[i].ExternalId) > 0 {
err = removed[i].RealDelete(ctx, userCred)
if err != nil {
result.AddError(err)
continue
}
result.Delete()
}
}
for i := 0; i < len(commondb); i++ {
err = commondb[i].SyncWithClouduser(ctx, userCred, commonext[i], cloudproviderId)
if err != nil {
result.UpdateError(err)
continue
}
localUsers = append(localUsers, commondb[i])
remoteUsers = append(remoteUsers, commonext[i])
result.Update()
}
for i := 0; i < len(added); i++ {
if added[i].GetName() != cloudprovider.TEST_CLOUDID_USER_NAME {
user, err := ClouduserManager.newFromClouduser(ctx, userCred, added[i], self.Id, cloudproviderId)
if err != nil {
result.AddError(err)
continue
}
localUsers = append(localUsers, *user)
remoteUsers = append(remoteUsers, added[i])
result.Add()
}
}
return localUsers, remoteUsers, result
}
func (self *SCloudaccount) GetCloudpolicies() ([]SCloudpolicy, error) {
q := CloudpolicyManager.Query().Equals("provider", self.Provider)
policies := []SCloudpolicy{}
err := db.FetchModelObjects(CloudpolicyManager, q, &policies)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
return policies, nil
}
func (self *SCloudaccount) SyncCloudpolicies(ctx context.Context, userCred mcclient.TokenCredential, iPolicies []cloudprovider.ICloudpolicy) compare.SyncResult {
result := compare.SyncResult{}
dbPolicies, err := self.GetCloudpolicies()
if err != nil {
result.Error(errors.Wrap(err, "GetCloudpolicies"))
return result
}
removed := make([]SCloudpolicy, 0)
commondb := make([]SCloudpolicy, 0)
commonext := make([]cloudprovider.ICloudpolicy, 0)
added := make([]cloudprovider.ICloudpolicy, 0)
err = compare.CompareSets(dbPolicies, iPolicies, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(errors.Wrap(err, "compare.CompareSets"))
return result
}
for i := 0; i < len(removed); i++ {
err = removed[i].Delete(ctx, userCred)
if err != nil {
result.AddError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err = commondb[i].SyncWithCloudpolicy(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i++ {
err := CloudpolicyManager.newFromCloudpolicy(ctx, userCred, added[i], self.Provider)
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func (self *SCloudaccount) GetCloudproviders() ([]SCloudprovider, error) {
q := CloudproviderManager.Query().Equals("cloudaccount_id", self.Id)
providers := []SCloudprovider{}
err := db.FetchModelObjects(CloudproviderManager, q, &providers)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
return providers, nil
}
func (self *SCloudaccount) GetICloudprovider() ([]SCloudprovider, error) {
s := auth.GetAdminSession(context.Background(), options.Options.Region, "")
params := map[string]string{"cloudaccount": self.Id}
result, err := modules.Cloudproviders.List(s, jsonutils.Marshal(params))
if err != nil {
return nil, errors.Wrap(err, "Cloudproviders.List")
}
providers := []SCloudprovider{}
err = jsonutils.Update(&providers, result.Data)
if err != nil {
return nil, errors.Wrap(err, "jsonutils.Update")
}
return providers, nil
}
func (self *SCloudaccount) syncCloudprovider(ctx context.Context, userCred mcclient.TokenCredential) compare.SyncResult {
result := compare.SyncResult{}
providers, err := self.GetICloudprovider()
if err != nil {
result.Error(errors.Wrap(err, "GetRegionCloudprovider"))
return result
}
dbProviders, err := self.GetCloudproviders()
if err != nil {
result.Error(errors.Wrap(err, "GetCloudproviders"))
return result
}
removed := make([]SCloudprovider, 0)
commondb := make([]SCloudprovider, 0)
commonext := make([]SCloudprovider, 0)
added := make([]SCloudprovider, 0)
err = compare.CompareSets(dbProviders, providers, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(errors.Wrap(err, "compare.CompareSets"))
return result
}
for i := 0; i < len(removed); i++ {
err = removed[i].syncRemoveClouduser(ctx, userCred)
if err != nil {
result.AddError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err = commondb[i].syncWithRegionProvider(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i++ {
err = CloudproviderManager.newFromRegionProvider(ctx, userCred, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func (self *SCloudaccount) GetCloudgroups() ([]SCloudgroup, error) {
groups := []SCloudgroup{}
q := CloudgroupManager.Query().Equals("provider", self.Provider).Equals("domain_id", self.DomainId)
err := db.FetchModelObjects(CloudgroupManager, q, &groups)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
return groups, nil
}
func (self *SCloudaccount) GetCloudgroupcaches() ([]SCloudgroupcache, error) {
caches := []SCloudgroupcache{}
q := CloudgroupcacheManager.Query().Equals("cloudaccount_id", self.Id)
err := db.FetchModelObjects(CloudgroupcacheManager, q, &caches)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
return caches, nil
}
func (manager *SCloudaccountManager) GetSupportCreateCloudgroupAccounts() ([]SCloudaccount, error) {
accounts := []SCloudaccount{}
q := manager.Query().In("provider", cloudprovider.GetSupportCloudgroupProviders())
err := db.FetchModelObjects(manager, q, &accounts)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
return accounts, nil
}
func (manager *SCloudaccountManager) SyncCloudpolicies(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
accounts, err := manager.GetCloudaccounts()
if err != nil {
log.Errorf("GetCloudaccounts error: %v", err)
return
}
for i := range accounts {
err = accounts[i].StartSyncCloudpolicyTask(ctx, userCred, "")
if err != nil {
log.Errorf("StartSyncCloudpolicyTask for account %s(%s) error: %v", accounts[i].Name, accounts[i].Provider, err)
}
}
}
func (self *SCloudaccount) StartSyncCloudpolicyTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
params := jsonutils.NewDict()
task, err := taskman.TaskManager.NewTask(ctx, "SyncCloudpoliciesTask", self, userCred, params, parentTaskId, "", nil)
if err != nil {
return errors.Wrap(err, "NewTask")
}
task.ScheduleRun(nil)
return nil
}
func (manager *SCloudaccountManager) SyncCloudgroups(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
accounts, err := manager.GetSupportCreateCloudgroupAccounts()
if err != nil {
log.Errorf("GetSupportCreateCloudgroupAccounts error: %v", err)
return
}
for i := range accounts {
err = accounts[i].StartSyncCloudgroupcacheTask(ctx, userCred, "")
if err != nil {
log.Errorf("StartSyncCloudgroupcacheTask for account %s(%s) error: %v", accounts[i].Name, accounts[i].Provider, err)
}
}
}
func (self *SCloudaccount) StartSyncCloudgroupcacheTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
params := jsonutils.NewDict()
task, err := taskman.TaskManager.NewTask(ctx, "SyncCloudgroupcachesTask", self, userCred, params, parentTaskId, "", nil)
if err != nil {
return errors.Wrap(err, "NewTask")
}
task.ScheduleRun(nil)
return nil
}
func (self *SCloudaccount) SyncCloudgroupcaches(ctx context.Context, userCred mcclient.TokenCredential, iGroups []cloudprovider.ICloudgroup) compare.SyncResult {
result := compare.SyncResult{}
dbCaches, err := self.GetCloudgroupcaches()
if err != nil {
result.Error(errors.Wrap(err, "GetCloudgroupcaches"))
return result
}
removed := make([]SCloudgroupcache, 0)
commondb := make([]SCloudgroupcache, 0)
commonext := make([]cloudprovider.ICloudgroup, 0)
added := make([]cloudprovider.ICloudgroup, 0)
err = compare.CompareSets(dbCaches, iGroups, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(errors.Wrap(err, "compare.CompareSets"))
return result
}
for i := 0; i < len(removed); i++ {
if len(removed[i].ExternalId) > 0 { // 只删除云上已经删除过的组
err = removed[i].RealDelete(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
}
for i := 0; i < len(commondb); i++ {
err = commondb[i].syncWithCloudgrup(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i++ {
group, err := self.GetOrCreateCloudgroup(ctx, userCred, added[i])
if err != nil {
result.AddError(err)
continue
}
err = CloudgroupcacheManager.newFromCloudgroup(ctx, userCred, added[i], group, self.Id)
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func (self *SCloudaccount) GetOrCreateCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, iGroup cloudprovider.ICloudgroup) (*SCloudgroup, error) {
groups, err := self.GetCloudgroups()
if err != nil {
return nil, errors.Wrap(err, "GetCloudgroups")
}
iPolicies, err := iGroup.GetISystemCloudpolicies()
if err != nil {
return nil, errors.Wrap(err, "GetICloudpolicies")
}
for i := range groups {
isEqual, err := groups[i].IsEqual(iPolicies)
if err != nil {
return nil, errors.Wrap(err, "IsEqual")
}
if isEqual {
return &groups[i], nil
}
}
group, err := CloudgroupManager.newCloudgroup(ctx, userCred, iGroup, self.Provider, self.DomainId)
if err != nil {
return nil, errors.Wrap(err, "newCloudgroup")
}
for i := range iPolicies {
err = group.attachPolicyFromCloudpolicy(ctx, userCred, iPolicies[i])
if err != nil {
return nil, errors.Wrap(err, "attachPolicyFromCloudpolicy")
}
}
return group, nil
}

View File

@@ -0,0 +1,105 @@
// 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 models
import (
"context"
"database/sql"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/reflectutils"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SCloudaccountResourceBaseManager struct {
}
type SCloudaccountResourceBase struct {
// 云账号Id
CloudaccountId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" json:"cloudaccount_id"`
}
func (manager *SCloudaccountResourceBaseManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query api.CloudaccountResourceListInput) (*sqlchemy.SQuery, error) {
if len(query.Cloudaccount) > 0 {
account, err := CloudaccountManager.FetchByIdOrName(nil, query.Cloudaccount)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("cloudaccount", query.Cloudaccount)
}
return nil, httperrors.NewGeneralError(err)
}
q = q.Equals("cloudaccount_id", account.GetId())
}
if len(query.Provider) > 0 {
sq := CloudaccountManager.Query().SubQuery()
q = q.Join(sq, sqlchemy.Equals(q.Field("cloudaccount_id"), sq.Field("id"))).Filter(sqlchemy.In(sq.Field("provider"), query.Provider))
}
return q, nil
}
func (manager *SCloudaccountResourceBaseManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.CloudaccountResourceDetails {
rows := make([]api.CloudaccountResourceDetails, len(objs))
accountIds := make([]string, len(objs))
for i := range objs {
var base *SCloudaccountResourceBase
err := reflectutils.FindAnonymouStructPointer(objs[i], &base)
if err != nil {
log.Errorf("Cannot find SCloudaccountResourceBase in %#v: %s", objs[i], err)
} else if base != nil && len(base.CloudaccountId) > 0 {
accountIds[i] = base.CloudaccountId
}
}
accounts := make(map[string]SCloudaccount)
err := db.FetchStandaloneObjectsByIds(CloudaccountManager, accountIds, &accounts)
if err != nil {
log.Errorf("FetchStandaloneObjectsByIds fail %v", err)
return rows
}
for i := range rows {
if account, ok := accounts[accountIds[i]]; ok {
rows[i].Cloudaccount = account.Name
rows[i].Provider = account.Provider
rows[i].Brand = account.Brand
if len(rows[i].Brand) == 0 {
rows[i].Brand = account.Provider
}
rows[i].IamLoginUrl = account.IamLoginUrl
}
}
return rows
}
func (self *SCloudaccountResourceBase) GetCloudaccount() (*SCloudaccount, error) {
account, err := CloudaccountManager.FetchById(self.CloudaccountId)
if err != nil {
return nil, errors.Wrap(err, "CloudaccountManager.FetchById")
}
return account.(*SCloudaccount), nil
}

View File

@@ -0,0 +1,774 @@
// 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 models
import (
"context"
"database/sql"
"gopkg.in/fatih/set.v0"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/logclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SCloudgroupManager struct {
db.SStatusInfrasResourceBaseManager
}
var CloudgroupManager *SCloudgroupManager
func init() {
CloudgroupManager = &SCloudgroupManager{
SStatusInfrasResourceBaseManager: db.NewStatusInfrasResourceBaseManager(
SCloudgroup{},
"cloudgroups_tbl",
"cloudgroup",
"cloudgroups",
),
}
CloudgroupManager.SetVirtualObject(CloudgroupManager)
}
type SCloudgroup struct {
db.SStatusInfrasResourceBase
Provider string `width:"64" charset:"ascii" list:"domain" create:"required"`
}
func (manager *SCloudgroupManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return db.IsDomainAllowList(userCred, manager)
}
// 权限组列表
func (manager *SCloudgroupManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query api.CloudgroupListInput) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
if err != nil {
return nil, err
}
if len(query.Provider) > 0 {
q = q.In("provider", query.Provider)
}
if len(query.ClouduserId) > 0 {
_, err = ClouduserManager.FetchById(query.ClouduserId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("clouduser", query.ClouduserId)
}
return q, httperrors.NewGeneralError(errors.Wrap(err, "ClouduserManager.FetchById"))
}
sq := CloudgroupUserManager.Query("cloudgroup_id").Equals("clouduser_id", query.ClouduserId)
q = q.In("id", sq.SubQuery())
}
if len(query.CloudpolicyId) > 0 {
_, err = CloudpolicyManager.FetchById(query.CloudpolicyId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("cloudpolicy", query.CloudpolicyId)
}
return q, httperrors.NewGeneralError(errors.Wrap(err, "CloudpolicyManager.FetchById"))
}
sq := CloudgroupPolicyManager.Query("cloudgroup_id").Equals("cloudpolicy_id", query.CloudpolicyId)
q = q.In("id", sq.SubQuery())
}
return q, nil
}
func (manager *SCloudgroupManager) FetchParentId(ctx context.Context, data jsonutils.JSONObject) string {
provider, _ := data.GetString("provider")
return provider
}
func (manager *SCloudgroupManager) FilterByParentId(q *sqlchemy.SQuery, parentId string) *sqlchemy.SQuery {
if len(parentId) > 0 {
return q.Equals("provider", parentId)
}
return q
}
// 更新权限组
func (self *SCloudgroup) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupUpdateInput) (api.CloudgroupUpdateInput, error) {
return input, nil
}
// 获取权限组详情
func (self *SCloudgroup) GetExtraDetails(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
isList bool,
) (api.CloudgroupDetails, error) {
return api.CloudgroupDetails{}, nil
}
func (manager *SCloudgroupManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.CloudgroupDetails {
rows := make([]api.CloudgroupDetails, len(objs))
statusRows := manager.SStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.CloudgroupDetails{
StatusInfrasResourceBaseDetails: statusRows[i],
Cloudpolicies: []api.SCloudIdBaseResource{},
}
group := objs[i].(*SCloudgroup)
rows[i].CloudgroupcacheCount, _ = group.GetCloudgroupcacheCount()
policies, _ := group.GetCloudpolicies()
for _, policy := range policies {
rows[i].Cloudpolicies = append(rows[i].Cloudpolicies, api.SCloudIdBaseResource{Id: policy.Id, Name: policy.Name})
}
rows[i].CloudgroupcacheCount = len(policies)
users, _ := group.GetCloudusers()
for _, user := range users {
rows[i].Cloudusers = append(rows[i].Cloudusers, api.SCloudIdBaseResource{Id: user.Id, Name: user.Name})
}
rows[i].ClouduserCount = len(users)
}
return rows
}
// 创建权限组
func (manager *SCloudgroupManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.CloudgroupCreateInput) (api.CloudgroupCreateInput, error) {
if len(input.Provider) == 0 {
return input, httperrors.NewMissingParameterError("provider")
}
factory, err := cloudprovider.GetProviderFactory(input.Provider)
if err != nil {
return input, errors.Wrap(err, "cloudprovider.GetProviderFactory")
}
if !factory.IsSupportClouduser() {
return input, httperrors.NewUnsupportOperationError("Unsupport cloudgroup for %s", input.Provider)
}
for _, cloudpolicyId := range input.CloudpolicyIds {
_policy, err := CloudpolicyManager.FetchById(cloudpolicyId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return input, httperrors.NewResourceNotFoundError2("cloudpolicy", cloudpolicyId)
}
return input, httperrors.NewGeneralError(err)
}
policy := _policy.(*SCloudpolicy)
if policy.Provider != input.Provider {
return input, httperrors.NewConflictError("cloudpolicy %s(%s) and cloudgroup not with same provider", policy.Name, policy.Id)
}
}
input.Status = api.CLOUD_GROUP_STATUS_AVAILABLE
return input, nil
}
func (self *SCloudgroup) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
input := api.CloudgroupCreateInput{}
data.Unmarshal(&input)
for _, policyId := range input.CloudpolicyIds {
self.attachPolicy(policyId)
}
}
func (manager *SCloudgroupManager) newCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, iGroup cloudprovider.ICloudgroup, provider, domainId string) (*SCloudgroup, error) {
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
group := &SCloudgroup{}
group.Name = iGroup.GetName()
group.Description = iGroup.GetDescription()
group.Provider = provider
group.DomainId = domainId
group.Status = api.CLOUD_GROUP_STATUS_AVAILABLE
group.SetModelManager(manager, group)
err := manager.TableSpec().Insert(ctx, group)
if err != nil {
return nil, errors.Wrap(err, "Insert")
}
return group, nil
}
// 删除权限组
func (self *SCloudgroup) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
params := jsonutils.NewDict()
return self.StartCloudgroupDeleteTask(ctx, userCred, params, "")
}
func (self *SCloudgroup) StartCloudgroupDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "CloudgroupDeleteTask", self, userCred, data, parentTaskId, "", nil)
if err != nil {
return errors.Wrap(err, "NewTask")
}
self.SetStatus(userCred, api.CLOUD_GROUP_STATUS_DELETING, "")
task.ScheduleRun(nil)
return nil
}
func (self *SCloudgroup) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SCloudgroup) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
err := self.removePolicies()
if err != nil {
return errors.Wrap(err, "removePolicies")
}
err = self.removeUsers()
if err != nil {
return errors.Wrap(err, "remoteUsers")
}
return self.SStatusInfrasResourceBase.Delete(ctx, userCred)
}
func (self *SCloudgroup) removeUsers() error {
users, err := self.GetCloudusers()
if err != nil {
return errors.Wrap(err, "GetCloudusers")
}
for i := range users {
err = self.removeUser(users[i].Id)
if err != nil {
return errors.Wrapf(err, "removeUser(%s)", users[i].Id)
}
}
return nil
}
func (self *SCloudgroup) removePolicies() error {
policies, err := self.GetCloudpolicies()
if err != nil {
return errors.Wrap(err, "GetCloudpolicies")
}
for i := range policies {
err = self.detachPolicy(policies[i].Id)
if err != nil {
return errors.Wrapf(err, "detachPolicy(%s)", policies[i].Id)
}
}
return nil
}
func (self *SCloudgroup) GetCloudpolicyQuery() *sqlchemy.SQuery {
q := CloudpolicyManager.Query()
sq := CloudgroupPolicyManager.Query().SubQuery()
return q.Join(sq, sqlchemy.Equals(q.Field("id"), sq.Field("cloudpolicy_id"))).Filter(sqlchemy.Equals(sq.Field("cloudgroup_id"), self.Id))
}
func (self *SCloudgroup) GetCloudpolicyCount() (int, error) {
return self.GetCloudpolicyQuery().CountWithError()
}
func (self *SCloudgroup) GetCloudgroupcacheQuery() *sqlchemy.SQuery {
return CloudgroupcacheManager.Query().Equals("cloudgroup_id", self.Id)
}
func (self *SCloudgroup) GetCloudgroupcacheCount() (int, error) {
return self.GetCloudgroupcacheQuery().CountWithError()
}
func (self *SCloudgroup) GetCloudgroupcaches() ([]SCloudgroupcache, error) {
caches := []SCloudgroupcache{}
q := self.GetCloudgroupcacheQuery()
err := db.FetchModelObjects(CloudgroupcacheManager, q, &caches)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
return caches, nil
}
func (self *SCloudgroup) GetCloudpolicies() ([]SCloudpolicy, error) {
policies := []SCloudpolicy{}
q := self.GetCloudpolicyQuery()
err := db.FetchModelObjects(CloudpolicyManager, q, &policies)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
return policies, nil
}
func (self *SCloudgroup) GetCloudpolicy(policyId string) (*SCloudpolicy, error) {
policies := []SCloudpolicy{}
q := self.GetCloudpolicyQuery().Equals("id", policyId)
err := db.FetchModelObjects(CloudpolicyManager, q, &policies)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
if len(policies) > 1 {
return nil, sqlchemy.ErrDuplicateEntry
}
if len(policies) == 0 {
return nil, sql.ErrNoRows
}
return &policies[0], nil
}
func (self *SCloudgroup) detachPolicy(policyId string) error {
policies := []SCloudgroupPolicy{}
q := CloudgroupPolicyManager.Query().Equals("cloudgroup_id", self.Id).Equals("cloudpolicy_id", policyId)
err := db.FetchModelObjects(CloudgroupPolicyManager, q, &policies)
if err != nil {
return errors.Wrap(err, "db.FetchModelObjects")
}
for i := range policies {
err = policies[i].Delete(context.Background(), nil)
if err != nil {
return errors.Wrap(err, "Delete")
}
}
return nil
}
func (self *SCloudgroup) GetClouduserQuery() *sqlchemy.SQuery {
q := ClouduserManager.Query()
sq := CloudgroupUserManager.Query().SubQuery()
return q.Join(sq, sqlchemy.Equals(q.Field("id"), sq.Field("clouduser_id"))).Filter(sqlchemy.Equals(sq.Field("cloudgroup_id"), self.Id))
}
func (self *SCloudgroup) GetClouduserCount() (int, error) {
return self.GetClouduserQuery().CountWithError()
}
func (self *SCloudgroup) GetClouduser(userId string) (*SClouduser, error) {
users := []SClouduser{}
q := self.GetClouduserQuery().Equals("id", userId)
err := db.FetchModelObjects(ClouduserManager, q, &users)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
if len(users) > 1 {
return nil, sqlchemy.ErrDuplicateEntry
}
if len(users) == 0 {
return nil, sql.ErrNoRows
}
return &users[0], nil
}
func (self *SCloudgroup) GetCloudusers() ([]SClouduser, error) {
users := []SClouduser{}
q := self.GetClouduserQuery()
err := db.FetchModelObjects(ClouduserManager, q, &users)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
return users, nil
}
func (self *SCloudgroup) removeUser(userId string) error {
users := []SCloudgroupUser{}
q := CloudgroupUserManager.Query().Equals("cloudgroup_id", self.Id).Equals("clouduser_id", userId)
err := db.FetchModelObjects(CloudgroupUserManager, q, &users)
if err != nil {
return errors.Wrap(err, "db.FetchModelObjects")
}
for i := range users {
err = users[i].Delete(context.Background(), nil)
if err != nil {
return errors.Wrap(err, "Delete")
}
}
return nil
}
func (self *SCloudgroup) GetProviderFactory() (cloudprovider.ICloudProviderFactory, error) {
return cloudprovider.GetProviderFactory(self.Provider)
}
func (self *SCloudgroup) AllowPerformAddUser(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsDomainAllowPerform(userCred, self, "add-user")
}
// 向权限组加入用户
// 权限组状态必须为: available
func (self *SCloudgroup) PerformAddUser(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupAddUserInput) (jsonutils.JSONObject, error) {
if len(input.ClouduserId) == 0 {
return nil, httperrors.NewMissingParameterError("clouduser_id")
}
_user, err := ClouduserManager.FetchById(input.ClouduserId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("clouduser", input.ClouduserId)
}
return nil, httperrors.NewGeneralError(err)
}
user := _user.(*SClouduser)
account, err := user.GetCloudaccount()
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
if account.Provider != self.Provider {
return nil, httperrors.NewDuplicateResourceError("group and user not with same provider")
}
_, err = self.GetClouduser(input.ClouduserId)
if err == nil || errors.Cause(err) == sqlchemy.ErrDuplicateEntry {
return nil, httperrors.NewDuplicateResourceError("user %s has aleady in this group", input.ClouduserId)
}
err = self.addUser(input.ClouduserId)
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrap(err, "addUser"))
}
logclient.AddSimpleActionLog(self, logclient.ACT_ADD_USER, user, userCred, true)
logclient.AddSimpleActionLog(user, logclient.ACT_ADD_USER, self, userCred, true)
return nil, self.StartCloudgroupSyncUsersTask(ctx, userCred, "")
}
func (self *SCloudgroup) StartCloudgroupSyncUsersTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "CloudgroupSyncUsersTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrap(err, "NewTask")
}
self.SetStatus(userCred, api.CLOUD_GROUP_STATUS_SYNC_USERS, "")
task.ScheduleRun(nil)
return nil
}
func (self *SCloudgroup) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsDomainAllowPerform(userCred, self, "syncstatus")
}
// 同步权限组状态
func (self *SCloudgroup) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupSyncstatusInput) (jsonutils.JSONObject, error) {
self.SetStatus(userCred, api.CLOUD_USER_STATUS_AVAILABLE, "syncstatus")
return nil, nil
}
func (self *SCloudgroup) AllowPerformRemoveUser(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsDomainAllowPerform(userCred, self, "remove-user")
}
// 从权限组移除用户
// 权限组状态必须为: available
func (self *SCloudgroup) PerformRemoveUser(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupRemoveUserInput) (jsonutils.JSONObject, error) {
if self.Status != api.CLOUD_GROUP_STATUS_AVAILABLE {
return nil, httperrors.NewInvalidStatusError("Can not remove user in status %s", self.Status)
}
if len(input.ClouduserId) == 0 {
return nil, httperrors.NewMissingParameterError("clouduser_id")
}
_user, err := ClouduserManager.FetchById(input.ClouduserId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("clouduser", input.ClouduserId)
}
return nil, httperrors.NewGeneralError(err)
}
user := _user.(*SClouduser)
_, err = self.GetClouduser(input.ClouduserId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, nil
}
return nil, httperrors.NewGeneralError(err)
}
err = self.removeUser(input.ClouduserId)
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrap(err, "RemoveUser"))
}
logclient.AddSimpleActionLog(self, logclient.ACT_REMOVE_USER, user, userCred, true)
logclient.AddSimpleActionLog(user, logclient.ACT_REMOVE_USER, self, userCred, true)
return nil, self.StartCloudgroupSyncUsersTask(ctx, userCred, "")
}
func (self *SCloudgroup) addUser(userId string) error {
gu := &SCloudgroupUser{}
gu.SetModelManager(CloudgroupUserManager, gu)
gu.ClouduserId = userId
gu.CloudgroupId = self.Id
return CloudgroupUserManager.TableSpec().Insert(context.Background(), gu)
}
func (self *SCloudgroup) AllowPerformSetUsers(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsDomainAllowPerform(userCred, self, "set-users")
}
// 设置权限组用户(全量覆盖)
// 权限组状态必须为: available
func (self *SCloudgroup) PerformSetUsers(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupSetUsersInput) (jsonutils.JSONObject, error) {
if self.Status != api.CLOUD_GROUP_STATUS_AVAILABLE {
return nil, httperrors.NewInvalidStatusError("Can not set users in status %s", self.Status)
}
users, err := self.GetCloudusers()
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
userMaps := map[string]*SClouduser{}
local := set.New(set.ThreadSafe)
for i := range users {
local.Add(users[i].Id)
userMaps[users[i].Id] = &users[i]
}
newU := set.New(set.ThreadSafe)
for _, userId := range input.ClouduserIds {
_user, err := ClouduserManager.FetchById(userId)
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
return nil, httperrors.NewResourceNotFoundError2("clouduser", userId)
}
return nil, httperrors.NewGeneralError(err)
}
user := _user.(*SClouduser)
account, err := user.GetCloudaccount()
if err != nil {
return nil, errors.Wrap(err, "user.GetCloudaccount")
}
if account.Provider != self.Provider {
return nil, httperrors.NewConflictError("user %s(%s) and group not with same provider", user.Name, user.Id)
}
newU.Add(userId)
userMaps[user.Id] = user
}
for _, del := range set.Difference(local, newU).List() {
id := del.(string)
user, ok := userMaps[id]
if ok {
err = self.removeUser(id)
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrap(err, "removeUser"))
}
logclient.AddSimpleActionLog(self, logclient.ACT_REMOVE_USER, user, userCred, true)
logclient.AddSimpleActionLog(user, logclient.ACT_REMOVE_USER, self, userCred, true)
}
}
for _, add := range set.Difference(newU, local).List() {
id := add.(string)
user, ok := userMaps[id]
if ok {
err = self.addUser(id)
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrap(err, "addUser"))
}
logclient.AddSimpleActionLog(self, logclient.ACT_ADD_USER, user, userCred, true)
logclient.AddSimpleActionLog(user, logclient.ACT_ADD_USER, self, userCred, true)
}
}
return nil, self.StartCloudgroupSyncUsersTask(ctx, userCred, "")
}
func (self *SCloudgroup) AllowPerformSetPolicies(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsDomainAllowPerform(userCred, self, "set-policies")
}
// 设置权限组添权限(全量覆盖)
// 权限组状态必须为: available
func (self *SCloudgroup) PerformSetPolicies(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupSetPoliciesInput) (jsonutils.JSONObject, error) {
if self.Status != api.CLOUD_GROUP_STATUS_AVAILABLE {
return nil, httperrors.NewInvalidStatusError("Can not set policies in status %s", self.Status)
}
policies, err := self.GetCloudpolicies()
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
policyMaps := map[string]*SCloudpolicy{}
local := set.New(set.ThreadSafe)
for i := range policies {
local.Add(policies[i].Id)
policyMaps[policies[i].Id] = &policies[i]
}
newP := set.New(set.ThreadSafe)
for _, policyId := range input.CloudpolicyIds {
_policy, err := CloudpolicyManager.FetchById(policyId)
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
return nil, httperrors.NewResourceNotFoundError2("cloudpolicy", policyId)
}
return nil, httperrors.NewGeneralError(err)
}
policy := _policy.(*SCloudpolicy)
if policy.Provider != self.Provider {
return nil, httperrors.NewConflictError("policy %s(%s) and group not with same provider", policy.Name, policy.Id)
}
newP.Add(policyId)
policyMaps[policyId] = policy
}
for _, del := range set.Difference(local, newP).List() {
id := del.(string)
policy, ok := policyMaps[id]
if ok {
err = self.detachPolicy(id)
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrap(err, "detachPolicy"))
}
logclient.AddSimpleActionLog(self, logclient.ACT_DETACH_POLICY, policy, userCred, true)
}
}
for _, add := range set.Difference(newP, local).List() {
id := add.(string)
policy, ok := policyMaps[id]
if ok {
err = self.attachPolicy(id)
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrap(err, "attachPolicy"))
}
logclient.AddSimpleActionLog(self, logclient.ACT_ATTACH_POLICY, policy, userCred, true)
}
}
return nil, self.StartCloudgroupSyncPoliciesTask(ctx, userCred, "")
}
func (self *SCloudgroup) StartCloudgroupSyncPoliciesTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "CloudgroupSyncPoliciesTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrap(err, "NewTask")
}
self.SetStatus(userCred, api.CLOUD_GROUP_STATUS_SYNC_POLICIES, "")
task.ScheduleRun(nil)
return nil
}
func (self *SCloudgroup) AllowPerformAttachPolicy(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsDomainAllowPerform(userCred, self, "attach-policy")
}
// 向权限组添加权限
// 权限组状态必须为: available
func (self *SCloudgroup) PerformAttachPolicy(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupAttachPolicyInput) (jsonutils.JSONObject, error) {
if self.Status != api.CLOUD_GROUP_STATUS_AVAILABLE {
return nil, httperrors.NewInvalidStatusError("Can not attach policy in status %s", self.Status)
}
if len(input.CloudpolicyId) == 0 {
return nil, httperrors.NewMissingParameterError("cloudpolicy_id")
}
_policy, err := CloudpolicyManager.FetchById(input.CloudpolicyId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("cloudpolicy", input.CloudpolicyId)
}
return nil, httperrors.NewGeneralError(err)
}
policy := _policy.(*SCloudpolicy)
if policy.Provider != self.Provider {
return nil, httperrors.NewDuplicateResourceError("group and policy not with same provider")
}
_, err = self.GetCloudpolicy(input.CloudpolicyId)
if err == nil || errors.Cause(err) == sqlchemy.ErrDuplicateEntry {
return nil, httperrors.NewDuplicateResourceError("policy %s has aleady in this group", input.CloudpolicyId)
}
err = self.attachPolicy(input.CloudpolicyId)
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrap(err, "attachPolicy"))
}
logclient.AddSimpleActionLog(self, logclient.ACT_ATTACH_POLICY, policy, userCred, true)
return nil, self.StartCloudgroupSyncPoliciesTask(ctx, userCred, "")
}
func (self *SCloudgroup) AllowPerformDetachPolicy(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsDomainAllowPerform(userCred, self, "detach-policy")
}
// 从权限组移除权限
// 权限组状态必须为: available
func (self *SCloudgroup) PerformDetachPolicy(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupDetachPolicyInput) (jsonutils.JSONObject, error) {
if self.Status != api.CLOUD_GROUP_STATUS_AVAILABLE {
return nil, httperrors.NewInvalidStatusError("Can not detach policy in status %s", self.Status)
}
if len(input.CloudpolicyId) == 0 {
return nil, httperrors.NewMissingParameterError("cloudpolicy_id")
}
_policy, err := CloudpolicyManager.FetchById(input.CloudpolicyId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("cloudpolicy", input.CloudpolicyId)
}
return nil, httperrors.NewGeneralError(err)
}
policy := _policy.(*SCloudpolicy)
_, err = self.GetCloudpolicy(input.CloudpolicyId)
if err != nil && errors.Cause(err) == sql.ErrNoRows {
return nil, nil
}
err = self.detachPolicy(input.CloudpolicyId)
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrap(err, "detachPolicy"))
}
logclient.AddSimpleActionLog(self, logclient.ACT_DETACH_POLICY, policy, userCred, true)
return nil, self.StartCloudgroupSyncPoliciesTask(ctx, userCred, "")
}
func (self *SCloudgroup) attachPolicy(policyId string) error {
gp := &SCloudgroupPolicy{}
gp.SetModelManager(CloudgroupPolicyManager, gp)
gp.CloudpolicyId = policyId
gp.CloudgroupId = self.Id
return CloudgroupPolicyManager.TableSpec().Insert(context.Background(), gp)
}
func (self *SCloudgroup) IsEqual(iPolicies []cloudprovider.ICloudpolicy) (bool, error) {
dbPolicies, err := self.GetCloudpolicies()
if err != nil {
return false, errors.Wrap(err, "GetCloudpolicies")
}
removed := make([]SCloudpolicy, 0)
commondb := make([]SCloudpolicy, 0)
commonext := make([]cloudprovider.ICloudpolicy, 0)
added := make([]cloudprovider.ICloudpolicy, 0)
err = compare.CompareSets(dbPolicies, iPolicies, &removed, &commondb, &commonext, &added)
if err != nil {
return false, errors.Wrap(err, "CompareSets")
}
return len(iPolicies) == len(commondb), nil
}
func (self *SCloudgroup) attachPolicyFromCloudpolicy(ctx context.Context, userCred mcclient.TokenCredential, iPolicy cloudprovider.ICloudpolicy) error {
up := &SCloudgroupPolicy{}
up.SetModelManager(CloudgroupPolicyManager, up)
up.CloudgroupId = self.Id
p, err := db.FetchByExternalId(CloudgroupPolicyManager, iPolicy.GetGlobalId())
if err != nil {
return errors.Wrapf(err, "db.FetchByExternalId(%s)", iPolicy.GetGlobalId())
}
up.CloudpolicyId = p.GetId()
return CloudgroupPolicyManager.TableSpec().Insert(ctx, up)
}

View File

@@ -0,0 +1,187 @@
// 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 models
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
// +onecloud:swagger-gen-ignore
type SCloudgroupPolicyManager struct {
SCloudgroupJointsManager
SCloudpolicyResourceBaseManager
}
var CloudgroupPolicyManager *SCloudgroupPolicyManager
func init() {
db.InitManager(func() {
CloudgroupPolicyManager = &SCloudgroupPolicyManager{
SCloudgroupJointsManager: NewCloudgroupJointsManager(
SCloudgroupPolicy{},
"cloudgroup_policies_tbl",
"cloudgroup_policy",
"cloudgroup_policies",
CloudpolicyManager,
),
}
CloudgroupPolicyManager.SetVirtualObject(CloudgroupPolicyManager)
CloudgroupPolicyManager.TableSpec().AddIndex(true, "cloudgroup_id", "cloudpolicy_id")
})
}
type SCloudgroupPolicy struct {
SCloudgroupJointsBase
SCloudpolicyResourceBase
}
func (manager *SCloudgroupPolicyManager) GetSlaveFieldName() string {
return "cloudpolicy_id"
}
func (manager *SCloudgroupPolicyManager) AllowCreateItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return false
}
func (self *SCloudgroupPolicy) AllowDeleteItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return false
}
// +onecloud:swagger-gen-ignore
func (manager *SCloudgroupPolicyManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return nil, httperrors.NewNotSupportedError("Not Supported")
}
// +onecloud:swagger-gen-ignore
func (self *SCloudgroupPolicy) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.SCloudgroupJointsBase.CustomizeDelete(ctx, userCred, query, data)
}
// +onecloud:swagger-gen-ignore
func (self *SCloudgroupPolicy) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return nil, httperrors.NewNotSupportedError("Not Supported")
}
func (joint *SCloudgroupPolicy) Master() db.IStandaloneModel {
return db.JointMaster(joint)
}
func (joint *SCloudgroupPolicy) Slave() db.IStandaloneModel {
return db.JointSlave(joint)
}
// 用户组中权限详情
func (self *SCloudgroupPolicy) GetExtraDetails(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
isList bool,
) (api.CloudgroupPolicyDetails, error) {
return api.CloudgroupPolicyDetails{}, nil
}
func (manager *SCloudgroupPolicyManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.CloudgroupPolicyDetails {
rows := make([]api.CloudgroupPolicyDetails, len(objs))
groupRows := manager.SCloudgroupJointsManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
policyRows := manager.SCloudpolicyResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.CloudgroupPolicyDetails{
CloudgroupJointResourceDetails: groupRows[i],
CloudpolicyResourceDetails: policyRows[i],
}
}
return rows
}
func (self *SCloudgroupPolicy) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DeleteModel(ctx, userCred, self)
}
func (self *SCloudgroupPolicy) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DetachJoint(ctx, userCred, self)
}
// 用户组中权限列表
func (manager *SCloudgroupPolicyManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.CloudgroupPolicyListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SCloudgroupJointsManager.ListItemFilter(ctx, q, userCred, query.CloudgroupJointsListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudgroupJointsManager.ListItemFilter")
}
q, err = manager.SCloudpolicyResourceBaseManager.ListItemFilter(ctx, q, userCred, query.CloudpolicyResourceListInput)
if err != nil {
return nil, err
}
return q, nil
}
func (manager *SCloudgroupPolicyManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.CloudgroupPolicyListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SCloudgroupJointsManager.OrderByExtraFields(ctx, q, userCred, query.CloudgroupJointsListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudgroupJointsManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SCloudgroupPolicyManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SCloudgroupJointsManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SCloudgroupJointsManager.ListItemExportKeys")
}
return q, nil
}

View File

@@ -0,0 +1,204 @@
// 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 models
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
// +onecloud:swagger-gen-ignore
type SCloudgroupUserManager struct {
SCloudgroupJointsManager
SClouduserResourceBaseManager
}
var CloudgroupUserManager *SCloudgroupUserManager
func init() {
db.InitManager(func() {
CloudgroupUserManager = &SCloudgroupUserManager{
SCloudgroupJointsManager: NewCloudgroupJointsManager(
SCloudgroupUser{},
"cloudgroup_users_tbl",
"cloudgroup_user",
"cloudgroup_users",
ClouduserManager,
),
}
CloudgroupUserManager.SetVirtualObject(CloudgroupUserManager)
CloudgroupUserManager.TableSpec().AddIndex(true, "cloudgroup_id", "clouduser_id")
})
}
type SCloudgroupUser struct {
SCloudgroupJointsBase
SClouduserResourceBase
}
func (manager *SCloudgroupUserManager) GetSlaveFieldName() string {
return "clouduser_id"
}
func (manager *SCloudgroupUserManager) AllowCreateItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return false
}
func (self *SCloudgroupUser) AllowDeleteItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return false
}
// +onecloud:swagger-gen-ignore
func (manager *SCloudgroupUserManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return nil, httperrors.NewNotSupportedError("Not Supported")
}
// +onecloud:swagger-gen-ignore
func (self *SCloudgroupUser) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.SCloudgroupJointsBase.CustomizeDelete(ctx, userCred, query, data)
}
// +onecloud:swagger-gen-ignore
func (self *SCloudgroupUser) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return nil, httperrors.NewNotSupportedError("Not Supported")
}
func (joint *SCloudgroupUser) Master() db.IStandaloneModel {
return db.JointMaster(joint)
}
func (joint *SCloudgroupUser) Slave() db.IStandaloneModel {
return db.JointSlave(joint)
}
// 获取用户组中用户详情
func (self *SCloudgroupUser) GetExtraDetails(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
isList bool,
) (api.CloudgroupUserDetails, error) {
return api.CloudgroupUserDetails{}, nil
}
func (manager *SCloudgroupUserManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.CloudgroupUserDetails {
rows := make([]api.CloudgroupUserDetails, len(objs))
groupRows := manager.SCloudgroupJointsManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
userRows := manager.SClouduserResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.CloudgroupUserDetails{
CloudgroupJointResourceDetails: groupRows[i],
ClouduserResourceDetails: userRows[i],
}
}
return rows
}
func (self *SCloudgroupUser) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DeleteModel(ctx, userCred, self)
}
func (self *SCloudgroupUser) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DetachJoint(ctx, userCred, self)
}
// 用户组中用户列表
func (manager *SCloudgroupUserManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.CloudgroupUserListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SCloudgroupJointsManager.ListItemFilter(ctx, q, userCred, query.CloudgroupJointsListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudgroupJointsManager.ListItemFilter")
}
q, err = manager.SClouduserResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ClouduserResourceListInput)
if err != nil {
return nil, err
}
return q, nil
}
func (manager *SCloudgroupUserManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.CloudgroupUserListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SCloudgroupJointsManager.OrderByExtraFields(ctx, q, userCred, query.CloudgroupJointsListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudgroupJointsManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SCloudgroupUserManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SCloudgroupJointsManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SCloudgroupJointsManager.ListItemExportKeys")
}
return q, nil
}
/*
func (manager *SCloudgroupUserManager) newFromCloudgroupUser(ctx context.Context, userCred mcclient.TokenCredential, iUser cloudprovider.IClouduser, group *SCloudgroup) error {
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
user := SCloudgroupUser{}
user.SetModelManager(manager, &user)
user.CloudgroupId = group.Id
u, err := group.GetClouduserByExternalId(iUser.GetGlobalId())
if err != nil {
return errors.Wrapf(err, "GetClouduserByExternalId(%s)", iUser.GetGlobalId())
}
user.ClouduserId = u.GetId()
return manager.TableSpec().Insert(&user)
}*/

View File

@@ -0,0 +1,408 @@
// 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 models
import (
"context"
"database/sql"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/logclient"
"yunion.io/x/onecloud/pkg/util/rand"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SCloudgroupcacheManager struct {
db.SStatusStandaloneResourceBaseManager
db.SExternalizedResourceBaseManager
SCloudaccountResourceBaseManager
}
var CloudgroupcacheManager *SCloudgroupcacheManager
func init() {
CloudgroupcacheManager = &SCloudgroupcacheManager{
SStatusStandaloneResourceBaseManager: db.NewStatusStandaloneResourceBaseManager(
SCloudgroupcache{},
"cloudgroupcaches_tbl",
"cloudgroupcache",
"cloudgroupcaches",
),
}
CloudgroupcacheManager.SetVirtualObject(CloudgroupcacheManager)
}
type SCloudgroupcache struct {
db.SStatusStandaloneResourceBase
db.SExternalizedResourceBase
SCloudaccountResourceBase
// 用户组Id
CloudgroupId string `width:"36" charset:"ascii" nullable:"true" list:"user" index:"true" json:"cloudgroup_id"`
}
func (manager *SCloudgroupcacheManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return db.IsDomainAllowList(userCred, manager)
}
// 公有云权限组缓存
func (manager *SCloudgroupcacheManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query api.CloudgroupcacheListInput) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, err
}
q, err = manager.SCloudaccountResourceBaseManager.ListItemFilter(ctx, q, userCred, query.CloudaccountResourceListInput)
if err != nil {
return nil, err
}
if len(query.CloudgroupId) > 0 {
_, err = CloudgroupManager.FetchById(query.CloudgroupId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("cloudgroup", query.CloudgroupId)
}
return q, httperrors.NewGeneralError(errors.Wrap(err, "CloudgroupManager.FetchById"))
}
q = q.Equals("cloudgroup_id", query.CloudgroupId)
}
return q, nil
}
// +onecloud:swagger-gen-ignore
func (self *SCloudgroupcache) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupUpdateInput) (api.CloudgroupUpdateInput, error) {
return input, httperrors.NewNotSupportedError("Not support")
}
// +onecloud:swagger-gen-ignore
func (manager *SCloudgroupcacheManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.CloudgroupcacheCreateInput) (api.CloudgroupcacheCreateInput, error) {
return input, httperrors.NewNotSupportedError("Not support")
}
// 删除权限组缓存
func (self *SCloudgroupcache) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartCloudgroupcacheDeleteTask(ctx, userCred, "")
}
func (self *SCloudgroupcache) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SCloudgroupcache) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SStatusStandaloneResourceBase.Delete(ctx, userCred)
}
func (manager *SCloudgroupcacheManager) newFromCloudgroup(ctx context.Context, userCred mcclient.TokenCredential, iGroup cloudprovider.ICloudgroup, group *SCloudgroup, cloudaccountId string) error {
cache := &SCloudgroupcache{}
cache.SetModelManager(manager, cache)
cache.CloudgroupId = group.Id
cache.Name = iGroup.GetName()
cache.Description = iGroup.GetDescription()
cache.Status = api.CLOUD_GROUP_STATUS_AVAILABLE
cache.ExternalId = iGroup.GetGlobalId()
cache.CloudaccountId = cloudaccountId
return manager.TableSpec().Insert(ctx, cache)
}
func (self *SCloudgroupcache) syncWithCloudgrup(ctx context.Context, userCred mcclient.TokenCredential, iGroup cloudprovider.ICloudgroup) error {
_, err := db.Update(self, func() error {
self.Name = iGroup.GetName()
self.Description = iGroup.GetDescription()
self.Status = api.CLOUD_GROUP_STATUS_AVAILABLE
return nil
})
return err
}
func (manager *SCloudgroupcacheManager) Register(group *SCloudgroup, account *SCloudaccount) (*SCloudgroupcache, error) {
q := manager.Query().Equals("cloudgroup_id", group.Id).Equals("cloudaccount_id", account.Id)
count, err := q.CountWithError()
if err != nil {
return nil, errors.Wrap(err, "CountWithError")
}
if count > 1 {
return nil, sqlchemy.ErrDuplicateEntry
}
cache := &SCloudgroupcache{}
cache.SetModelManager(manager, cache)
if count < 1 {
cache.Name = group.Name
cache.Description = group.Description
cache.Status = api.CLOUD_GROUP_CACHE_STATUS_CREATING
cache.CloudgroupId = group.Id
cache.CloudaccountId = account.Id
return cache, manager.TableSpec().Insert(context.Background(), cache)
}
err = q.First(cache)
if err != nil {
return nil, errors.Wrap(err, "q.First")
}
return cache, nil
}
// 获取权限组缓存详情
func (self *SCloudgroupcache) GetExtraDetails(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
isList bool,
) (api.CloudgroupcacheDetails, error) {
return api.CloudgroupcacheDetails{}, nil
}
func (manager *SCloudgroupcacheManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.CloudgroupcacheDetails {
rows := make([]api.CloudgroupcacheDetails, len(objs))
statusRows := manager.SStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
acRows := manager.SCloudaccountResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.CloudgroupcacheDetails{
StatusStandaloneResourceDetails: statusRows[i],
CloudaccountResourceDetails: acRows[i],
}
}
return rows
}
func (self *SCloudgroupcache) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsDomainAllowPerform(userCred, self, "syncstatus")
}
// 同步权限组缓存状态
func (self *SCloudgroupcache) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudgroupSyncstatusInput) (jsonutils.JSONObject, error) {
return nil, self.StartCloudgroupcacheSyncstatusTask(ctx, userCred, "")
}
func (self *SCloudgroupcache) StartCloudgroupcacheSyncstatusTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "CloudgroupcacheSyncstatusTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrap(err, "NewTask")
}
self.SetStatus(userCred, api.CLOUD_GROUP_CACHE_STATUS_SYNC_STATUS, "")
task.ScheduleRun(nil)
return nil
}
func (self *SCloudgroupcache) StartCloudgroupcacheDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "CloudgroupcacheDeleteTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrap(err, "NewTask")
}
self.SetStatus(userCred, api.CLOUD_GROUP_STATUS_DELETING, "")
task.ScheduleRun(nil)
return nil
}
func (self *SCloudgroupcache) GetOrCreateICloudgroup(ctx context.Context, userCred mcclient.TokenCredential) (cloudprovider.ICloudgroup, error) {
lockman.LockObject(ctx, self)
defer lockman.ReleaseObject(ctx, self)
if len(self.ExternalId) > 0 {
iGroup, err := self.GetICloudgroup()
if err == nil {
return iGroup, nil
}
if errors.Cause(err) != cloudprovider.ErrNotFound {
return nil, errors.Wrap(err, "GetICloudgroup")
}
}
account, err := self.GetCloudaccount()
if err != nil {
return nil, errors.Wrap(err, "GetCloudaccount")
}
provider, err := account.GetProvider()
if err != nil {
return nil, errors.Wrap(err, "account.GetProvider")
}
randomString := func(prefix string, length int) string {
return fmt.Sprintf("%s-%s", prefix, rand.String(length))
}
groupName := self.Name
for i := 2; i < 30; i++ {
_, err := provider.GetICloudgroupByName(groupName)
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
break
}
return nil, errors.Wrapf(err, "GetICloudgroupByName(%s)", groupName)
}
groupName = randomString(self.Name, i)
}
iGroup, err := provider.CreateICloudgroup(groupName, self.Description)
if err != nil {
logclient.AddSimpleActionLog(self, logclient.ACT_CREATE, err, userCred, false)
return nil, errors.Wrap(err, "CreateICloudgroup")
}
_, err = db.Update(self, func() error {
self.ExternalId = iGroup.GetGlobalId()
self.Status = api.CLOUD_GROUP_STATUS_AVAILABLE
return nil
})
return iGroup, err
}
func (self *SCloudgroupcache) GetCloudgroup() (*SCloudgroup, error) {
group, err := CloudgroupManager.FetchById(self.CloudgroupId)
if err != nil {
return nil, errors.Wrapf(err, "FetchById(%s)", self.CloudgroupId)
}
return group.(*SCloudgroup), nil
}
func (self *SCloudgroupcache) GetICloudgroup() (cloudprovider.ICloudgroup, error) {
account, err := self.GetCloudaccount()
if err != nil {
return nil, errors.Wrap(err, "self.GetCloudaccount")
}
provider, err := account.GetProvider()
if err != nil {
return nil, errors.Wrap(err, "account.GetProvider")
}
return provider.GetICloudgroupByName(self.Name)
}
// 将本地的权限推送到云上(覆盖云上设置)
func (self *SCloudgroupcache) SyncCloudpoliciesForCloud(ctx context.Context) (result compare.SyncResult, err error) {
lockman.LockObject(ctx, self)
defer lockman.ReleaseObject(ctx, self)
iGroup, err := self.GetICloudgroup()
if err != nil {
return result, errors.Wrap(err, "GetICloudgroup")
}
iPolicies, err := iGroup.GetISystemCloudpolicies()
if err != nil {
return result, errors.Wrap(err, "GetISystemCloudpolicies")
}
group, err := self.GetCloudgroup()
if err != nil {
return result, errors.Wrap(err, "GetCloudgroup")
}
dbPolicies, err := group.GetCloudpolicies()
if err != nil {
return result, errors.Wrap(err, "GetCloudpolicies")
}
added := make([]SCloudpolicy, 0)
commondb := make([]SCloudpolicy, 0)
commonext := make([]cloudprovider.ICloudpolicy, 0)
removed := make([]cloudprovider.ICloudpolicy, 0)
err = compare.CompareSets(dbPolicies, iPolicies, &added, &commondb, &commonext, &removed)
if err != nil {
return result, errors.Wrap(err, "compare.CompareSets")
}
for i := 0; i < len(removed); i++ {
err = iGroup.DetachSystemPolicy(removed[i].GetGlobalId())
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
result.UpdateCnt = len(commondb)
for i := 0; i < len(added); i++ {
if added[i].PolicyType == api.CLOUD_POLICY_TYPE_SYSTEM {
err = iGroup.AttachSystemPolicy(added[i].ExternalId)
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
}
return result, nil
}
// 将本地的用户推送到云上(覆盖云上设置)
func (self *SCloudgroupcache) SyncCloudusersForCloud(ctx context.Context) (result compare.SyncResult, err error) {
lockman.LockObject(ctx, self)
defer lockman.ReleaseObject(ctx, self)
iGroup, err := self.GetICloudgroup()
if err != nil {
return result, errors.Wrap(err, "GetICloudgroup")
}
iUsers, err := iGroup.GetICloudusers()
if err != nil {
return result, errors.Wrap(err, "GetICloudusers")
}
group, err := self.GetCloudgroup()
if err != nil {
return result, errors.Wrap(err, "GetCloudgroup")
}
dbUsers, err := group.GetCloudusers()
if err != nil {
return result, errors.Wrap(err, "GetCloudusers")
}
added := make([]SClouduser, 0)
commondb := make([]SClouduser, 0)
commonext := make([]cloudprovider.IClouduser, 0)
removed := make([]cloudprovider.IClouduser, 0)
err = compare.CompareSets(dbUsers, iUsers, &added, &commondb, &commonext, &removed)
if err != nil {
return result, errors.Wrap(err, "compare.CompareSets")
}
for i := 0; i < len(removed); i++ {
err = iGroup.RemoveUser(removed[i].GetName())
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
result.UpdateCnt = len(commondb)
for i := 0; i < len(added); i++ {
err = iGroup.AddUser(added[i].GetName())
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result, nil
}

View File

@@ -0,0 +1,186 @@
// 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 models
import (
"context"
"database/sql"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/reflectutils"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SCloudgroupJointsManager struct {
db.SJointResourceBaseManager
}
func NewCloudgroupJointsManager(dt interface{}, tableName string, keyword string, keywordPlural string, slave db.IVirtualModelManager) SCloudgroupJointsManager {
return SCloudgroupJointsManager{
SJointResourceBaseManager: db.NewJointResourceBaseManager(
dt,
tableName,
keyword,
keywordPlural,
CloudgroupManager,
slave,
),
}
}
type SCloudgroupJointsBase struct {
db.SJointResourceBase
// 用户组Id
CloudgroupId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" index:"true" json:"cloudgroup_id"`
}
func (self *SCloudgroupJointsBase) getCloudgroup() (*SCloudgroup, error) {
group, err := CloudgroupManager.FetchById(self.CloudgroupId)
if err != nil {
return nil, errors.Wrap(err, "FetchById")
}
return group.(*SCloudgroup), nil
}
func (manager *SCloudgroupJointsManager) GetMasterFieldName() string {
return "cloudgroup_id"
}
func (self *SCloudgroupJointsBase) GetExtraDetails(
ctx context.Context,
groupCred mcclient.TokenCredential,
query jsonutils.JSONObject,
isList bool,
) (api.CloudgroupJointResourceDetails, error) {
return api.CloudgroupJointResourceDetails{}, nil
}
func (manager *SCloudgroupJointsManager) FetchCustomizeColumns(
ctx context.Context,
groupCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.CloudgroupJointResourceDetails {
rows := make([]api.CloudgroupJointResourceDetails, len(objs))
jointRows := manager.SJointResourceBaseManager.FetchCustomizeColumns(ctx, groupCred, query, objs, fields, isList)
groupIds := make([]string, len(rows))
for i := range rows {
rows[i] = api.CloudgroupJointResourceDetails{
JointResourceBaseDetails: jointRows[i],
}
var base *SCloudgroupJointsBase
reflectutils.FindAnonymouStructPointer(objs[i], &base)
if base != nil && len(base.CloudgroupId) > 0 {
groupIds[i] = base.CloudgroupId
}
}
groupIdMaps, err := db.FetchIdNameMap2(CloudgroupManager, groupIds)
if err != nil {
log.Errorf("db.FetchIdNameMap2 fail %s", err)
return rows
}
for i := range rows {
if name, ok := groupIdMaps[groupIds[i]]; ok {
rows[i].Cloudgroup = name
}
}
return rows
}
func (manager *SCloudgroupJointsManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
groupCred mcclient.TokenCredential,
query api.CloudgroupJointsListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SJointResourceBaseManager.ListItemFilter(ctx, q, groupCred, query.JointResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SJointResourceBaseManager.ListItemFilter")
}
if len(query.Cloudgroup) > 0 {
group, err := CloudgroupManager.FetchByIdOrName(nil, query.Cloudgroup)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("cloudgroup", query.Cloudgroup)
}
return nil, httperrors.NewGeneralError(err)
}
q = q.Equals("cloudgroup_id", group.GetId())
}
return q, nil
}
func (manager *SCloudgroupJointsManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
groupCred mcclient.TokenCredential,
query api.CloudgroupJointsListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SJointResourceBaseManager.OrderByExtraFields(ctx, q, groupCred, query.JointResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SJointResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (self *SCloudgroupJointsBase) ValidateUpdateData(
ctx context.Context,
groupCred mcclient.TokenCredential,
query jsonutils.JSONObject,
input api.CloudgroupJointBaseUpdateInput,
) (api.CloudgroupJointBaseUpdateInput, error) {
var err error
input.JointResourceBaseUpdateInput, err = self.SJointResourceBase.ValidateUpdateData(ctx, groupCred, query, input.JointResourceBaseUpdateInput)
if err != nil {
return input, errors.Wrap(err, "SJointResourceBase.ValidateUpdateData")
}
return input, nil
}
func (manager *SCloudgroupJointsManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
groupCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SJointResourceBaseManager.ListItemExportKeys(ctx, q, groupCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SJointResourceBaseManager.ListItemExportKeys")
}
return q, nil
}

View File

@@ -0,0 +1,280 @@
// 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 models
import (
"context"
"database/sql"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SCloudpolicyManager struct {
db.SStatusStandaloneResourceBaseManager
db.SExternalizedResourceBaseManager
}
var CloudpolicyManager *SCloudpolicyManager
func init() {
CloudpolicyManager = &SCloudpolicyManager{
SStatusStandaloneResourceBaseManager: db.NewStatusStandaloneResourceBaseManager(
SCloudpolicy{},
"cloudpolicy_tbl",
"cloudpolicy",
"cloudpolicies",
),
}
CloudpolicyManager.SetVirtualObject(CloudpolicyManager)
}
type SCloudpolicy struct {
db.SStatusStandaloneResourceBase
db.SExternalizedResourceBase
// 权限类型
//
// | 权限类型 | 说明 |
// |---------------|----------------------|
// | system | 平台内置权限 |
// | custom | 目前不支持 |
PolicyType string `width:"16" charset:"ascii" list:"domain" default:"custom"`
// 平台
Provider string `width:"64" charset:"ascii" list:"domain"`
}
func (manager *SCloudpolicyManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return true
}
func (manager *SCloudpolicyManager) GetIVirtualModelManager() db.IVirtualModelManager {
return manager.GetVirtualObject().(db.IVirtualModelManager)
}
func (manager *SCloudpolicyManager) GetResourceCount() ([]db.SScopeResourceCount, error) {
return nil, nil
}
// 公有云权限列表
func (manager *SCloudpolicyManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query api.CloudpolicyListInput) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, err
}
if len(query.Provider) > 0 {
q = q.In("provider", query.Provider)
}
if len(query.ClouduserId) > 0 {
_, err = ClouduserManager.FetchById(query.ClouduserId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("clouduser", query.ClouduserId)
}
return q, httperrors.NewGeneralError(errors.Wrap(err, "ClouduserManager.FetchById"))
}
sq := ClouduserPolicyManager.Query("cloudpolicy_id").Equals("clouduser_id", query.ClouduserId)
q = q.In("id", sq.SubQuery())
}
if len(query.CloudgroupId) > 0 {
_, err = CloudgroupManager.FetchById(query.CloudgroupId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("cloudgroup", query.CloudgroupId)
}
return q, httperrors.NewGeneralError(errors.Wrap(err, "CloudgroupManager.FetchById"))
}
sq := CloudgroupPolicyManager.Query("cloudpolicy_id").Equals("cloudgroup_id", query.CloudgroupId)
q = q.In("id", sq.SubQuery())
}
return q, nil
}
func (manager *SCloudpolicyManager) AllowCreateItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return false
}
// +onecloud:swagger-gen-ignore
func (manager *SCloudpolicyManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.CloudpolicyCreateInput) (api.CloudpolicyCreateInput, error) {
return input, httperrors.NewNotImplementedError("Not Implement")
}
// +onecloud:swagger-gen-ignore
func (self *SCloudpolicy) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudpolicyUpdateInput) (api.CloudpolicyUpdateInput, error) {
return input, nil
}
// +onecloud:swagger-gen-ignore
func (self *SCloudpolicy) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.SStatusStandaloneResourceBase.CustomizeDelete(ctx, userCred, query, data)
}
func (manager *SCloudpolicyManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.CloudpolicyListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SCloudpolicyManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (self *SCloudpolicy) AllowPerformAssignGroup(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsDomainAllowPerform(userCred, self, "assign-group")
}
// 将权限加入权限组
func (self *SCloudpolicy) PerformAssignGroup(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudpolicyAssignGroupInput) (jsonutils.JSONObject, error) {
if len(input.CloudgroupId) == 0 {
return nil, httperrors.NewMissingParameterError("cloudgroup_id")
}
_group, err := CloudgroupManager.FetchById(input.CloudgroupId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("cloudgroup", input.CloudgroupId)
}
return nil, httperrors.NewGeneralError(err)
}
group := _group.(*SCloudgroup)
if self.Provider != group.Provider {
return nil, httperrors.NewConflictError("policy and group not with same provider")
}
err = group.attachPolicy(self.Id)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
return nil, group.StartCloudgroupSyncPoliciesTask(ctx, userCred, "")
}
func (self *SCloudpolicy) AllowPerformRevokeGroup(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return db.IsDomainAllowPerform(userCred, self, "revoke-group")
}
// 将权限从权限组中移除
func (self *SCloudpolicy) PerformRevokeGroup(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.CloudpolicyRevokeGroupInput) (jsonutils.JSONObject, error) {
if len(input.CloudgroupId) == 0 {
return nil, httperrors.NewMissingParameterError("cloudgroup_id")
}
_group, err := CloudgroupManager.FetchById(input.CloudgroupId)
if err != nil {
if errors.Cause(err) == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("cloudgroup", input.CloudgroupId)
}
return nil, httperrors.NewGeneralError(err)
}
group := _group.(*SCloudgroup)
if self.Provider != group.Provider {
return nil, httperrors.NewConflictError("policy and group not with same provider")
}
err = group.detachPolicy(self.Id)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
return nil, group.StartCloudgroupSyncPoliciesTask(ctx, userCred, "")
}
func (self *SCloudpolicy) AllowGetDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return true
}
// 获取公有云权限详情
func (self *SCloudpolicy) GetExtraDetails(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
isList bool,
) (api.CloudpolicyDetails, error) {
return api.CloudpolicyDetails{}, nil
}
func (manager *SCloudpolicyManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.CloudpolicyDetails {
rows := make([]api.CloudpolicyDetails, len(objs))
statusRows := manager.SStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.CloudpolicyDetails{
StatusStandaloneResourceDetails: statusRows[i],
}
}
return rows
}
func (self *SCloudpolicy) AllowUpdateItem(ctx context.Context, userCred mcclient.TokenCredential) bool {
return false
}
func (self *SCloudpolicy) AllowDeleteItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return false
}
func (manager *SCloudpolicyManager) newFromCloudpolicy(ctx context.Context, userCred mcclient.TokenCredential, iPolicy cloudprovider.ICloudpolicy, provider string) error {
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
policy := &SCloudpolicy{}
policy.SetModelManager(manager, policy)
policy.Name = iPolicy.GetName()
policy.Status = api.CLOUD_POLICY_STATUS_AVAILABLE
policy.PolicyType = api.CLOUD_POLICY_TYPE_SYSTEM
policy.Provider = provider
policy.ExternalId = iPolicy.GetGlobalId()
policy.Description = iPolicy.GetDescription()
return manager.TableSpec().Insert(ctx, policy)
}
func (self *SCloudpolicy) SyncWithCloudpolicy(ctx context.Context, userCred mcclient.TokenCredential, iPolicy cloudprovider.ICloudpolicy) error {
_, err := db.Update(self, func() error {
self.Name = iPolicy.GetName()
self.Description = iPolicy.GetDescription()
self.Status = api.CLOUD_POLICY_STATUS_AVAILABLE
return nil
})
return err
}

View File

@@ -0,0 +1,83 @@
// 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 models
import (
"context"
"database/sql"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/util/reflectutils"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SCloudpolicyResourceBaseManager struct {
}
type SCloudpolicyResourceBase struct {
// 权限Id
CloudpolicyId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" json:"cloudpolicy_id"`
}
func (manager *SCloudpolicyResourceBaseManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, policyCred mcclient.TokenCredential, query api.CloudpolicyResourceListInput) (*sqlchemy.SQuery, error) {
if len(query.Cloudpolicy) > 0 {
policy, err := CloudpolicyManager.FetchByIdOrName(nil, query.Cloudpolicy)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("cloudpolicy", query.Cloudpolicy)
}
return nil, httperrors.NewGeneralError(err)
}
q = q.Equals("cloudpolicy_id", policy.GetId())
}
return q, nil
}
func (manager *SCloudpolicyResourceBaseManager) FetchCustomizeColumns(
ctx context.Context,
policyCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.CloudpolicyResourceDetails {
rows := make([]api.CloudpolicyResourceDetails, len(objs))
policyIds := make([]string, len(objs))
for i := range objs {
var base *SCloudpolicyResourceBase
err := reflectutils.FindAnonymouStructPointer(objs[i], &base)
if err != nil {
log.Errorf("Cannot find SCloudpolicyResourceBase in %#v: %s", objs[i], err)
} else if base != nil && len(base.CloudpolicyId) > 0 {
policyIds[i] = base.CloudpolicyId
}
}
policyMaps, err := db.FetchIdNameMap2(CloudpolicyManager, policyIds)
if err != nil {
log.Errorf("FetchIdNameMap2 fail %v", err)
return rows
}
for i := range rows {
rows[i].Cloudpolicy, _ = policyMaps[policyIds[i]]
}
return rows
}

View File

@@ -0,0 +1,168 @@
// 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 models
import (
"context"
"database/sql"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudid/options"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modules"
)
// +onecloud:swagger-gen-ignore
type SCloudproviderManager struct {
db.SStandaloneResourceBaseManager
}
var CloudproviderManager *SCloudproviderManager
func init() {
CloudproviderManager = &SCloudproviderManager{
SStandaloneResourceBaseManager: db.NewStandaloneResourceBaseManager(
SCloudprovider{},
"cloudproviders_tbl",
"cloudprovider",
"cloudproviders",
),
}
CloudproviderManager.SetVirtualObject(CloudproviderManager)
}
type SCloudprovider struct {
db.SStandaloneResourceBase
Provider string `width:"64" charset:"ascii" list:"domain"`
CloudaccountId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
}
func (self *SCloudprovider) syncRemoveClouduser(ctx context.Context, userCred mcclient.TokenCredential) error {
users, err := self.getCloudusers()
if err != nil {
return errors.Wrap(err, "getCloudusers")
}
for i := range users {
err = users[i].RealDelete(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "RealDelete user %s(%s)", users[i].Name, users[i].Id)
}
}
return self.Delete(ctx, userCred)
}
func (manager *SCloudproviderManager) newFromRegionProvider(ctx context.Context, userCred mcclient.TokenCredential, provider SCloudprovider) error {
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
return manager.TableSpec().Insert(ctx, &provider)
}
func (self *SCloudprovider) syncWithRegionProvider(ctx context.Context, userCred mcclient.TokenCredential, provider SCloudprovider) error {
_, err := db.UpdateWithLock(ctx, self, func() error {
self.Name = provider.Name
return nil
})
return err
}
func (self SCloudprovider) GetGlobalId() string {
return self.Id
}
func (self SCloudprovider) GetExternalId() string {
return self.Id
}
func (self SCloudprovider) GetCloudproviderId() string {
return self.Id
}
func (manager *SCloudproviderManager) FetchProvider(ctx context.Context, id string) (*SCloudprovider, error) {
provider, err := manager.FetchById(id)
if err != nil {
if err == sql.ErrNoRows {
session := auth.GetAdminSession(context.Background(), options.Options.Region, "")
result, err := modules.Cloudproviders.Get(session, id, nil)
if err != nil {
return nil, errors.Wrap(err, "Cloudproviders.Get")
}
_provider := &SCloudprovider{}
_provider.SetModelManager(manager, _provider)
err = result.Unmarshal(_provider)
if err != nil {
return nil, errors.Wrap(err, "result.Unmarshal")
}
lockman.LockRawObject(ctx, manager.KeywordPlural(), id)
defer lockman.ReleaseRawObject(ctx, manager.KeywordPlural(), id)
return _provider, manager.TableSpec().InsertOrUpdate(ctx, _provider)
}
return nil, errors.Wrap(err, "manager.FetchById")
}
return provider.(*SCloudprovider), nil
}
func (self *SCloudprovider) getCloudDelegate(ctx context.Context) (*SCloudDelegate, error) {
s := auth.GetAdminSession(ctx, options.Options.Region, "")
result, err := modules.Cloudproviders.Get(s, self.Id, nil)
if err != nil {
return nil, errors.Wrap(err, "Cloudproviders.Get")
}
delegate := &SCloudDelegate{}
err = result.Unmarshal(delegate)
if err != nil {
return nil, errors.Wrap(err, "result.Unmarshal")
}
return delegate, nil
}
func (self *SCloudprovider) GetProvider() (cloudprovider.ICloudProvider, error) {
delegate, err := self.getCloudDelegate(context.Background())
if err != nil {
return nil, errors.Wrap(err, "getCloudproviderDelegate")
}
return delegate.GetProvider()
}
func (self *SCloudprovider) GetProviderFactory() (cloudprovider.ICloudProviderFactory, error) {
return cloudprovider.GetProviderFactory(self.Provider)
}
func (self *SCloudprovider) getCloudusers() ([]SClouduser, error) {
users := []SClouduser{}
q := ClouduserManager.Query().Equals("cloudprovider_id", self.Id)
err := db.FetchModelObjects(ClouduserManager, q, &users)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
return users, nil
}
func (self *SCloudprovider) getAvailableUsers(cloudproviderId string) ([]SClouduser, error) {
users := []SClouduser{}
q := ClouduserManager.Query().Equals("status", api.CLOUD_USER_STATUS_AVAILABLE).Equals("cloudprovider_id", self.Id)
err := db.FetchModelObjects(ClouduserManager, q, &users)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
return users, nil
}

View File

@@ -0,0 +1,83 @@
// 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 models
import (
"context"
"database/sql"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/util/reflectutils"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SCloudproviderResourceBaseManager struct {
}
type SCloudproviderResourceBase struct {
// 子订阅Id
CloudproviderId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"optional" json:"cloudprovider_id"`
}
func (manager *SCloudproviderResourceBaseManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query api.CloudproviderResourceListInput) (*sqlchemy.SQuery, error) {
if len(query.Cloudprovider) > 0 {
provider, err := CloudproviderManager.FetchByIdOrName(nil, query.Cloudprovider)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("cloudprovider", query.Cloudprovider)
}
return nil, httperrors.NewGeneralError(err)
}
q = q.Equals("cloudprovider_id", provider.GetId())
}
return q, nil
}
func (manager *SCloudproviderResourceBaseManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.CloudproviderResourceDetails {
rows := make([]api.CloudproviderResourceDetails, len(objs))
providerIds := make([]string, len(objs))
for i := range objs {
var base *SCloudproviderResourceBase
err := reflectutils.FindAnonymouStructPointer(objs[i], &base)
if err != nil {
log.Errorf("Cannot find SCloudproviderResourceBase in %#v: %s", objs[i], err)
} else if base != nil && len(base.CloudproviderId) > 0 {
providerIds[i] = base.CloudproviderId
}
}
providerMaps, err := db.FetchIdNameMap2(CloudproviderManager, providerIds)
if err != nil {
log.Errorf("FetchIdNameMap2 fail %v", err)
return rows
}
for i := range rows {
rows[i].Cloudprovider, _ = providerMaps[providerIds[i]]
}
return rows
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,207 @@
// 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 models
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
// +onecloud:swagger-gen-ignore
type SClouduserPolicyManager struct {
SClouduserJointsManager
SCloudpolicyResourceBaseManager
}
var ClouduserPolicyManager *SClouduserPolicyManager
func init() {
db.InitManager(func() {
ClouduserPolicyManager = &SClouduserPolicyManager{
SClouduserJointsManager: NewClouduserJointsManager(
SClouduserPolicy{},
"clouduser_policies_tbl",
"clouduser_policy",
"clouduser_policies",
CloudpolicyManager,
),
}
ClouduserPolicyManager.SetVirtualObject(ClouduserPolicyManager)
ClouduserPolicyManager.TableSpec().AddIndex(true, "clouduser_id", "cloudpolicy_id")
})
}
type SClouduserPolicy struct {
SClouduserJointsBase
SCloudpolicyResourceBase
}
func (manager *SClouduserPolicyManager) GetSlaveFieldName() string {
return "cloudpolicy_id"
}
func (manager *SClouduserPolicyManager) AllowCreateItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return false
}
func (self *SClouduserPolicy) AllowDeleteItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return false
}
// +onecloud:swagger-gen-ignore
func (manager *SClouduserPolicyManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return nil, httperrors.NewNotSupportedError("Not Supported")
}
// +onecloud:swagger-gen-ignore
func (self *SClouduserPolicy) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.SClouduserJointsBase.CustomizeDelete(ctx, userCred, query, data)
}
// +onecloud:swagger-gen-ignore
func (self *SClouduserPolicy) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return nil, httperrors.NewNotSupportedError("Not Supported")
}
func (joint *SClouduserPolicy) Master() db.IStandaloneModel {
return db.JointMaster(joint)
}
func (joint *SClouduserPolicy) Slave() db.IStandaloneModel {
return db.JointSlave(joint)
}
// 获取公有云用户权限详情
func (self *SClouduserPolicy) GetExtraDetails(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
isList bool,
) (api.ClouduserPolicyDetails, error) {
return api.ClouduserPolicyDetails{}, nil
}
func (manager *SClouduserPolicyManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.ClouduserPolicyDetails {
rows := make([]api.ClouduserPolicyDetails, len(objs))
userRows := manager.SClouduserJointsManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
policyRows := manager.SCloudpolicyResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.ClouduserPolicyDetails{
ClouduserJointResourceDetails: userRows[i],
CloudpolicyResourceDetails: policyRows[i],
}
}
return rows
}
func (self *SClouduserPolicy) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DeleteModel(ctx, userCred, self)
}
func (self *SClouduserPolicy) Detach(ctx context.Context, userCred mcclient.TokenCredential) error {
return db.DetachJoint(ctx, userCred, self)
}
// 公有云用户权限列表
func (manager *SClouduserPolicyManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.ClouduserPolicyListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SClouduserJointsManager.ListItemFilter(ctx, q, userCred, query.ClouduserJointsListInput)
if err != nil {
return nil, errors.Wrap(err, "SClouduserJointsManager.ListItemFilter")
}
q, err = manager.SCloudpolicyResourceBaseManager.ListItemFilter(ctx, q, userCred, query.CloudpolicyResourceListInput)
if err != nil {
return nil, err
}
return q, nil
}
func (manager *SClouduserPolicyManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.ClouduserPolicyListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SClouduserJointsManager.OrderByExtraFields(ctx, q, userCred, query.ClouduserJointsListInput)
if err != nil {
return nil, errors.Wrap(err, "SClouduserJointsManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SClouduserPolicyManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SClouduserJointsManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SClouduserJointsManager.ListItemExportKeys")
}
return q, nil
}
func (manager *SClouduserPolicyManager) newFromClouduserPolicy(ctx context.Context, userCred mcclient.TokenCredential, iPolicy cloudprovider.ICloudpolicy, user *SClouduser) error {
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
up := &SClouduserPolicy{}
up.SetModelManager(manager, up)
up.ClouduserId = user.Id
p, err := db.FetchByExternalId(CloudpolicyManager, iPolicy.GetGlobalId())
if err != nil {
return errors.Wrapf(err, "db.FetchByExternalId(%s)", iPolicy.GetGlobalId())
}
up.CloudpolicyId = p.GetId()
return manager.TableSpec().Insert(ctx, up)
}

View File

@@ -0,0 +1,149 @@
// 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 models
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SClouduserJointsManager struct {
db.SJointResourceBaseManager
SClouduserResourceBaseManager
}
func NewClouduserJointsManager(dt interface{}, tableName string, keyword string, keywordPlural string, slave db.IVirtualModelManager) SClouduserJointsManager {
return SClouduserJointsManager{
SJointResourceBaseManager: db.NewJointResourceBaseManager(
dt,
tableName,
keyword,
keywordPlural,
ClouduserManager,
slave,
),
}
}
type SClouduserJointsBase struct {
db.SJointResourceBase
SClouduserResourceBase
}
func (manager *SClouduserJointsManager) GetMasterFieldName() string {
return "clouduser_id"
}
func (self *SClouduserJointsBase) GetExtraDetails(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
isList bool,
) (api.ClouduserJointResourceDetails, error) {
return api.ClouduserJointResourceDetails{}, nil
}
func (manager *SClouduserJointsManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.ClouduserJointResourceDetails {
rows := make([]api.ClouduserJointResourceDetails, len(objs))
jointRows := manager.SJointResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
userRows := manager.SClouduserResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.ClouduserJointResourceDetails{
JointResourceBaseDetails: jointRows[i],
ClouduserResourceDetails: userRows[i],
}
}
return rows
}
func (manager *SClouduserJointsManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.ClouduserJointsListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SJointResourceBaseManager.ListItemFilter(ctx, q, userCred, query.JointResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SJointResourceBaseManager.ListItemFilter")
}
q, err = manager.SClouduserResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ClouduserResourceListInput)
if err != nil {
return nil, err
}
return q, nil
}
func (manager *SClouduserJointsManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.ClouduserJointsListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SJointResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.JointResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SJointResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (self *SClouduserJointsBase) ValidateUpdateData(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
input api.ClouduserJointBaseUpdateInput,
) (api.ClouduserJointBaseUpdateInput, error) {
var err error
input.JointResourceBaseUpdateInput, err = self.SJointResourceBase.ValidateUpdateData(ctx, userCred, query, input.JointResourceBaseUpdateInput)
if err != nil {
return input, errors.Wrap(err, "SJointResourceBase.ValidateUpdateData")
}
return input, nil
}
func (manager *SClouduserJointsManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SJointResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SJointResourceBaseManager.ListItemExportKeys")
}
return q, nil
}

View File

@@ -0,0 +1,115 @@
// 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 models
import (
"context"
"database/sql"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/reflectutils"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SClouduserResourceBaseManager struct {
}
type SClouduserResourceBase struct {
ClouduserId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required"`
}
func (self *SClouduserJointsBase) GetClouduser() (*SClouduser, error) {
user, err := ClouduserManager.FetchById(self.ClouduserId)
if err != nil {
return nil, errors.Wrap(err, "FetchById")
}
return user.(*SClouduser), nil
}
func (manager *SClouduserResourceBaseManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query api.ClouduserResourceListInput) (*sqlchemy.SQuery, error) {
if len(query.Clouduser) > 0 {
user, err := ClouduserManager.FetchByIdOrName(nil, query.Clouduser)
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("clouduser", query.Clouduser)
}
return nil, httperrors.NewGeneralError(err)
}
q = q.Equals("clouduser_id", user.GetId())
}
return q, nil
}
func (manager *SClouduserResourceBaseManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.ClouduserResourceDetails {
rows := make([]api.ClouduserResourceDetails, len(objs))
userIds := make([]string, len(objs))
for i := range objs {
var base *SClouduserResourceBase
err := reflectutils.FindAnonymouStructPointer(objs[i], &base)
if err != nil {
log.Errorf("Cannot find SClouduserResourceBase in %#v: %s", objs[i], err)
} else if base != nil && len(base.ClouduserId) > 0 {
userIds[i] = base.ClouduserId
}
}
users := make(map[string]SClouduser)
err := db.FetchStandaloneObjectsByIds(ClouduserManager, userIds, &users)
if err != nil {
log.Errorf("FetchStandaloneObjectsByIds fail %v", err)
return rows
}
accountIds := make([]string, len(objs))
providerIds := make([]string, len(objs))
for i := range rows {
if user, ok := users[userIds[i]]; ok {
rows[i].Clouduser = user.Name
accountIds[i] = user.CloudaccountId
providerIds[i] = user.CloudproviderId
}
}
accountMaps, err := db.FetchIdNameMap2(CloudaccountManager, accountIds)
if err != nil {
log.Errorf("FetchIdNameMap2 fail %v", err)
return rows
}
providerMaps, err := db.FetchIdNameMap2(CloudproviderManager, providerIds)
if err != nil {
log.Errorf("FetchIdNameMap2 fail %v", err)
return rows
}
for i := range rows {
rows[i].Cloudaccount, _ = accountMaps[accountIds[i]]
rows[i].Cloudprovider, _ = providerMaps[providerIds[i]]
}
return rows
}

15
pkg/cloudid/models/doc.go Normal file
View File

@@ -0,0 +1,15 @@
// 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 models // import "yunion.io/x/onecloud/pkg/cloudid/models"

View File

@@ -0,0 +1,19 @@
// 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 models
func InitDB() error {
return nil
}

View File

@@ -0,0 +1 @@
package options // import "yunion.io/x/onecloud/pkg/cloudid/options"

View File

@@ -0,0 +1,33 @@
// 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 options
import (
common_options "yunion.io/x/onecloud/pkg/cloudcommon/options"
)
type SCloudIdOptions struct {
common_options.CommonOptions
common_options.DBOptions
CloudaccountSyncIntervalMinutes int `help:"frequency to sync region cloudaccount task" default:"3"`
CloudpolicySyncIntervalHours int `help:"frequency to sync region cloudpolicy task" default:"12"`
CloudgroupSyncIntervalHours int `help:"frequency to sync region cloudgrouptask" default:"3"`
ClouduserSyncIntervalHours int `help:"frequency to sync clouduser task" default:"7"`
}
var (
Options SCloudIdOptions
)

View File

@@ -0,0 +1 @@
package service // import "yunion.io/x/onecloud/pkg/cloudid/service"

View File

@@ -0,0 +1,69 @@
package service
// 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.
import (
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/appsrv/dispatcher"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/proxy"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
)
func InitHandlers(app *appsrv.Application) {
db.InitAllManagers()
taskman.AddTaskHandler("v1", app)
db.AddScopeResourceCountHandler("", app)
for _, manager := range []db.IModelManager{
taskman.TaskManager,
taskman.SubTaskManager,
taskman.TaskObjectManager,
db.UserCacheManager,
db.TenantCacheManager,
db.SharedResourceManager,
db.Metadata,
models.CloudaccountManager,
models.CloudproviderManager,
} {
db.RegisterModelManager(manager)
}
for _, manager := range []db.IModelManager{
db.OpsLog,
proxy.ProxySettingManager,
models.ClouduserManager,
models.CloudgroupManager,
models.CloudgroupcacheManager,
models.CloudpolicyManager,
} {
db.RegisterModelManager(manager)
handler := db.NewModelHandler(manager)
dispatcher.AddModelDispatcher("", app, handler)
}
for _, manager := range []db.IJointModelManager{
models.ClouduserPolicyManager,
models.CloudgroupPolicyManager,
models.CloudgroupUserManager,
} {
db.RegisterModelManager(manager)
handler := db.NewJointModelHandler(manager)
dispatcher.AddJointModelDispatcher("", app, handler)
}
}

View File

@@ -0,0 +1,62 @@
// 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 service
import (
"os"
"time"
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/cloudcommon"
common_app "yunion.io/x/onecloud/pkg/cloudcommon/app"
"yunion.io/x/onecloud/pkg/cloudcommon/cronman"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
common_options "yunion.io/x/onecloud/pkg/cloudcommon/options"
"yunion.io/x/onecloud/pkg/cloudid/models"
"yunion.io/x/onecloud/pkg/cloudid/options"
_ "yunion.io/x/onecloud/pkg/cloudid/tasks"
_ "yunion.io/x/onecloud/pkg/multicloud/loader"
)
func StartService() {
opts := &options.Options
dbOpts := &opts.DBOptions
baseOpts := &opts.BaseOptions
commonOpts := &opts.CommonOptions
common_options.ParseOptions(opts, os.Args, "cloudid.conf", "cloudid")
common_app.InitAuth(commonOpts, func() {
log.Infof("Auth complete!!")
})
app := common_app.InitApp(baseOpts, false)
InitHandlers(app)
db.EnsureAppInitSyncDB(app, dbOpts, models.InitDB)
defer cloudcommon.CloseDB()
if !opts.IsSlaveNode {
cron := cronman.InitCronJobManager(true, options.Options.CronJobWorkerCount)
cron.AddJobAtIntervalsWithStartRun("SyncCloudaccounts", time.Duration(opts.CloudaccountSyncIntervalMinutes)*time.Minute, models.CloudaccountManager.SyncCloudaccounts, true)
cron.AddJobAtIntervalsWithStartRun("SyncCloudpolicies", time.Duration(opts.CloudpolicySyncIntervalHours)*time.Hour, models.CloudaccountManager.SyncCloudpolicies, true)
cron.AddJobAtIntervalsWithStartRun("SyncCloudgroups", time.Duration(opts.CloudgroupSyncIntervalHours)*time.Hour, models.CloudaccountManager.SyncCloudgroups, true)
cron.AddJobAtIntervalsWithStartRun("SyncCloudusersTask", time.Duration(opts.ClouduserSyncIntervalHours)*time.Hour, models.CloudaccountManager.SyncCloudusers, true)
cron.Start()
defer cron.Stop()
}
common_app.ServeForever(app, baseOpts)
}

View File

@@ -0,0 +1,82 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type CloudgroupDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(CloudgroupDeleteTask{})
}
func (self *CloudgroupDeleteTask) taskFailed(ctx context.Context, group *models.SCloudgroup, err error) {
group.SetStatus(self.GetUserCred(), api.CLOUD_GROUP_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, group, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, err.Error())
}
func (self *CloudgroupDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
group := obj.(*models.SCloudgroup)
caches, err := group.GetCloudgroupcaches()
if err != nil {
self.taskFailed(ctx, group, errors.Wrap(err, "GetCloudgroupcaches"))
return
}
for i := range caches {
iGroup, err := caches[i].GetICloudgroup()
if err != nil && errors.Cause(err) != cloudprovider.ErrNotFound {
self.taskFailed(ctx, group, errors.Wrap(err, "caches[i].GetICloudgroup"))
return
}
if err == nil {
err = iGroup.Delete()
if err != nil {
self.taskFailed(ctx, group, errors.Wrap(err, "iGroup.Delete"))
return
}
}
caches[i].RealDelete(ctx, self.GetUserCred())
}
cnt, err := group.GetCloudgroupcacheCount()
if err != nil {
self.taskFailed(ctx, group, errors.Wrap(err, "GetCloudgroupcacheCount"))
return
}
if cnt == 0 {
group.RealDelete(ctx, self.GetUserCred())
logclient.AddActionLogWithStartable(self, group, logclient.ACT_DELETE, nil, self.UserCred, true)
self.SetStageComplete(ctx, nil)
return
}
self.SetStageComplete(ctx, nil)
}

View File

@@ -0,0 +1,99 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type CloudgroupSyncPoliciesTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(CloudgroupSyncPoliciesTask{})
}
func (self *CloudgroupSyncPoliciesTask) taskFailed(ctx context.Context, group *models.SCloudgroup, err error) {
group.SetStatus(self.GetUserCred(), api.CLOUD_GROUP_STATUS_SYNC_POLICIES, err.Error())
logclient.AddActionLogWithStartable(self, group, logclient.ACT_SYNC_POLICIES, err, self.UserCred, false)
self.SetStageFailed(ctx, err.Error())
}
func (self *CloudgroupSyncPoliciesTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
group := obj.(*models.SCloudgroup)
factory, err := group.GetProviderFactory()
if err != nil {
self.taskFailed(ctx, group, errors.Wrap(err, "group.GetProviderFactory"))
return
}
if !factory.IsSupportCreateCloudgroup() {
if factory.IsSupportClouduserPolicy() {
users, err := group.GetCloudusers()
if err != nil {
self.taskFailed(ctx, group, errors.Wrap(err, "group.GetCloudusers"))
return
}
for i := range users {
result, err := users[i].SyncCloudpoliciesForCloud(ctx)
if err != nil {
logclient.AddActionLogWithStartable(self, &users[i], logclient.ACT_SYNC_POLICIES, err, self.UserCred, false)
continue
}
log.Infof("Sync cloudpolicies for user %s(%s) result: %s", users[i].Name, users[i].Id, result.Result())
if result.AddErrCnt+result.DelErrCnt > 0 {
self.taskFailed(ctx, group, result.AllError())
return
}
}
}
} else {
caches, err := group.GetCloudgroupcaches()
if err != nil {
self.taskFailed(ctx, group, errors.Wrap(err, "GetCloudgroupcaches"))
return
}
for i := range caches {
result, err := caches[i].SyncCloudpoliciesForCloud(ctx)
if err != nil {
logclient.AddActionLogWithStartable(self, &caches[i], logclient.ACT_SYNC_POLICIES, err, self.UserCred, false)
continue
}
log.Infof("Sync cloudpolicies for group cache %s(%s) result: %s", caches[i].Name, caches[i].Id, result.Result())
if result.AddErrCnt+result.DelErrCnt > 0 {
self.taskFailed(ctx, group, result.AllError())
return
}
}
}
group.SetStatus(self.GetUserCred(), api.CLOUD_GROUP_STATUS_AVAILABLE, "")
self.SetStageComplete(ctx, nil)
}

View File

@@ -0,0 +1,139 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type CloudgroupSyncUsersTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(CloudgroupSyncUsersTask{})
}
func (self *CloudgroupSyncUsersTask) taskFailed(ctx context.Context, group *models.SCloudgroup, err error) {
group.SetStatus(self.GetUserCred(), api.CLOUD_GROUP_STATUS_SYNC_POLICIES, err.Error())
logclient.AddActionLogWithStartable(self, group, logclient.ACT_SYNC_POLICIES, err, self.UserCred, false)
self.SetStageFailed(ctx, err.Error())
}
func (self *CloudgroupSyncUsersTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
group := obj.(*models.SCloudgroup)
factory, err := group.GetProviderFactory()
if err != nil {
self.taskFailed(ctx, group, errors.Wrap(err, "GetProviderFactory"))
return
}
users, err := group.GetCloudusers()
if err != nil {
self.taskFailed(ctx, group, errors.Wrap(err, "GetCloudusers"))
return
}
if !factory.IsSupportCreateCloudgroup() && factory.IsSupportClouduserPolicy() {
for i := range users {
result, err := users[i].SyncCloudpoliciesForCloud(ctx)
if err != nil {
logclient.AddActionLogWithStartable(self, &users[i], logclient.ACT_SYNC_POLICIES, err, self.UserCred, false)
continue
}
log.Infof("Sync cloudpolicies for user %s(%s) result: %s", users[i].Name, users[i].Id, result.Result())
if result.AddErrCnt+result.DelErrCnt > 0 {
self.taskFailed(ctx, group, result.AllError())
return
}
}
} else {
caches, err := group.GetCloudgroupcaches()
if err != nil {
self.taskFailed(ctx, group, errors.Wrap(err, "GetCloudgroupcaches"))
return
}
accounts := map[string]string{}
for i := range caches {
account, err := caches[i].GetCloudaccount()
if err != nil {
log.Errorf("failed to get cloudaccoutn for cache %s(%s) error: %v", caches[i].Name, caches[i].Id, err)
continue
}
accounts[account.Id] = account.Name
result, err := caches[i].SyncCloudusersForCloud(ctx)
if err != nil {
logclient.AddActionLogWithStartable(self, &caches[i], logclient.ACT_SYNC_POLICIES, err, self.UserCred, false)
continue
}
log.Infof("Sync cloudpolicies for group cache %s(%s) result: %s", caches[i].Name, caches[i].Id, result.Result())
if result.AddErrCnt+result.DelErrCnt > 0 {
self.taskFailed(ctx, group, result.AllError())
return
}
}
for _, user := range users {
if _, ok := accounts[user.CloudaccountId]; !ok {
account, err := user.GetCloudaccount()
if err != nil {
self.taskFailed(ctx, group, errors.Wrap(err, "GetCloudaccount"))
return
}
cache, err := models.CloudgroupcacheManager.Register(group, account)
if err != nil {
self.taskFailed(ctx, group, errors.Wrap(err, "CloudgroupcacheManager.Register"))
return
}
_, err = cache.GetOrCreateICloudgroup(ctx, self.GetUserCred())
if err != nil {
self.taskFailed(ctx, group, errors.Wrap(err, "GetOrCreateICloudgroup"))
return
}
result, err := cache.SyncCloudusersForCloud(ctx)
if err != nil {
logclient.AddActionLogWithStartable(self, cache, logclient.ACT_SYNC_POLICIES, err, self.UserCred, false)
continue
}
log.Infof("Sync cloudpolicies for group cache %s(%s) result: %s", cache.Name, cache.Id, result.Result())
if result.AddErrCnt+result.DelErrCnt > 0 {
self.taskFailed(ctx, group, result.AllError())
return
}
}
}
}
group.SetStatus(self.GetUserCred(), api.CLOUD_GROUP_STATUS_AVAILABLE, "")
self.SetStageComplete(ctx, nil)
}

View File

@@ -0,0 +1,72 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type CloudgroupcacheDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(CloudgroupcacheDeleteTask{})
}
func (self *CloudgroupcacheDeleteTask) taskFailed(ctx context.Context, cache *models.SCloudgroupcache, err error) {
cache.SetStatus(self.GetUserCred(), api.CLOUD_GROUP_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, cache, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, err.Error())
}
func (self *CloudgroupcacheDeleteTask) taskComplete(ctx context.Context, cache *models.SCloudgroupcache) {
cache.RealDelete(ctx, self.GetUserCred())
logclient.AddActionLogWithStartable(self, cache, logclient.ACT_DELETE, "", self.UserCred, true)
self.SetStageComplete(ctx, nil)
}
func (self *CloudgroupcacheDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
cache := obj.(*models.SCloudgroupcache)
if len(cache.ExternalId) == 0 {
self.taskComplete(ctx, cache)
return
}
iGroup, err := cache.GetICloudgroup()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
self.taskComplete(ctx, cache)
return
}
self.taskFailed(ctx, cache, errors.Wrap(err, "GetICloudgroup"))
return
}
err = iGroup.Delete()
if err != nil {
self.taskFailed(ctx, cache, errors.Wrap(err, "iGroup.Delete"))
return
}
self.taskComplete(ctx, cache)
}

View File

@@ -0,0 +1,52 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type CloudgroupcacheSyncstatusTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(CloudgroupcacheSyncstatusTask{})
}
func (self *CloudgroupcacheSyncstatusTask) taskFailed(ctx context.Context, cache *models.SCloudgroupcache, err error) {
cache.SetStatus(self.GetUserCred(), api.CLOUD_GROUP_CACHE_STATUS_UNKNOWN, err.Error())
logclient.AddActionLogWithStartable(self, cache, logclient.ACT_SYNC_STATUS, err, self.UserCred, false)
self.SetStageFailed(ctx, err.Error())
}
func (self *CloudgroupcacheSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
cache := obj.(*models.SCloudgroupcache)
_, err := cache.GetICloudgroup()
if err != nil {
self.taskFailed(ctx, cache, errors.Wrap(err, "GetICloudgroup"))
return
}
self.SetStageComplete(ctx, nil)
}

View File

@@ -0,0 +1,73 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type ClouduserDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(ClouduserDeleteTask{})
}
func (self *ClouduserDeleteTask) taskFailed(ctx context.Context, clouduser *models.SClouduser, err error) {
clouduser.SetStatus(self.GetUserCred(), api.CLOUD_USER_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, clouduser, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, err.Error())
}
func (self *ClouduserDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
clouduser := obj.(*models.SClouduser)
if len(clouduser.ExternalId) == 0 {
clouduser.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
return
}
iUser, err := clouduser.GetIClouduser()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
clouduser.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
return
}
self.taskFailed(ctx, clouduser, errors.Wrap(err, "GetIClouduser"))
return
}
err = iUser.Delete()
if err != nil {
self.taskFailed(ctx, clouduser, errors.Wrap(err, "user.Delete"))
return
}
clouduser.RealDelete(ctx, self.GetUserCred())
logclient.AddActionLogWithStartable(self, clouduser, logclient.ACT_DELETE, clouduser, self.UserCred, true)
self.SetStageComplete(ctx, nil)
}

View File

@@ -0,0 +1,80 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type ClouduserResetPasswordTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(ClouduserResetPasswordTask{})
}
func (self *ClouduserResetPasswordTask) taskFailed(ctx context.Context, clouduser *models.SClouduser, err error) {
clouduser.SetStatus(self.GetUserCred(), api.CLOUD_USER_STATUS_RESET_PASSWORD_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, clouduser, logclient.ACT_RESET_PASSWORD, err, self.UserCred, false)
self.SetStageFailed(ctx, err.Error())
}
func (self *ClouduserResetPasswordTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
clouduser := obj.(*models.SClouduser)
password, _ := self.GetParams().GetString("password")
account, err := clouduser.GetCloudaccount()
if err != nil {
self.taskFailed(ctx, clouduser, errors.Wrap(err, "GetCloudaccount"))
return
}
factory, err := account.GetProviderFactory()
if err != nil {
self.taskFailed(ctx, clouduser, errors.Wrap(err, "GetProviderFactory"))
return
}
iUser, err := clouduser.GetIClouduser()
if err != nil {
self.taskFailed(ctx, clouduser, errors.Wrap(err, "GetIClouduser"))
return
}
if factory.IsSupportResetClouduserPassword() {
err = iUser.ResetPassword(password)
if err != nil {
self.taskFailed(ctx, clouduser, errors.Wrap(err, "ResetPassword"))
return
}
clouduser.SyncWithClouduser(ctx, self.GetUserCred(), iUser, clouduser.CloudproviderId)
} else {
password = ""
}
clouduser.SavePassword(password)
logclient.AddActionLogWithStartable(self, clouduser, logclient.ACT_RESET_PASSWORD, "", self.UserCred, true)
self.SetStageComplete(ctx, nil)
}

View File

@@ -0,0 +1,106 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
)
type ClouduserSyncGroupsTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(ClouduserSyncGroupsTask{})
}
func (self *ClouduserSyncGroupsTask) taskFailed(ctx context.Context, clouduser *models.SClouduser, err error) {
clouduser.SetStatus(self.GetUserCred(), api.CLOUD_USER_STATUS_SYNC_GROUPS_FAILED, err.Error())
self.SetStageFailed(ctx, err.Error())
}
func (self *ClouduserSyncGroupsTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
user := obj.(*models.SClouduser)
account, err := user.GetCloudaccount()
if err != nil {
self.taskFailed(ctx, user, errors.Wrap(err, "GetCloudaccount"))
return
}
factory, err := account.GetProviderFactory()
if err != nil {
self.taskFailed(ctx, user, errors.Wrap(err, "GetCloudaccount"))
return
}
if factory.IsSupportCreateCloudgroup() {
groups, err := user.GetCloudgroups()
if err != nil {
self.taskFailed(ctx, user, errors.Wrap(err, "GetCloudgroups"))
return
}
for i := range groups {
cache, err := models.CloudgroupcacheManager.Register(&groups[i], account)
if err != nil {
self.taskFailed(ctx, user, errors.Wrap(err, "CloudgroupcacheManager.Register"))
return
}
_, err = cache.GetOrCreateICloudgroup(ctx, self.GetUserCred())
if err != nil {
self.taskFailed(ctx, user, errors.Wrap(err, "GetOrCreateICloudgroup"))
return
}
result, err := cache.SyncCloudusersForCloud(ctx)
if err != nil {
self.taskFailed(ctx, user, errors.Wrap(err, "GetOrCreateICloudgroup"))
return
}
log.Infof("sync cloudusers for cache %s(%s) result: %s", cache.Name, cache.Id, result.Result())
if result.AddErrCnt+result.DelErrCnt > 0 {
self.taskFailed(ctx, user, result.AllError())
return
}
}
} else if factory.IsSupportClouduserPolicy() {
result, err := user.SyncCloudpoliciesForCloud(ctx)
if err != nil {
self.taskFailed(ctx, user, errors.Wrap(err, "SyncCloudpoliciesForCloud"))
return
}
log.Infof("sync cloudpolicies for user %s(%s) result: %s", user.Name, user.Id, result.Result())
if result.AddErrCnt+result.DelErrCnt > 0 {
self.taskFailed(ctx, user, result.AllError())
return
}
}
if !self.IsSubtask() {
user.SetStatus(self.GetUserCred(), api.CLOUD_USER_STATUS_AVAILABLE, "")
}
self.SetStageComplete(ctx, nil)
}

View File

@@ -0,0 +1,76 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
)
type ClouduserSyncPoliciesTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(ClouduserSyncPoliciesTask{})
}
func (self *ClouduserSyncPoliciesTask) taskFailed(ctx context.Context, clouduser *models.SClouduser, err error) {
clouduser.SetStatus(self.GetUserCred(), api.CLOUD_USER_STATUS_SYNC_POLICIES_FAILED, err.Error())
self.SetStageFailed(ctx, err.Error())
}
func (self *ClouduserSyncPoliciesTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
user := obj.(*models.SClouduser)
account, err := user.GetCloudaccount()
if err != nil {
self.taskFailed(ctx, user, errors.Wrap(err, "GetCloudaccount"))
return
}
factory, err := account.GetProviderFactory()
if err != nil {
self.taskFailed(ctx, user, errors.Wrap(err, "account.GetProviderFactory"))
return
}
if factory.IsSupportClouduserPolicy() {
result, err := user.SyncCloudpoliciesForCloud(ctx)
if err != nil {
self.taskFailed(ctx, user, errors.Wrap(err, "SyncCloudpoliciesForCloud"))
return
}
log.Infof("sync cloudpolicies for user %s(%s) result: %s", user.Name, user.Id, result.Result())
if result.AddErrCnt+result.DelErrCnt > 0 {
self.taskFailed(ctx, user, result.AllError())
return
}
}
if !self.IsSubtask() {
user.SetStatus(self.GetUserCred(), api.CLOUD_USER_STATUS_AVAILABLE, "")
}
self.SetStageComplete(ctx, nil)
}

View File

@@ -0,0 +1,82 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
)
type ClouduserSyncTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(ClouduserSyncTask{})
}
func (self *ClouduserSyncTask) taskFailed(ctx context.Context, clouduser *models.SClouduser, err error) {
clouduser.SetStatus(self.GetUserCred(), api.CLOUD_USER_STATUS_SYNC_FAILED, err.Error())
self.SetStageFailed(ctx, err.Error())
}
func (self *ClouduserSyncTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
user := obj.(*models.SClouduser)
self.SetStage("OnSyncCloudpoliciesComplete", nil)
user.StartClouduserSyncPoliciesTask(ctx, self.GetUserCred(), self.GetTaskId())
}
func (self *ClouduserSyncTask) OnSyncCloudpoliciesComplete(ctx context.Context, user *models.SClouduser, body jsonutils.JSONObject) {
account, err := user.GetCloudaccount()
if err != nil {
self.taskFailed(ctx, user, errors.Wrap(err, "user.GetCloudaccount"))
return
}
factory, err := account.GetProviderFactory()
if err != nil {
self.taskFailed(ctx, user, errors.Wrap(err, "GetProviderFactory"))
return
}
if factory.IsSupportCreateCloudgroup() {
self.SetStage("OnSyncCloudgroupsComplete", nil)
user.StartClouduserSyncGroupsTask(ctx, self.GetUserCred(), self.GetTaskId())
return
}
user.SetStatus(self.GetUserCred(), api.CLOUD_USER_STATUS_AVAILABLE, "")
self.SetStageComplete(ctx, nil)
}
func (self *ClouduserSyncTask) OnSyncCloudpoliciesCompleteFailed(ctx context.Context, user *models.SClouduser, data jsonutils.JSONObject) {
self.taskFailed(ctx, user, errors.Error(data.String()))
}
func (self *ClouduserSyncTask) OnSyncCloudgroupsComplete(ctx context.Context, user *models.SClouduser, body jsonutils.JSONObject) {
user.SetStatus(self.GetUserCred(), api.CLOUD_USER_STATUS_AVAILABLE, "")
self.SetStageComplete(ctx, nil)
}
func (self *ClouduserSyncTask) OnSyncCloudgroupsCompleteFailed(ctx context.Context, user *models.SClouduser, data jsonutils.JSONObject) {
self.taskFailed(ctx, user, errors.Error(data.String()))
}

View File

@@ -0,0 +1,53 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/cloudid"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
)
type ClouduserSyncstatusTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(ClouduserSyncstatusTask{})
}
func (self *ClouduserSyncstatusTask) taskFailed(ctx context.Context, clouduser *models.SClouduser, err error) {
clouduser.SetStatus(self.GetUserCred(), api.CLOUD_USER_STATUS_UNKNOWN, err.Error())
self.SetStageFailed(ctx, err.Error())
}
func (self *ClouduserSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
clouduser := obj.(*models.SClouduser)
_, err := clouduser.GetIClouduser()
if err != nil {
self.taskFailed(ctx, clouduser, errors.Wrap(err, "GetIClouduser"))
return
}
clouduser.SetStatus(self.GetUserCred(), api.CLOUD_USER_STATUS_AVAILABLE, "")
self.SetStageComplete(ctx, nil)
}

1
pkg/cloudid/tasks/doc.go Normal file
View File

@@ -0,0 +1 @@
package tasks // import "yunion.io/x/onecloud/pkg/cloudid/tasks"

View File

@@ -0,0 +1,60 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
)
type SyncCloudgroupcachesTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SyncCloudgroupcachesTask{})
}
func (self *SyncCloudgroupcachesTask) taskFailed(ctx context.Context, cloudaccount *models.SCloudaccount, err error) {
self.SetStageFailed(ctx, err.Error())
}
func (self *SyncCloudgroupcachesTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
account := obj.(*models.SCloudaccount)
provider, err := account.GetProvider()
if err != nil {
self.taskFailed(ctx, account, errors.Wrap(err, "GetProvider"))
return
}
groups, err := provider.GetICloudgroups()
if err != nil {
self.taskFailed(ctx, account, errors.Wrapf(err, "GetICloudgroups for %s(%s)", account.Name, account.Provider))
return
}
result := account.SyncCloudgroupcaches(ctx, self.GetUserCred(), groups)
log.Infof("Sync groups for %s(%s) result: %s", account.Name, account.Provider, result.Result())
self.SetStageComplete(ctx, nil)
}

View File

@@ -0,0 +1,60 @@
// 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 tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
)
type SyncCloudpoliciesTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SyncCloudpoliciesTask{})
}
func (self *SyncCloudpoliciesTask) taskFailed(ctx context.Context, cloudaccount *models.SCloudaccount, err error) {
self.SetStageFailed(ctx, err.Error())
}
func (self *SyncCloudpoliciesTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
account := obj.(*models.SCloudaccount)
provider, err := account.GetProvider()
if err != nil {
self.taskFailed(ctx, account, errors.Wrap(err, "GetProvider"))
return
}
policy, err := provider.GetISystemCloudpolicies()
if err != nil {
self.taskFailed(ctx, account, errors.Wrapf(err, "GetISystemCloudpolicies for %s(%s)", account.Name, account.Provider))
return
}
result := account.SyncCloudpolicies(ctx, self.GetUserCred(), policy)
log.Infof("Sync policies for %s(%s) result: %s", account.Name, account.Provider, result.Result())
self.SetStageComplete(ctx, nil)
}

View File

@@ -0,0 +1,125 @@
// 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 tasks
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudid/models"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SyncCloudusersTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(SyncCloudusersTask{})
}
type IProvider interface {
GetProvider() (cloudprovider.ICloudProvider, error)
GetName() string
GetCloudproviderId() string
}
func (self *SyncCloudusersTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
account := obj.(*models.SCloudaccount)
self.SetStage("OnClouduserSyncComplete", nil)
taskman.LocalTaskRun(self, func() (jsonutils.JSONObject, error) {
factory, err := account.GetProviderFactory()
if err != nil {
return nil, errors.Wrap(err, "account.GetProviderFactory")
}
if !factory.IsSupportClouduser() {
return nil, nil
}
iProviders := []IProvider{account}
if factory.IsClouduserBelongCloudprovider() {
iProviders = []IProvider{}
providers, err := account.GetCloudproviders()
if err != nil {
return nil, errors.Wrap(err, "GetCloudproviders")
}
for i := range providers {
iProviders = append(iProviders, &providers[i])
}
}
for i := range iProviders {
provider, err := iProviders[i].GetProvider()
if err != nil {
return nil, errors.Wrap(err, "GetProvider")
}
iUsers, err := provider.GetICloudusers()
if err != nil {
return nil, errors.Wrap(err, "provider.GetICloudusers")
}
localUsers, remoteUsers, result := account.SyncCloudusers(ctx, self.UserCred, iProviders[i].GetCloudproviderId(), iUsers)
msg := fmt.Sprintf("SyncCloudusers for account %s(%s) result: %s", iProviders[i].GetName(), account.Provider, result.Result())
log.Infof(msg)
for i := 0; i < len(localUsers); i += 1 {
func() {
// lock clouduser
lockman.LockObject(ctx, &localUsers[i])
defer lockman.ReleaseObject(ctx, &localUsers[i])
syncClouduserPolicies(ctx, self.GetUserCred(), &localUsers[i], remoteUsers[i])
syncClouduserGroups(ctx, self.GetUserCred(), &localUsers[i], remoteUsers[i])
}()
}
}
return nil, nil
})
}
func syncClouduserPolicies(ctx context.Context, userCred mcclient.TokenCredential, localUser *models.SClouduser, remoteUser cloudprovider.IClouduser) {
iPolicies, err := remoteUser.GetISystemCloudpolicies()
if err != nil {
log.Errorf("failed to get user %s policies error: %v", remoteUser.GetName(), err)
return
}
result := localUser.SyncCloudpolicies(ctx, userCred, iPolicies)
msg := fmt.Sprintf("SyncCloudpolicies for user %s(%s) result: %s", localUser.Name, localUser.Id, result.Result())
log.Infof(msg)
}
func syncClouduserGroups(ctx context.Context, userCred mcclient.TokenCredential, localUser *models.SClouduser, remoteUser cloudprovider.IClouduser) {
iGroups, err := remoteUser.GetICloudgroups()
if err != nil {
log.Errorf("failed to get user %s groups error: %v", remoteUser.GetName(), err)
return
}
result := localUser.SyncCloudgroups(ctx, userCred, iGroups)
msg := fmt.Sprintf("SyncCloudgroups for user %s(%s) result: %s", localUser.Name, localUser.Id, result.Result())
log.Infof(msg)
}
func (self *SyncCloudusersTask) OnClouduserSyncComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
self.SetStageComplete(ctx, nil)
}
func (self *SyncCloudusersTask) OnClouduserSyncCompleteFailed(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
self.SetStageFailed(ctx, data.String())
}

View File

@@ -32,6 +32,8 @@ import (
const (
ErrNoSuchProvder = errors.Error("no such provider")
TEST_CLOUDID_USER_NAME = "cloud-id-user"
)
type SCloudaccountCredential struct {
@@ -190,6 +192,14 @@ type ICloudProviderFactory interface {
IsCloudeventRegional() bool
GetMaxCloudEventSyncDays() int
GetMaxCloudEventKeepDays() int
IsSupportClouduser() bool
IsSupportClouduserPolicy() bool
IsSupportResetClouduserPassword() bool
GetClouduserMinPolicyCount() int
IsClouduserNeedInitPolicy() bool
IsClouduserBelongCloudprovider() bool
IsSupportCreateCloudgroup() bool
}
type ICloudProvider interface {
@@ -197,6 +207,8 @@ type ICloudProvider interface {
GetSysInfo() (jsonutils.JSONObject, error)
GetVersion() string
GetIamLoginUrl() string
IsSupportCloudId() bool
GetIRegions() []ICloudRegion
GetIProjects() ([]ICloudProject, error)
@@ -218,6 +230,15 @@ type ICloudProvider interface {
GetCapabilities() []string
GetICloudQuotas() ([]ICloudQuota, error)
IsClouduserSupportPassword() bool
GetICloudusers() ([]IClouduser, error)
GetISystemCloudpolicies() ([]ICloudpolicy, error)
GetICloudgroups() ([]ICloudgroup, error)
GetICloudgroupByName(name string) (ICloudgroup, error)
CreateICloudgroup(name, desc string) (ICloudgroup, error)
GetIClouduserByName(name string) (IClouduser, error)
CreateIClouduser(conf *SClouduserCreateConfig) (IClouduser, error)
}
func IsSupportProject(prod ICloudProvider) bool {
@@ -321,6 +342,64 @@ func (self *SBaseProvider) GetICloudQuotas() ([]ICloudQuota, error) {
return nil, ErrNotImplemented
}
func (self *SBaseProvider) GetIamLoginUrl() string {
return ""
}
func (self *SBaseProvider) IsSupportCloudId() bool {
return false
}
func IsSupportCloudId(provider ICloudProvider) bool {
defer func() {
iUser, err := provider.GetIClouduserByName(TEST_CLOUDID_USER_NAME)
if err != nil {
return
}
err = iUser.Delete()
if err != nil {
log.Errorf("failed to delete test user: %v", err)
}
}()
_, err := provider.CreateIClouduser(&SClouduserCreateConfig{Name: TEST_CLOUDID_USER_NAME})
if err != nil {
return false
}
return true
}
func (self *SBaseProvider) IsClouduserSupportPassword() bool {
return true
}
func (self *SBaseProvider) GetICloudusers() ([]IClouduser, error) {
return nil, ErrNotImplemented
}
func (self *SBaseProvider) GetICloudgroups() ([]ICloudgroup, error) {
return nil, ErrNotImplemented
}
func (self *SBaseProvider) GetICloudgroupByName(name string) (ICloudgroup, error) {
return nil, ErrNotImplemented
}
func (self *SBaseProvider) CreateICloudgroup(name, desc string) (ICloudgroup, error) {
return nil, ErrNotImplemented
}
func (self *SBaseProvider) GetISystemCloudpolicies() ([]ICloudpolicy, error) {
return nil, ErrNotImplemented
}
func (self *SBaseProvider) GetIClouduserByName(name string) (IClouduser, error) {
return nil, ErrNotImplemented
}
func (self *SBaseProvider) CreateIClouduser(conf *SClouduserCreateConfig) (IClouduser, error) {
return nil, ErrNotImplemented
}
func (self *SBaseProvider) GetCloudRegionExternalIdPrefix() string {
return self.factory.GetId()
}
@@ -353,6 +432,16 @@ func GetPrivateProviders() []string {
return providers
}
func GetSupportCloudgroupProviders() []string {
providers := []string{}
for p, d := range providerTable {
if d.IsSupportCreateCloudgroup() {
providers = append(providers, p)
}
}
return providers
}
func GetOnPremiseProviders() []string {
providers := make([]string, 0)
for p, d := range providerTable {
@@ -408,6 +497,35 @@ func (factory *baseProviderFactory) GetMaxCloudEventKeepDays() int {
return 7
}
func (factory *baseProviderFactory) IsSupportClouduser() bool {
return false
}
func (factory *baseProviderFactory) IsSupportClouduserPolicy() bool {
return true
}
func (factory *baseProviderFactory) IsSupportResetClouduserPassword() bool {
return true
}
func (factory *baseProviderFactory) IsClouduserNeedInitPolicy() bool {
return false
}
func (factory *baseProviderFactory) GetClouduserMinPolicyCount() int {
// unlimited
return -1
}
func (factory *baseProviderFactory) IsSupportCreateCloudgroup() bool {
return false
}
func (factory *baseProviderFactory) IsClouduserBelongCloudprovider() bool {
return false
}
type SPremiseBaseProviderFactory struct {
baseProviderFactory
}

View File

@@ -0,0 +1,25 @@
// 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 cloudprovider
type SClouduserCreateConfig struct {
Name string
Desc string
Password string
IsConsoleLogin bool
Email string
MobilePhone string
ExternalPolicyIds []string
}

View File

@@ -952,3 +952,44 @@ type ICloudQuota interface {
GetMaxQuotaCount() int
GetCurrentQuotaUsedCount() int
}
// 公有云子账号
type IClouduser interface {
GetGlobalId() string
GetName() string
GetICloudgroups() ([]ICloudgroup, error)
GetISystemCloudpolicies() ([]ICloudpolicy, error)
AttachSystemPolicy(policyType string) error
DetachSystemPolicy(policyId string) error
Delete() error
ResetPassword(password string) error
IsConsoleLogin() bool
}
// 公有云子账号权限
type ICloudpolicy interface {
GetGlobalId() string
GetName() string
//GetPolicyType() string
GetDescription() string
}
// 公有云用户组
type ICloudgroup interface {
GetGlobalId() string
GetName() string
GetDescription() string
GetISystemCloudpolicies() ([]ICloudpolicy, error)
GetICloudusers() ([]IClouduser, error)
AddUser(name string) error
RemoveUser(name string) error
AttachSystemPolicy(policyId string) error
DetachSystemPolicy(policyId string) error
Delete() error
}

View File

@@ -160,6 +160,12 @@ type SCloudaccount struct {
// 默认值proxyapi.ProxySettingId_DIRECT
ProxySettingId string `width:"36" charset:"ascii" nullable:"false" list:"domain" create:"optional" update:"domain" default:"DIRECT"`
// 公有云子账号登录地址
IamLoginUrl string `width:"512" charset:"ascii" nullable:"false" list:"domain" update:"domain"`
// 是否支持创建公有云子账号
IsSupportCloudId tristate.TriState `nullable:"false" get:"domain" list:"domain" default:"false"`
}
func (self *SCloudaccount) GetCloudproviders() []SCloudprovider {
@@ -2269,6 +2275,7 @@ func (account *SCloudaccount) probeAccountStatus(ctx context.Context, userCred m
log.Errorf("manager.GetSysInfo fail %s", err)
return nil, errors.Wrap(err, "manager.GetSysInfo")
}
iamLoginUrl := manager.GetIamLoginUrl()
factory := manager.GetFactory()
diff, err := db.Update(account, func() error {
isPublic := factory.IsPublicCloud()
@@ -2282,6 +2289,8 @@ func (account *SCloudaccount) probeAccountStatus(ctx context.Context, userCred m
account.ProbeAt = timeutils.UtcNow()
account.Version = version
account.Sysinfo = sysInfo
account.IamLoginUrl = iamLoginUrl
account.IsSupportCloudId = tristate.NewFromBool(manager.IsSupportCloudId())
return nil
})
if err != nil {

View File

@@ -20,7 +20,6 @@ import (
"golang.org/x/crypto/ssh"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
"yunion.io/x/sqlchemy"
@@ -36,14 +35,14 @@ import (
)
type SKeypairManager struct {
db.SStandaloneResourceBaseManager
db.SUserResourceBaseManager
}
var KeypairManager *SKeypairManager
func init() {
KeypairManager = &SKeypairManager{
SStandaloneResourceBaseManager: db.NewStandaloneResourceBaseManager(
SUserResourceBaseManager: db.NewUserResourceBaseManager(
SKeypair{},
"keypairs_tbl",
"keypair",
@@ -54,7 +53,7 @@ func init() {
}
type SKeypair struct {
db.SStandaloneResourceBase
db.SUserResourceBase
// 加密类型
// example: RSA
@@ -66,8 +65,6 @@ type SKeypair struct {
PrivateKey string `width:"2048" charset:"ascii" nullable:"true" create:"optional"`
// 公钥
PublicKey string `width:"1024" charset:"ascii" nullable:"false" list:"user" create:"required"`
// 用户Id
OwnerId string `width:"128" charset:"ascii" index:"true" nullable:"false" create:"required"`
}
// 列出ssh密钥对
@@ -77,22 +74,10 @@ func (manager *SKeypairManager) ListItemFilter(
userCred mcclient.TokenCredential,
query api.KeypairListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StandaloneResourceListInput)
q, err := manager.SUserResourceBaseManager.ListItemFilter(ctx, q, userCred, query.UserResourceListInput)
if err != nil {
return nil, err
}
if query.Admin != nil && *query.Admin && db.IsAdminAllowList(userCred, manager) {
user := query.User
if len(user) > 0 {
uc, _ := db.UserCacheManager.FetchUserByIdOrName(ctx, user)
if uc == nil {
return nil, httperrors.NewUserNotFoundError("user %s not found", user)
}
q = q.Equals("owner_id", uc.Id)
}
} else {
q = q.Equals("owner_id", userCred.GetUserId())
}
if len(query.Scheme) > 0 {
q = q.In("scheme", query.Scheme)
@@ -111,34 +96,22 @@ func (manager *SKeypairManager) OrderByExtraFields(
query api.KeypairListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StandaloneResourceListInput)
q, err = manager.SUserResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.UserResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStandaloneResourceBaseManager.OrderByExtraFields")
return nil, errors.Wrap(err, "SUserResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SKeypairManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
q, err = manager.SUserResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SKeypairManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return true
}
func (self *SKeypair) IsOwner(userCred mcclient.TokenCredential) bool {
return self.OwnerId == userCred.GetUserId()
}
func (self *SKeypair) AllowGetDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowGet(userCred, self)
}
func (self *SKeypair) GetExtraDetails(
ctx context.Context,
userCred mcclient.TokenCredential,
@@ -157,57 +130,30 @@ func (manager *SKeypairManager) FetchCustomizeColumns(
isList bool,
) []api.KeypairDetails {
rows := make([]api.KeypairDetails, len(objs))
stdRows := manager.SStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
userIds := make([]string, len(objs))
userRows := manager.SUserResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
keypair := objs[i].(*SKeypair)
rows[i] = api.KeypairDetails{
StandaloneResourceDetails: stdRows[i],
PrivateKeyLen: len(keypair.PrivateKey),
UserResourceDetails: userRows[i],
PrivateKeyLen: len(keypair.PrivateKey),
}
rows[i].LinkedGuestCount, _ = keypair.GetLinkedGuestsCount()
userIds[i] = keypair.OwnerId
}
users := make(map[string]db.SUser)
err := db.FetchStandaloneObjectsByIds(db.UserCacheManager, userIds, &users)
if err != nil {
log.Errorf("FetchStandaloneObjectsByIds for users fail %s", err)
return rows
}
for i := range rows {
if owner, ok := users[userIds[i]]; ok {
rows[i].OwnerName = owner.Name
}
}
return rows
}
func (manager *SKeypairManager) AllowCreateItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return true
}
func (self *SKeypair) AllowUpdateItem(ctx context.Context, userCred mcclient.TokenCredential) bool {
return self.IsOwner(userCred) || db.IsAdminAllowUpdate(userCred, self)
}
func (self *SKeypair) AllowDeleteItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowDelete(userCred, self)
}
func (self *SKeypair) GetLinkedGuestsCount() (int, error) {
return GuestManager.Query().Equals("keypair_id", self.Id).CountWithError()
}
func (manager *SKeypairManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.KeypairCreateInput) (*jsonutils.JSONDict, error) {
func (manager *SKeypairManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.KeypairCreateInput) (api.KeypairCreateInput, error) {
if len(input.PublicKey) == 0 {
if len(input.Scheme) == 0 {
input.Scheme = api.KEYPAIRE_SCHEME_RSA
}
if !utils.IsInStringArray(input.Scheme, api.KEYPAIR_SCHEMAS) {
return nil, httperrors.NewInputParameterError("Unsupported scheme %s", input.Scheme)
return input, httperrors.NewInputParameterError("Unsupported scheme %s", input.Scheme)
}
var err error
@@ -217,28 +163,26 @@ func (manager *SKeypairManager) ValidateCreateData(ctx context.Context, userCred
input.PrivateKey, input.PublicKey, err = seclib2.GenerateDSASSHKeypair()
}
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrapf(err, "Generate%sSSHKeypair", input.Scheme))
return input, httperrors.NewGeneralError(errors.Wrapf(err, "Generate%sSSHKeypair", input.Scheme))
}
}
pubKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(input.PublicKey))
if err != nil {
return nil, httperrors.NewInputParameterError("invalid public error: %v", err)
return input, httperrors.NewInputParameterError("invalid public error: %v", err)
}
// 只允许上传RSA格式密钥。PS: AWS只支持RSA格式。
input.Scheme = seclib2.GetPublicKeyScheme(pubKey)
if input.Scheme != api.KEYPAIRE_SCHEME_RSA {
return nil, httperrors.NewInputParameterError("Unsupported scheme %s", input.Scheme)
return input, httperrors.NewInputParameterError("Unsupported scheme %s", input.Scheme)
}
input.Fingerprint = ssh.FingerprintLegacyMD5(pubKey)
input.OwnerId = userCred.GetUserId()
input.StandaloneResourceCreateInput, err = manager.SStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.StandaloneResourceCreateInput)
input.UserResourceCreateInput, err = manager.SUserResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.UserResourceCreateInput)
if err != nil {
return nil, err
return input, err
}
return input.JSON(input), nil
return input, nil
}
func (self *SKeypair) ValidateDeleteCondition(ctx context.Context) error {
@@ -268,19 +212,6 @@ func (manager *SKeypairManager) FilterByOwner(q *sqlchemy.SQuery, owner mcclient
return q
}
func (self *SKeypair) GetOwnerId() mcclient.IIdentityProvider {
owner := db.SOwnerId{UserId: self.OwnerId}
return &owner
}
func (manager *SKeypairManager) FetchByName(userCred mcclient.IIdentityProvider, idStr string) (db.IModel, error) {
return db.FetchByName(manager, userCred, idStr)
}
func (manager *SKeypairManager) FetchByIdOrName(userCred mcclient.IIdentityProvider, idStr string) (db.IModel, error) {
return db.FetchByIdOrName(manager, userCred, idStr)
}
func (keypair *SKeypair) AllowGetDetailsPrivatekey(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return keypair.OwnerId == userCred.GetUserId()
}
@@ -304,15 +235,3 @@ func (keypair *SKeypair) GetDetailsPrivatekey(ctx context.Context, userCred mccl
}
return retval, nil
}
func (manager *SKeypairManager) FetchOwnerId(ctx context.Context, data jsonutils.JSONObject) (mcclient.IIdentityProvider, error) {
return db.FetchUserInfo(ctx, data)
}
func (manager *SKeypairManager) NamespaceScope() rbacutils.TRbacScope {
return rbacutils.ScopeUser
}
func (manager *SKeypairManager) ResourceScope() rbacutils.TRbacScope {
return rbacutils.ScopeUser
}

View File

@@ -424,7 +424,7 @@ func (man *SLoadbalancerAclManager) SyncLoadbalancerAcls(ctx context.Context, us
func (manager *SLoadbalancerAclManager) GetResourceCount() ([]db.SScopeResourceCount, error) {
virts := manager.Query().IsFalse("pending_deleted")
return db.CalculateProjectResourceCount(virts)
return db.CalculateResourceCount(virts, "tenant_id")
}
func (manager *SLoadbalancerAclManager) InitializeData() error {

View File

@@ -1078,7 +1078,7 @@ func (manager *SLoadbalancerBackendGroupManager) initBackendGroupRegion() error
func (manager *SLoadbalancerBackendGroupManager) GetResourceCount() ([]db.SScopeResourceCount, error) {
virts := manager.Query().IsFalse("pending_deleted")
return db.CalculateProjectResourceCount(virts)
return db.CalculateResourceCount(virts, "tenant_id")
}
func (manager *SLoadbalancerBackendGroupManager) ListItemExportKeys(ctx context.Context,

View File

@@ -648,7 +648,7 @@ func (manager *SLoadbalancerBackendManager) InitializeData() error {
func (manager *SLoadbalancerBackendManager) GetResourceCount() ([]db.SScopeResourceCount, error) {
virts := manager.Query().IsFalse("pending_deleted")
return db.CalculateProjectResourceCount(virts)
return db.CalculateResourceCount(virts, "tenant_id")
}
func (manager *SLoadbalancerBackendManager) ListItemExportKeys(ctx context.Context,

View File

@@ -402,5 +402,5 @@ func (man *SLoadbalancerCertificateManager) CreateCertificate(ctx context.Contex
func (manager *SLoadbalancerCertificateManager) GetResourceCount() ([]db.SScopeResourceCount, error) {
virts := manager.Query().IsFalse("pending_deleted")
return db.CalculateProjectResourceCount(virts)
return db.CalculateResourceCount(virts, "tenant_id")
}

View File

@@ -941,7 +941,7 @@ func (lbr *SLoadbalancerListenerRule) SyncWithCloudLoadbalancerListenerRule(
func (manager *SLoadbalancerListenerRuleManager) GetResourceCount() ([]db.SScopeResourceCount, error) {
virts := manager.Query().IsFalse("pending_deleted")
return db.CalculateProjectResourceCount(virts)
return db.CalculateResourceCount(virts, "tenant_id")
}
func (manager *SLoadbalancerListenerRuleManager) ListItemExportKeys(ctx context.Context,

View File

@@ -1236,7 +1236,7 @@ func (manager *SLoadbalancerListenerManager) InitializeData() error {
func (manager *SLoadbalancerListenerManager) GetResourceCount() ([]db.SScopeResourceCount, error) {
virts := manager.Query().IsFalse("pending_deleted")
return db.CalculateProjectResourceCount(virts)
return db.CalculateResourceCount(virts, "tenant_id")
}
func (manager *SLoadbalancerListenerManager) ListItemExportKeys(ctx context.Context,

View File

@@ -1034,7 +1034,7 @@ func (man *SLoadbalancerManager) InitializeData() error {
func (manager *SLoadbalancerManager) GetResourceCount() ([]db.SScopeResourceCount, error) {
virts := manager.Query().IsFalse("pending_deleted")
return db.CalculateProjectResourceCount(virts)
return db.CalculateResourceCount(virts, "tenant_id")
}
func (manager *SLoadbalancerManager) FetchByExternalId(providerId string, extId string) (*SLoadbalancer, error) {

View File

@@ -1015,7 +1015,7 @@ func (self *SSnapshot) getCloudProviderInfo() SCloudProviderInfo {
func (manager *SSnapshotManager) GetResourceCount() ([]db.SScopeResourceCount, error) {
virts := manager.Query().IsFalse("fake_deleted")
return db.CalculateProjectResourceCount(virts)
return db.CalculateResourceCount(virts, "tenant_id")
}
func (manager *SSnapshotManager) CleanupSnapshots(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {

View File

@@ -34,7 +34,7 @@ func InitHandlers(app *appsrv.Application) {
db.RegistUserCredCacheUpdater()
db.AddProjectResourceCountHandler("", app)
db.AddScopeResourceCountHandler("", app)
quotas.AddQuotaHandler(&models.QuotaManager.SQuotaBaseManager, "", app)
quotas.AddQuotaHandler(&models.RegionQuotaManager.SQuotaBaseManager, "", app)

View File

@@ -36,7 +36,7 @@ func InitHandlers(app *appsrv.Application) {
db.RegistUserCredCacheUpdater()
db.AddProjectResourceCountHandler(API_VERSION, app)
db.AddScopeResourceCountHandler(API_VERSION, app)
quotas.AddQuotaHandler(&models.QuotaManager.SQuotaBaseManager, API_VERSION, app)
usages.AddUsageHandler(API_VERSION, app)

View File

@@ -22,6 +22,7 @@ import (
"yunion.io/x/log"
"yunion.io/x/onecloud/pkg/apis"
api "yunion.io/x/onecloud/pkg/apis/identity"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/keystone/models"
@@ -45,16 +46,16 @@ type sServiceEndpoints struct {
external string
}
func FetchProjectResourceCount(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
log.Debugf("FetchProjectResourceCount")
func FetchScopeResourceCount(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
log.Debugf("FetchScopeResourceCount")
eps, err := models.EndpointManager.FetchAll()
if err != nil {
return
}
serviceTbl := make(map[string]*sServiceEndpoints)
for _, ep := range eps {
if ep.ServiceType == api.SERVICE_TYPE {
// skip self
if ep.ServiceType == apis.SERVICE_TYPE_KEYSTONE || ep.ServiceType == apis.SERVICE_TYPE_OFFLINE_CLOUDMETA {
// skip self and offline cloudmeta
continue
}
key := fmt.Sprintf("%s-%s", ep.RegionId, ep.ServiceId)
@@ -81,11 +82,10 @@ func FetchProjectResourceCount(ctx context.Context, userCred mcclient.TokenCrede
if url == "" {
url = ep.external
}
url = httputils.JoinPath(url, "project-resources")
url = httputils.JoinPath(url, "scope-resources")
tk, _ := tokens.GetDefaultToken()
hdr := http.Header{}
hdr.Add("X-Auth-Token", tk)
// log.Debugf("request %s", url)
_, ret, err := httputils.JSONRequest(
httputils.GetDefaultClient(),
ctx, "GET",
@@ -111,48 +111,57 @@ func FetchProjectResourceCount(ctx context.Context, userCred mcclient.TokenCrede
if err != nil {
continue
}
syncProjectResourceCount(ctx, ep.regionId, ep.serviceId, projectResCounts)
syncScopeResourceCount(ctx, ep.regionId, ep.serviceId, projectResCounts)
}
}
func syncProjectResourceCount(ctx context.Context, regionId string, serviceId string, projResCnt map[string][]db.SScopeResourceCount) {
func syncScopeResourceCount(ctx context.Context, regionId string, serviceId string, projResCnt map[string][]db.SScopeResourceCount) {
projList := make([]string, 0)
domainList := []string{}
ownerList := []string{}
for res, resCnts := range projResCnt {
for i := range resCnts {
if len(resCnts[i].TenantId) == 0 && len(resCnts[i].DomainId) == 0 {
if len(resCnts[i].TenantId) == 0 && len(resCnts[i].DomainId) == 0 && len(resCnts[i].OwnerId) == 0 {
continue
}
projRes := models.SProjectResource{}
if len(resCnts[i].TenantId) > 0 {
projRes.ProjectId = resCnts[i].TenantId
} else {
projRes.ProjectId = resCnts[i].DomainId
scopeRes := models.SScopeResource{
DomainId: resCnts[i].DomainId,
ProjectId: resCnts[i].TenantId,
OwnerId: resCnts[i].OwnerId,
}
projRes.RegionId = regionId
projRes.ServiceId = serviceId
projRes.Resource = res
projRes.Count = resCnts[i].ResCount
scopeRes.RegionId = regionId
scopeRes.ServiceId = serviceId
scopeRes.Resource = res
scopeRes.Count = resCnts[i].ResCount
projList = append(projList, projRes.ProjectId)
projList = append(projList, scopeRes.ProjectId)
domainList = append(domainList, scopeRes.DomainId)
ownerList = append(ownerList, scopeRes.OwnerId)
err := models.ProjectResourceManager.TableSpec().InsertOrUpdate(ctx, &projRes)
err := models.ScopeResourceManager.TableSpec().InsertOrUpdate(ctx, &scopeRes)
if err != nil {
log.Errorf("table insert error %s", err)
}
}
q := models.ProjectResourceManager.Query()
q := models.ScopeResourceManager.Query()
if len(projList) > 0 {
q = q.NotIn("project_id", projList)
}
if len(domainList) > 0 {
q = q.NotIn("domain_id", domainList)
}
if len(ownerList) > 0 {
q = q.NotIn("owner_id", ownerList)
}
q = q.Equals("region_id", regionId)
q = q.Equals("service_id", serviceId)
q = q.Equals("resource", res)
q = q.NotEquals("count", 0)
emptySets := make([]models.SProjectResource, 0)
err := db.FetchModelObjects(models.ProjectResourceManager, q, &emptySets)
emptySets := make([]models.SScopeResource, 0)
err := db.FetchModelObjects(models.ScopeResourceManager, q, &emptySets)
if err != nil {
log.Errorf("db.FetchModelObjects %s", err)
}

View File

@@ -359,7 +359,7 @@ func (manager *SDomainManager) FetchCustomizeColumns(
if update.IsZero() {
update = time.Now()
}
nextUpdate := update.Add(time.Duration(options.Options.FetchProjectResourceCountIntervalSeconds) * time.Second)
nextUpdate := update.Add(time.Duration(options.Options.FetchScopeResourceCountIntervalSeconds) * time.Second)
rows[i].ExtResourcesNextUpdate = nextUpdate
}
}
@@ -485,7 +485,7 @@ func (domain *SDomain) UnlinkIdp(idpId string) error {
}
func (domain *SDomain) getExternalResources() (map[string]int, time.Time, error) {
return ProjectResourceManager.getProjectResource(domain.Id)
return ScopeResourceManager.getScopeResource(domain.Id, "", "")
}
func (manager *SDomainManager) ValidateCreateData(

Some files were not shown because too many files have changed in this diff Show More