From 258db2cb483fa5b6fe94aafd2919e6fa2cd3ca44 Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Thu, 26 Mar 2020 13:13:14 +0800 Subject: [PATCH] fix updates --- cmd/climc/shell/cloudaccounts.go | 4 +- cmd/climc/shell/hosts.go | 29 +++++++++ cmd/climc/shell/images.go | 10 ++-- cmd/climc/shell/networks.go | 5 +- pkg/apis/compute/bucket.go | 4 +- .../compute/cachedloadbalancercertificate.go | 6 +- pkg/apis/compute/dbinstance.go | 12 +++- pkg/apis/compute/disk.go | 14 ++++- pkg/apis/compute/elasticcache.go | 8 ++- pkg/apis/compute/globalvpc.go | 12 +++- pkg/apis/compute/groupguest.go | 2 +- pkg/apis/compute/guests.go | 37 ++++-------- pkg/apis/compute/input.go | 6 +- pkg/apis/compute/instance_group.go | 8 ++- pkg/apis/compute/loadbalancer.go | 52 ++++++++++++---- pkg/apis/compute/loadbalancerbackendgroup.go | 10 +++- pkg/apis/compute/loadbalancercluster.go | 12 ++-- pkg/apis/compute/loadbalancerlistener.go | 10 +++- pkg/apis/compute/natgateway.go | 12 +++- pkg/apis/compute/network.go | 16 +++-- pkg/apis/compute/routetable.go | 2 +- pkg/apis/compute/schedtag.go | 6 +- pkg/apis/compute/secgroup.go | 10 +++- pkg/apis/compute/storage_const.go | 8 ++- pkg/apis/identity/domain.go | 2 + pkg/apis/identity/output.go | 3 +- pkg/apis/identity/project.go | 15 +++-- pkg/apis/input.go | 2 +- pkg/apis/share.go | 24 ++++++++ pkg/cloudcommon/db/infraresource.go | 45 ++++++++++++++ pkg/cloudcommon/db/interface.go | 4 +- pkg/cloudcommon/db/opslog.go | 1 + pkg/cloudcommon/db/project_resources.go | 33 +++++----- pkg/cloudcommon/db/sharablebase.go | 35 ++++++++++- pkg/cloudcommon/db/sharablevirtual.go | 39 ++++++++++++ pkg/cloudcommon/db/sharedresource.go | 12 ++-- pkg/cloudcommon/db/tenantcache.go | 5 +- pkg/cloudcommon/options/manager.go | 3 +- pkg/cloudprovider/resources.go | 5 +- pkg/compute/models/baremetalagents.go | 6 +- pkg/compute/models/cloudaccounts.go | 9 +++ pkg/compute/models/cloudproviders.go | 5 ++ pkg/compute/models/cloudregionresource.go | 15 +++++ pkg/compute/models/cloudsync.go | 2 +- pkg/compute/models/dbinstanceresource.go | 25 +++++--- pkg/compute/models/diskresource.go | 21 +++++-- pkg/compute/models/elasticcacheresource.go | 21 +++++-- pkg/compute/models/globalvpcresource.go | 21 +++++-- pkg/compute/models/groupguests.go | 4 +- pkg/compute/models/groupresource.go | 21 +++++-- pkg/compute/models/guestjoints.go | 4 +- pkg/compute/models/guestresource.go | 29 +++++---- pkg/compute/models/guests.go | 3 +- pkg/compute/models/hostresource.go | 21 +++++-- pkg/compute/models/hosts.go | 6 +- pkg/compute/models/loadbalanceracls.go | 2 +- .../loadbalancerbackendgroupresource.go | 21 +++++-- .../models/loadbalancerbackendgroups.go | 2 +- pkg/compute/models/loadbalancerbackends.go | 2 +- .../models/loadbalancercertificateresource.go | 21 +++++-- .../models/loadbalancercertificates.go | 2 +- .../models/loadbalancerclusterresource.go | 21 +++++-- .../models/loadbalancerlistenerresource.go | 21 +++++-- .../models/loadbalancerlistenerrules.go | 2 +- pkg/compute/models/loadbalancerlisteners.go | 2 +- pkg/compute/models/loadbalancerresource.go | 21 +++++-- pkg/compute/models/loadbalancers.go | 60 ++++++++++++------- pkg/compute/models/managedresource.go | 29 +++++---- pkg/compute/models/natgatewayresource.go | 21 +++++-- pkg/compute/models/networkresource.go | 21 +++++-- pkg/compute/models/networks.go | 33 ++++++---- pkg/compute/models/regiondrivers.go | 2 +- pkg/compute/models/routetables.go | 3 +- pkg/compute/models/schedtagresource.go | 21 +++++-- pkg/compute/models/secgroupresource.go | 21 +++++-- pkg/compute/models/secgroups.go | 9 +-- pkg/compute/models/snapshotpolicyresource.go | 21 +++++-- pkg/compute/models/snapshots.go | 2 +- pkg/compute/models/storageresource.go | 21 +++++-- pkg/compute/models/storages.go | 5 +- pkg/compute/models/vpcresource.go | 11 ++-- pkg/compute/models/vpcs.go | 3 +- pkg/compute/models/wireresource.go | 21 +++++-- pkg/compute/models/wires.go | 10 ++-- pkg/compute/models/zoneresource.go | 9 +-- pkg/compute/regiondrivers/aliyun.go | 5 +- pkg/compute/regiondrivers/aws.go | 5 +- pkg/compute/regiondrivers/azure.go | 2 +- pkg/compute/regiondrivers/ctyun.go | 2 +- pkg/compute/regiondrivers/esxi.go | 2 +- pkg/compute/regiondrivers/huawei.go | 5 +- pkg/compute/regiondrivers/kvm.go | 3 +- pkg/compute/regiondrivers/managedvirtual.go | 2 +- pkg/compute/regiondrivers/openstack.go | 2 +- pkg/compute/regiondrivers/qcloud.go | 5 +- pkg/compute/regiondrivers/ucloud.go | 2 +- pkg/compute/regiondrivers/zstack.go | 2 +- pkg/compute/tasks/network_create_task.go | 2 +- pkg/compute/tasks/network_syncstatus_task.go | 2 +- pkg/keystone/cronjobs/project_resources.go | 16 +++-- pkg/keystone/models/domains.go | 21 +++++++ pkg/keystone/models/policies.go | 15 ++++- pkg/keystone/models/roles.go | 15 ++++- pkg/keystone/service/handlers.go | 2 + pkg/keystone/service/service.go | 2 +- 105 files changed, 916 insertions(+), 372 deletions(-) create mode 100644 pkg/apis/share.go diff --git a/cmd/climc/shell/cloudaccounts.go b/cmd/climc/shell/cloudaccounts.go index 58d1394f19..10286e01c2 100644 --- a/cmd/climc/shell/cloudaccounts.go +++ b/cmd/climc/shell/cloudaccounts.go @@ -1012,10 +1012,10 @@ func init() { type ClouaccountChangeProjectOptions struct { ID string `help:"ID or name of cloudaccount" json:"-"` - Project string `json:"project" help:"target domain"` + PROJECT string `json:"project" help:"target domain"` } R(&ClouaccountChangeProjectOptions{}, "cloud-account-change-project", "Change domain/project of cloudaccount", func(s *mcclient.ClientSession, args *ClouaccountChangeProjectOptions) error { - if len(args.Project) == 0 { + if len(args.PROJECT) == 0 { return fmt.Errorf("empty project") } params := jsonutils.Marshal(args) diff --git a/cmd/climc/shell/hosts.go b/cmd/climc/shell/hosts.go index 476ce978b7..33ba0d8593 100644 --- a/cmd/climc/shell/hosts.go +++ b/cmd/climc/shell/hosts.go @@ -723,4 +723,33 @@ func init() { printObject(ret) return nil }) + + type HostPublicOptions struct { + ID string `help:"ID or name of host" json:"-"` + Scope string `help:"sharing scope" choices:"system|domain|project"` + SharedProjects []string `help:"Share to prjects"` + SharedDomains []string `help:"share to domains"` + } + R(&HostPublicOptions{}, "host-public", "Make a host public", func(s *mcclient.ClientSession, args *HostPublicOptions) error { + params := jsonutils.Marshal(args) + result, err := modules.Hosts.PerformAction(s, args.ID, "public", params) + if err != nil { + return err + } + printObject(result) + return nil + }) + + type HostPrivateOptions struct { + ID string `help:"ID or name of host" json:"-"` + } + R(&HostPrivateOptions{}, "host-private", "Make a host private", func(s *mcclient.ClientSession, args *HostPrivateOptions) error { + params := jsonutils.Marshal(args) + result, err := modules.Hosts.PerformAction(s, args.ID, "private", params) + if err != nil { + return err + } + printObject(result) + return nil + }) } diff --git a/cmd/climc/shell/images.go b/cmd/climc/shell/images.go index 22f11b1ed0..9924b4039b 100644 --- a/cmd/climc/shell/images.go +++ b/cmd/climc/shell/images.go @@ -416,14 +416,12 @@ func init() { type ImagePublicOptions struct { ID []string `help:"ID or name of image" json:"-"` - Scope string `help:"sharing scope" choices:"system|domain"` - ShareToProject []string `help:"Share to prject"` + Scope string `help:"sharing scope" choices:"system|domain|project"` + SharedProjects []string `help:"Share to projects"` + SharedDomains []string `help:"Share to domains"` } R(&ImagePublicOptions{}, "image-public", "Make a image public", func(s *mcclient.ClientSession, args *ImagePublicOptions) error { - params, err := options.StructToParams(args) - if err != nil { - return err - } + params := jsonutils.Marshal(args) if len(args.ID) == 0 { return fmt.Errorf("No image ID provided") } else if len(args.ID) == 1 { diff --git a/cmd/climc/shell/networks.go b/cmd/climc/shell/networks.go index b6682acf72..ac0c5d65b3 100644 --- a/cmd/climc/shell/networks.go +++ b/cmd/climc/shell/networks.go @@ -180,8 +180,9 @@ func init() { type NetworkShareOptions struct { NetworkIdOptions - Scope string `help:"sharing scope" choices:"system|domain"` - ShareToProject []string `help:"Share to prject"` + Scope string `help:"sharing scope" choices:"system|domain|project"` + SharedProjects []string `help:"Share to prjects"` + SharedDomains []string `help:"share to domains"` } R(&NetworkShareOptions{}, "network-public", "Make a network public", func(s *mcclient.ClientSession, args *NetworkShareOptions) error { params, err := options.StructToParams(args) diff --git a/pkg/apis/compute/bucket.go b/pkg/apis/compute/bucket.go index 4ff12957f0..b6a5fd1c4f 100644 --- a/pkg/apis/compute/bucket.go +++ b/pkg/apis/compute/bucket.go @@ -44,8 +44,8 @@ const ( type BucketCreateInput struct { apis.VirtualResourceCreateInput - RegionalResourceCreateInput - ManagedResourceCreateInput + CloudregionResourceInput + CloudproviderResourceInput StorageClass string `json:"storage_class"` } diff --git a/pkg/apis/compute/cachedloadbalancercertificate.go b/pkg/apis/compute/cachedloadbalancercertificate.go index 7f9db9bdac..7a8ec1ef25 100644 --- a/pkg/apis/compute/cachedloadbalancercertificate.go +++ b/pkg/apis/compute/cachedloadbalancercertificate.go @@ -37,13 +37,17 @@ type LoadbalancerCertificateResourceInfo struct { Certificate string `json:"certificate"` } -type LoadbalancerCertificateFilterListInput struct { +type LoadbalancerCertificateResourceInput struct { // 证书名称或ID Certificate string `json:"certificate"` // swagger:ignore // Deprecated CertificateId string `json:"certificate_id" deprecated-by:"certificate"` +} + +type LoadbalancerCertificateFilterListInput struct { + LoadbalancerCertificateResourceInput // 以证书名称排序 OrderByCertificate string `json:"order_by_certificate"` diff --git a/pkg/apis/compute/dbinstance.go b/pkg/apis/compute/dbinstance.go index 5f74cc8e03..90af8f482e 100644 --- a/pkg/apis/compute/dbinstance.go +++ b/pkg/apis/compute/dbinstance.go @@ -300,10 +300,18 @@ type DBInstanceResourceInfo struct { VpcResourceInfo } -type DBInstanceFilterListInputBase struct { - // 以RDS实例过滤 +type DBInstanceResourceInput struct { + // RDS实例(ID or Name) DBInstance string `json:"dbinstance"` + // swagger:ignore + // Deprecated + DBInstanceId string `json:"dbinstance_id" deprecated-by:"dbinstance"` +} + +type DBInstanceFilterListInputBase struct { + DBInstanceResourceInput + // 以RDS实例名字排序 OrderByDBInstance string `json:"order_by_dbinstance"` } diff --git a/pkg/apis/compute/disk.go b/pkg/apis/compute/disk.go index f75fe0b451..3d1a4b48fb 100644 --- a/pkg/apis/compute/disk.go +++ b/pkg/apis/compute/disk.go @@ -84,13 +84,17 @@ func (req *ServerCreateInput) ToDiskCreateInput() *DiskCreateInput { return &input } -type SnapshotPolicyFilterListInput struct { +type SnapshotPolicyResourceInput struct { // filter disk by snapshotpolicy Snapshotpolicy string `json:"snapshotpolicy"` // swagger:ignore // Deprecated // filter disk by snapshotpolicy_id SnapshotpolicyId string `json:"snapshotpolicy_id" deprecated-by:"snapshotpolicy"` +} + +type SnapshotPolicyFilterListInput struct { + SnapshotPolicyResourceInput // 以快照策略名称排序 OrderBySnapshotpolicy string `json:"order_by_snapshotpolicy"` @@ -144,13 +148,17 @@ type DiskListInput struct { SnapshotId string `json:"snapshot_id" deprecated-by:"snapshot"` } -type DiskFilterListInputBase struct { - // 以指定虚拟磁盘(ID或Name)过滤列表结果 +type DiskResourceInput struct { + // 虚拟磁盘(ID或Name) Disk string `json:"disk"` // swagger:ignore // Deprecated // filter by disk_id DiskId string `json:"disk_id" deprecated-by:"disk"` +} + +type DiskFilterListInputBase struct { + DiskResourceInput // 以磁盘名称排序 // pattern:asc|desc diff --git a/pkg/apis/compute/elasticcache.go b/pkg/apis/compute/elasticcache.go index 3718cb45bb..b7e15dd0a6 100644 --- a/pkg/apis/compute/elasticcache.go +++ b/pkg/apis/compute/elasticcache.go @@ -47,13 +47,17 @@ type ElasticcacheResourceInfo struct { ZoneResourceInfoBase } -type ElasticcacheFilterListInput struct { - // 以弹性缓存实例过滤 +type ELasticcacheResourceInput struct { + // 弹性缓存实例(ID or Name) Elasticcache string `json:"elasticcache"` // swagger:ignore // Deprecated ElasticcacheId string `json:"elasticcache_id" deprecated-by:"elasticcache"` +} + +type ElasticcacheFilterListInput struct { + ELasticcacheResourceInput // 以弹性缓存实例名称排序 OrderByElasticcache string `json:"order_by_elasticcache"` diff --git a/pkg/apis/compute/globalvpc.go b/pkg/apis/compute/globalvpc.go index dbdb38756a..9942e51f3f 100644 --- a/pkg/apis/compute/globalvpc.go +++ b/pkg/apis/compute/globalvpc.go @@ -33,10 +33,18 @@ type GlobalVpcResourceInfo struct { Globalvpc string `json:"globalvpc"` } -type GlobalVpcResourceListInput struct { - // 以GlobalVpc的过滤 +type GlobalVpcResourceInput struct { + // GlobalVpc ID or Name Globalvpc string `json:"globalvpc"` + // swagger:ignore + // Deprecated + GlobalvpcId string `json:"globalvpc_id" deprecated-by:"globalvpc"` +} + +type GlobalVpcResourceListInput struct { + GlobalVpcResourceInput + // 以GlobalVpc的名称排序 OrderByGlobalvpc string `json:"order_by_globalvpc"` } diff --git a/pkg/apis/compute/groupguest.go b/pkg/apis/compute/groupguest.go index c2f84f293f..19fd67de85 100644 --- a/pkg/apis/compute/groupguest.go +++ b/pkg/apis/compute/groupguest.go @@ -41,7 +41,7 @@ type GroupguestDetails struct { type GroupguestListInput struct { GroupJointsListInput - GuestFilterListInput + ServerFilterListInput // 标签 Tag []string `json:"tag"` diff --git a/pkg/apis/compute/guests.go b/pkg/apis/compute/guests.go index 87a4614b37..0e64658a36 100644 --- a/pkg/apis/compute/guests.go +++ b/pkg/apis/compute/guests.go @@ -23,23 +23,6 @@ import ( "yunion.io/x/onecloud/pkg/apis/billing" ) -type ServerFilterListInput struct { - // 以关联主机(ID或Name)过滤列表 - Server string `json:"server"` - // swagger:ignore - // Deprecated - // Filter by guest Id - ServerId string `json:"server_id" deprecated-by:"server"` - // swagger:ignore - // Deprecated - // Filter by guest Id - Guest string `json:"guest" deprecated-by:"server"` - // swagger:ignore - // Deprecated - // Filter by guest Id - GuestId string `json:"guest_id" deprecated-by:"server"` -} - type ServerListInput struct { apis.VirtualResourceListInput apis.ExternalizedResourceBaseListInput @@ -250,7 +233,7 @@ type GuestJointResourceDetails struct { type GuestJointsListInput struct { apis.VirtualJointResourceBaseListInput - GuestFilterListInput + ServerFilterListInput } type GuestResourceInfo struct { @@ -266,23 +249,29 @@ type GuestResourceInfo struct { HostResourceInfo } -type GuestFilterListInput struct { - HostFilterListInput - - // 以指定虚拟主机(ID或Name)过滤列表结果 +type ServerResourceInput struct { + // 主机(ID或Name) Server string `json:"server"` // swagger:ignore // Deprecated + // Filter by guest Id ServerId string `json:"server_id" deprecated-by:"server"` // swagger:ignore // Deprecated + // Filter by guest Id Guest string `json:"guest" deprecated-by:"server"` // swagger:ignore // Deprecated + // Filter by guest Id GuestId string `json:"guest_id" deprecated-by:"server"` +} - // 以虚拟主机名称排序 - // pattern:asc|desc +type ServerFilterListInput struct { + HostFilterListInput + + ServerResourceInput + + // 以主机名称排序 OrderByServer string `json:"order_by_server"` } diff --git a/pkg/apis/compute/input.go b/pkg/apis/compute/input.go index 004dbc65fb..dc8bc229a2 100644 --- a/pkg/apis/compute/input.go +++ b/pkg/apis/compute/input.go @@ -18,15 +18,17 @@ import ( "yunion.io/x/onecloud/pkg/apis" ) +/* type RegionalResourceCreateInput struct { Cloudregion string `json:"cloudregion"` CloudregionId string `json:"cloudregion_id"` } -type ManagedResourceCreateInput struct { - Manager string `json:"manager"` +type ManagedResourceInput struct { + Manager string `json:"manager"` ManagerId string `json:"manager_id"` } +*/ type DeletePreventableCreateInput struct { //删除保护,创建的资源默认不允许删除 diff --git a/pkg/apis/compute/instance_group.go b/pkg/apis/compute/instance_group.go index d09ac7f6df..8c8412c8bb 100644 --- a/pkg/apis/compute/instance_group.go +++ b/pkg/apis/compute/instance_group.go @@ -44,13 +44,17 @@ type InstanceGroupDetail struct { GuestCount int `json:"guest_count"` } -type GroupFilterListInput struct { - // 以指定实例组(ID或Name)过滤列表结果 +type GroupResourceInput struct { + // 实例组(ID或Name) Group string `json:"group"` // swagger:ignore // Deprecated // Filter by instance group Id GroupId string `json:"group_id" deprecated-by:"group"` +} + +type GroupFilterListInput struct { + GroupResourceInput // 按组名排序 OrderByGroup string `json:"order_by_group"` diff --git a/pkg/apis/compute/loadbalancer.go b/pkg/apis/compute/loadbalancer.go index 8a09818c40..e159d2ce11 100644 --- a/pkg/apis/compute/loadbalancer.go +++ b/pkg/apis/compute/loadbalancer.go @@ -15,6 +15,8 @@ package compute import ( + "yunion.io/x/jsonutils" + "yunion.io/x/onecloud/pkg/apis" "yunion.io/x/onecloud/pkg/util/ansible" ) @@ -194,17 +196,21 @@ type LoadbalancerResourceInfo struct { ZoneResourceInfoBase } -type LoadbalancerFilterListInput struct { - VpcFilterListInput - - ZonalFilterListBase - +type LoadbalancerResourceInput struct { // 负载均衡名称 Loadbalancer string `json:"loadbalancer"` // swagger:ignore // Deprecated LoadbalancerId string `json:"loadbalancer_id" deprecated-by:"loadbalancer"` +} + +type LoadbalancerFilterListInput struct { + VpcFilterListInput + + ZonalFilterListBase + + LoadbalancerResourceInput // 以负载均衡名称排序 OrderByLoadbalancer string `json:"order_by_loadbalancer"` @@ -213,11 +219,35 @@ type LoadbalancerFilterListInput struct { type LoadbalancerCreateInput struct { apis.VirtualResourceCreateInput - SLoadbalancer + // IP地址 + Address string `json:"address"` + // 地址类型 + AddressType string `json:"address_type"` + // 网络类型 + NetworkType string `json:"network_type"` - Vpc string `json:"vpc"` - Zone string `json:"zone"` - Cloudregion string `json:"cloudregion"` - Network string `json:"network"` - Manager string `json:"manager"` + // 负载均衡集群Id + ClusterId string `json:"cluster_id"` + + // 计费类型 + ChargeType string `json:"charge_type"` + + // 套餐名称 + LoadbalancerSpec string `json:"loadbalancer_spec"` + + // LB的其他配置信息 + LBInfo jsonutils.JSONObject `json:"lb_info"` + + // SLoadbalancer + + VpcResourceInput + // Vpc string `json:"vpc"` + ZoneResourceInput + // Zone string `json:"zone"` + CloudregionResourceInput + // Cloudregion string `json:"cloudregion"` + NetworkResourceInput + // Network string `json:"network"` + CloudproviderResourceInput + // Manager string `json:"manager"` } diff --git a/pkg/apis/compute/loadbalancerbackendgroup.go b/pkg/apis/compute/loadbalancerbackendgroup.go index b307a73553..b20d3b382b 100644 --- a/pkg/apis/compute/loadbalancerbackendgroup.go +++ b/pkg/apis/compute/loadbalancerbackendgroup.go @@ -33,15 +33,19 @@ type LoadbalancerBackendGroupResourceInfo struct { LoadbalancerId string `json:"loadbalancer_id"` } -type LoadbalancerBackendGroupFilterListInput struct { - LoadbalancerFilterListInput - +type LoadbalancerBackendGroupResourceInput struct { // 负载均衡后端组ID或名称 BackendGroup string `json:"backend_group"` // swagger:ignore // Deprecated BackendGroupId string `json:"backend_group_id" deprecated-by:"backend_group"` +} + +type LoadbalancerBackendGroupFilterListInput struct { + LoadbalancerFilterListInput + + LoadbalancerBackendGroupResourceInput // 以负载均衡后端组名称排序 OrderByBackendGroup string `json:"order_by_backend_group"` diff --git a/pkg/apis/compute/loadbalancercluster.go b/pkg/apis/compute/loadbalancercluster.go index 355960933b..23e74658fb 100644 --- a/pkg/apis/compute/loadbalancercluster.go +++ b/pkg/apis/compute/loadbalancercluster.go @@ -39,16 +39,20 @@ type LoadbalancerClusterResourceInfo struct { Cluster string `json:"cluster"` } -type LoadbalancerClusterFilterListInput struct { - ZonalFilterListInput - WireFilterListBase - +type LoadbalancerClusterResourceInput struct { // 负载均衡集群ID或名称 Cluster string `json:"cluster"` // swagger:ignore // Deprecated ClusterId string `json:"cluster_id" deprecated-by:"cluster"` +} + +type LoadbalancerClusterFilterListInput struct { + ZonalFilterListInput + WireFilterListBase + + LoadbalancerClusterResourceInput // 以负载均衡集群排序 OrderByCluster string `json:"order_by_cluster"` diff --git a/pkg/apis/compute/loadbalancerlistener.go b/pkg/apis/compute/loadbalancerlistener.go index 2b0b3b8d74..42ee9c1d12 100644 --- a/pkg/apis/compute/loadbalancerlistener.go +++ b/pkg/apis/compute/loadbalancerlistener.go @@ -38,9 +38,7 @@ type LoadbalancerListenerResourceInfo struct { LoadbalancerResourceInfo } -type LoadbalancerListenerFilterListInput struct { - LoadbalancerFilterListInput - +type LoadbalancerListenerResourceInput struct { // 负载均衡监听器 Listener string `json:"listener"` @@ -48,6 +46,12 @@ type LoadbalancerListenerFilterListInput struct { // swagger:ignore // Deprecated ListenerId string `json:"listener_id" deprecated-by:"listener"` +} + +type LoadbalancerListenerFilterListInput struct { + LoadbalancerFilterListInput + + LoadbalancerListenerResourceInput // 以负载均衡监听器名称排序 OrderByListener string `json:"order_by_listener"` diff --git a/pkg/apis/compute/natgateway.go b/pkg/apis/compute/natgateway.go index 82de740055..992076460f 100644 --- a/pkg/apis/compute/natgateway.go +++ b/pkg/apis/compute/natgateway.go @@ -83,10 +83,18 @@ type NatGatewayResourceInfo struct { VpcResourceInfo } -type NatGatewayFilterListInput struct { - // 以NAT网关过滤 +type NatGatewayResourceInput struct { + // NAT网关ID or Name Natgateway string `json:"natgateway"` + // swagger:ignore + // Deprecated + NatgatewayId string `json:"natgateway_id" deprecated-by:"natgateway"` +} + +type NatGatewayFilterListInput struct { + NatGatewayResourceInput + // 以NAT网关名字排序 OrderByNatgateway string `json:"order_by_natgateway"` diff --git a/pkg/apis/compute/network.go b/pkg/apis/compute/network.go index 22ff1b0445..cbcd518c8e 100644 --- a/pkg/apis/compute/network.go +++ b/pkg/apis/compute/network.go @@ -18,13 +18,17 @@ import ( "yunion.io/x/onecloud/pkg/apis" ) -type WireFilterListBase struct { - // 过滤连接此二层网络(ID或Name)的资源 +type WireResourceInput struct { + // 二层网络(ID或Name)的资源 Wire string `json:"wire"` // swagger:ignore // Deprecated // fitler by wire id WireId string `json:"wire_id" deprecated-by:"wire"` +} + +type WireFilterListBase struct { + WireResourceInput // 以二层网络名称排序 OrderByWire string `json:"order_by_wire"` @@ -37,13 +41,17 @@ type WireFilterListInput struct { WireFilterListBase } -type NetworkFilterListBase struct { - // 过滤关联此IP子网(ID或Name)的资源 +type NetworkResourceInput struct { + // IP子网(ID或Name) Network string `json:"network"` // swagger:ignore // Deprecated // filter by networkId NetworkId string `json:"network_id" deprecated-by:"network"` +} + +type NetworkFilterListBase struct { + NetworkResourceInput // 以IP子网的名称排序 OrderByNetwork string `json:"order_by_network"` diff --git a/pkg/apis/compute/routetable.go b/pkg/apis/compute/routetable.go index e0679088a5..4d98099a43 100644 --- a/pkg/apis/compute/routetable.go +++ b/pkg/apis/compute/routetable.go @@ -19,10 +19,10 @@ import ( "reflect" "strings" + "yunion.io/x/jsonutils" "yunion.io/x/pkg/errors" "yunion.io/x/pkg/gotypes" - "yunion.io/x/jsonutils" "yunion.io/x/onecloud/pkg/apis" "yunion.io/x/onecloud/pkg/httperrors" ) diff --git a/pkg/apis/compute/schedtag.go b/pkg/apis/compute/schedtag.go index ad2d84372e..829cdd0653 100644 --- a/pkg/apis/compute/schedtag.go +++ b/pkg/apis/compute/schedtag.go @@ -39,13 +39,17 @@ type SchedtagCreateInput struct { ResourceType string `json:"resource_type"` } -type SchedtagFilterListInput struct { +type SchedtagResourceInput struct { // 以关联的调度标签(ID或Name)过滤列表 Schedtag string `json:"schedtag"` // swagger:ignore // Deprecated // filter by schedtag_id SchedtagId string `json:"schedtag_id" deprecated-by:"schedtag"` +} + +type SchedtagFilterListInput struct { + SchedtagResourceInput // 按调度标签名称排序 // pattern:asc|desc diff --git a/pkg/apis/compute/secgroup.go b/pkg/apis/compute/secgroup.go index 556b58ba92..6de90f00a2 100644 --- a/pkg/apis/compute/secgroup.go +++ b/pkg/apis/compute/secgroup.go @@ -132,11 +132,11 @@ type SSecgroupCreateInput struct { type SecgroupListInput struct { apis.SharableVirtualResourceListInput + ServerFilterListInput + // equals Equals string - ServerFilterListInput - // 按缓存数量排序 // pattern:asc|desc OrderByCacheCnt string `json:"order_by_cache_cnt"` @@ -172,13 +172,17 @@ type SecurityGroupRuleListInput struct { Protocol string `json:"protocol"` } -type SecgroupFilterListInput struct { +type SecgroupResourceInput struct { // 过滤关联指定安全组(ID或Name)的列表结果 Secgroup string `json:"secgroup"` // swagger:ignore // Deprecated // filter by secgroup_id SecgroupId string `json:"secgroup_id" deprecated-by:"secgroup"` +} + +type SecgroupFilterListInput struct { + SecgroupResourceInput // 以安全组排序 OrderBySecgroup string `json:"order_by_secgroup"` diff --git a/pkg/apis/compute/storage_const.go b/pkg/apis/compute/storage_const.go index aebc980e6f..85ad3070f9 100644 --- a/pkg/apis/compute/storage_const.go +++ b/pkg/apis/compute/storage_const.go @@ -138,13 +138,17 @@ var ( SHARED_STORAGE = []string{STORAGE_NFS, STORAGE_GPFS, STORAGE_RBD} ) -type StorageFilterListInputBase struct { - // 过滤关联此存储(ID或Name)的列表结果 +type StorageResourceInput struct { + // 存储(ID或Name) Storage string `json:"storage"` // swagger:ignore // Deprecated // filter by storage_id StorageId string `json:"storage_id" deprecated-by:"storage"` +} + +type StorageFilterListInputBase struct { + StorageResourceInput // 以存储名称排序 // pattern:asc|desc diff --git a/pkg/apis/identity/domain.go b/pkg/apis/identity/domain.go index 3f98daff29..73248672e9 100644 --- a/pkg/apis/identity/domain.go +++ b/pkg/apis/identity/domain.go @@ -28,6 +28,8 @@ type DomainDetails struct { RoleCount int `json:"role_count"` PolicyCount int `json:"policy_count"` IdpCount int `json:"idp_count"` + + ExternalResourceInfo } type DomainUpdateInput struct { diff --git a/pkg/apis/identity/output.go b/pkg/apis/identity/output.go index bbfcd1c605..e6f6acfa17 100644 --- a/pkg/apis/identity/output.go +++ b/pkg/apis/identity/output.go @@ -1,6 +1,5 @@ // Copyright 2019 Yunion -// 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 diff --git a/pkg/apis/identity/project.go b/pkg/apis/identity/project.go index fa3a9fe39f..51f993b7e2 100644 --- a/pkg/apis/identity/project.go +++ b/pkg/apis/identity/project.go @@ -20,14 +20,19 @@ import ( "yunion.io/x/jsonutils" ) +type ExternalResourceInfo struct { + ExtResource jsonutils.JSONObject `json:"ext_resource"` + ExtResourcesLastUpdate time.Time `json:"ext_resources_last_update"` + ExtResourcesNextUpdate time.Time `json:"ext_resources_next_update"` +} + type ProjectDetails struct { IdentityBaseResourceDetails SProject - GroupCount int `json:"group_count"` - UserCount int `json:"user_count"` - ExtResource jsonutils.JSONObject `json:"ext_resource"` - ExtResourcesLastUpdate time.Time `json:"ext_resources_last_update"` - ExtResourcesNextUpdate time.Time `json:"ext_resources_next_update"` + GroupCount int `json:"group_count"` + UserCount int `json:"user_count"` + + ExternalResourceInfo } diff --git a/pkg/apis/input.go b/pkg/apis/input.go index 83700a76ba..5b6d850fd2 100644 --- a/pkg/apis/input.go +++ b/pkg/apis/input.go @@ -127,7 +127,7 @@ type StandaloneResourceCreateInput struct { // example: test-network Name string `json:"name"` - // 生成资源名称的规则,如果name为空,则为必填项 + // 生成资源名称的模板,如果name为空,则为必填项 // description: generated resource name, given a pattern to generate name, required if name is not given // unique: false // required: false diff --git a/pkg/apis/share.go b/pkg/apis/share.go new file mode 100644 index 0000000000..90a3e028a0 --- /dev/null +++ b/pkg/apis/share.go @@ -0,0 +1,24 @@ +// 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 + +import "yunion.io/x/onecloud/pkg/util/rbacutils" + +type SAccountShareInfo struct { + IsPublic bool + PublicScope rbacutils.TRbacScope + ShareMode string + SharedDomains []string +} diff --git a/pkg/cloudcommon/db/infraresource.go b/pkg/cloudcommon/db/infraresource.go index 562509c972..6c6a086195 100644 --- a/pkg/cloudcommon/db/infraresource.go +++ b/pkg/cloudcommon/db/infraresource.go @@ -22,6 +22,7 @@ import ( "yunion.io/x/sqlchemy" "yunion.io/x/onecloud/pkg/apis" + "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/rbacutils" @@ -201,3 +202,47 @@ func (model *SInfrasResourceBase) PerformChangeOwner( } return model.SDomainLevelResourceBase.PerformChangeOwner(ctx, userCred, query, input) } + +func (model *SInfrasResourceBase) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + model.SSharableBaseResource.CustomizeCreate(ctx, userCred, ownerId, query, data) + return model.SDomainLevelResourceBase.CustomizeCreate(ctx, userCred, ownerId, query, data) +} + +func (model *SInfrasResourceBase) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { + SharedResourceManager.CleanModelShares(ctx, userCred, model.GetIInfrasModel()) + return model.SDomainLevelResourceBase.Delete(ctx, userCred) +} + +func (model *SInfrasResourceBase) SyncShareState(ctx context.Context, userCred mcclient.TokenCredential, shareInfo apis.SAccountShareInfo) { + if model.PublicScope != string(apis.OWNER_SOURCE_LOCAL) { + diff, _ := Update(model, func() error { + switch shareInfo.ShareMode { + case compute.CLOUD_ACCOUNT_SHARE_MODE_ACCOUNT_DOMAIN: + model.IsPublic = false + model.PublicScope = string(rbacutils.ScopeNone) + case compute.CLOUD_ACCOUNT_SHARE_MODE_PROVIDER_DOMAIN: + model.IsPublic = false + model.PublicScope = string(rbacutils.ScopeNone) + case compute.CLOUD_ACCOUNT_SHARE_MODE_SYSTEM: + if shareInfo.IsPublic && shareInfo.PublicScope == rbacutils.ScopeSystem { + model.IsPublic = true + model.PublicScope = string(rbacutils.ScopeSystem) + } else if len(shareInfo.SharedDomains) > 0 { + model.IsPublic = true + model.PublicScope = string(rbacutils.ScopeDomain) + SharedResourceManager.shareToTarget(ctx, userCred, model.GetIInfrasModel(), SharedTargetProject, nil) + SharedResourceManager.shareToTarget(ctx, userCred, model.GetIInfrasModel(), SharedTargetDomain, shareInfo.SharedDomains) + } else { + model.IsPublic = false + model.PublicScope = string(rbacutils.ScopeNone) + SharedResourceManager.shareToTarget(ctx, userCred, model.GetIInfrasModel(), SharedTargetProject, nil) + SharedResourceManager.shareToTarget(ctx, userCred, model.GetIInfrasModel(), SharedTargetDomain, nil) + } + } + return nil + }) + if len(diff) > 0 { + OpsLog.LogEvent(model, ACT_SYNC_SHARE, diff, userCred) + } + } +} diff --git a/pkg/cloudcommon/db/interface.go b/pkg/cloudcommon/db/interface.go index 983d6017b3..731f77e188 100644 --- a/pkg/cloudcommon/db/interface.go +++ b/pkg/cloudcommon/db/interface.go @@ -284,7 +284,7 @@ type IDomainLevelModelManager interface { IStandaloneModelManager GetIDomainLevelModelManager() IDomainLevelModelManager - GetResourceCount() ([]SDomainResourceCount, error) + GetResourceCount() ([]SScopeResourceCount, error) } type IDomainLevelModel interface { @@ -315,7 +315,7 @@ type IVirtualModelManager interface { IStandaloneModelManager GetIVirtualModelManager() IVirtualModelManager - GetResourceCount() ([]SProjectResourceCount, error) + GetResourceCount() ([]SScopeResourceCount, error) } type IVirtualModel interface { diff --git a/pkg/cloudcommon/db/opslog.go b/pkg/cloudcommon/db/opslog.go index 648102c2d1..1145c2a7e5 100644 --- a/pkg/cloudcommon/db/opslog.go +++ b/pkg/cloudcommon/db/opslog.go @@ -178,6 +178,7 @@ const ( ACT_CHANGE_OWNER = "change_owner" ACT_SYNC_OWNER = "sync_owner" + ACT_SYNC_SHARE = "sync_share" ACT_RESERVE_IP = "reserve_ip" ACT_RELEASE_IP = "release_ip" diff --git a/pkg/cloudcommon/db/project_resources.go b/pkg/cloudcommon/db/project_resources.go index 7e73e74221..4245f08971 100644 --- a/pkg/cloudcommon/db/project_resources.go +++ b/pkg/cloudcommon/db/project_resources.go @@ -43,38 +43,44 @@ func getAllProjectResourceCountsHandler(ctx context.Context, w http.ResponseWrit appsrv.SendJSON(w, jsonutils.Marshal(cnt)) } -func getAllProjectResourceCounts() (map[string][]SProjectResourceCount, error) { - ret := make(map[string][]SProjectResourceCount) +func getAllProjectResourceCounts() (map[string][]SScopeResourceCount, error) { + ret := make(map[string][]SScopeResourceCount) for _, manager := range globalTables { - virtman, ok := manager.(IVirtualModelManager) - if ok { + if virtman, ok := manager.(IVirtualModelManager); ok { resCnt, err := virtman.GetResourceCount() if err != nil { return nil, errors.Wrap(err, "getProjectResourceCount") } ret[virtman.KeywordPlural()] = resCnt + } else if domainMan, ok := manager.(IDomainLevelModelManager); ok { + resCnt, err := domainMan.GetResourceCount() + if err != nil { + return nil, errors.Wrap(err, "getDomainResourceCount") + } + ret[domainMan.KeywordPlural()] = resCnt } } return ret, nil } -type SProjectResourceCount struct { +type SScopeResourceCount struct { TenantId string `json:"tenant_id"` + DomainId string `json:"domain_id"` ResCount int `json:"res_count"` } -func (virtman *SVirtualResourceBaseManager) GetResourceCount() ([]SProjectResourceCount, error) { +func (virtman *SVirtualResourceBaseManager) GetResourceCount() ([]SScopeResourceCount, error) { virts := virtman.GetIVirtualModelManager().Query() // log.Debugf("GetResourceCount: %s", virtman.keywordPlural) return CalculateProjectResourceCount(virts) } -func CalculateProjectResourceCount(query *sqlchemy.SQuery) ([]SProjectResourceCount, error) { +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([]SProjectResourceCount, 0) + cnts := make([]SScopeResourceCount, 0) err := q.All(&cnts) if err != nil && err != sql.ErrNoRows { return nil, errors.Wrap(err, "q.All") @@ -82,23 +88,18 @@ func CalculateProjectResourceCount(query *sqlchemy.SQuery) ([]SProjectResourceCo return cnts, nil } -type SDomainResourceCount struct { - DomainId string `json:"domain_id"` - ResCount int `json:"res_count"` -} - -func (domainman *SDomainLevelResourceBaseManager) GetResourceCount() ([]SDomainResourceCount, error) { +func (domainman *SDomainLevelResourceBaseManager) GetResourceCount() ([]SScopeResourceCount, error) { virts := domainman.GetIDomainLevelModelManager().Query() // log.Debugf("GetResourceCount: %s", virtman.keywordPlural) return CalculateDomainResourceCount(virts) } -func CalculateDomainResourceCount(query *sqlchemy.SQuery) ([]SDomainResourceCount, error) { +func CalculateDomainResourceCount(query *sqlchemy.SQuery) ([]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")) - cnts := make([]SDomainResourceCount, 0) + cnts := make([]SScopeResourceCount, 0) err := q.All(&cnts) if err != nil && err != sql.ErrNoRows { return nil, errors.Wrap(err, "q.All") diff --git a/pkg/cloudcommon/db/sharablebase.go b/pkg/cloudcommon/db/sharablebase.go index b1efde77a6..6b52042f20 100644 --- a/pkg/cloudcommon/db/sharablebase.go +++ b/pkg/cloudcommon/db/sharablebase.go @@ -65,18 +65,30 @@ func (manager *SSharableBaseResourceManager) FetchCustomizeColumns( var resType string resIds := make([]string, len(rows)) var sharedTarget string + var resScope rbacutils.TRbacScope for i := range rows { if model, ok := objs[i].(ISharableBaseModel); ok { if len(resType) == 0 { resType = model.Keyword() } if len(sharedTarget) == 0 { - sharedTarget = string(model.GetModelManager().ResourceScope()) + sharedTarget = string(model.GetPublicScope()) + } + if len(resScope) == 0 { + resScope = model.GetModelManager().ResourceScope() } resIds[i] = model.GetId() } } + if sharedTarget != SharedTargetProject && sharedTarget != SharedTargetDomain { + if resScope == rbacutils.ScopeProject && sharedTarget == string(rbacutils.ScopeNone) { + sharedTarget = SharedTargetProject + } else { + return rows + } + } + q := SharedResourceManager.Query() q = q.Equals("resource_type", resType) q = q.Equals("target_type", sharedTarget) @@ -199,6 +211,9 @@ type SSharableBaseResource struct { IsPublic bool `default:"false" nullable:"false" list:"user"` // 默认共享范围 PublicScope string `width:"16" charset:"ascii" nullable:"false" default:"system" list:"user"` + // 共享设置的来源, local: 本地设置, cloud: 从云上同步过来 + // example: local + PublicSrc string `width:"10" charset:"ascii" nullable:"true" list:"user" json:"public_src"` } type ISharableBaseModel interface { @@ -260,6 +275,7 @@ func (m SSharableBaseResource) GetPublicScope() rbacutils.TRbacScope { } func SharablePerformPublic(model ISharableBaseModel, ctx context.Context, userCred mcclient.TokenCredential, input apis.PerformPublicInput) error { + log.Debugf("%s", jsonutils.Marshal(input)) var err error resourceScope := model.GetModelManager().ResourceScope() @@ -268,6 +284,16 @@ func SharablePerformPublic(model ISharableBaseModel, ctx context.Context, userCr return errors.Wrapf(httperrors.ErrNotSupported, "cannot share %s resource to %s", resourceScope, targetScope) } + if len(input.SharedProjects) > 0 && len(input.SharedDomains) > 0 { + return errors.Wrap(httperrors.ErrInputParameter, "cannot set shared_projects and shared_domains at the same time") + } else if len(input.SharedProjects) > 0 && targetScope != rbacutils.ScopeProject { + targetScope = rbacutils.ScopeProject + // return errors.Wrapf(httperrors.ErrInputParameter, "scope %s != project when shared_projects specified", targetScope) + } else if len(input.SharedDomains) > 0 && targetScope != rbacutils.ScopeDomain { + targetScope = rbacutils.ScopeDomain + // return errors.Wrapf(httperrors.ErrInputParameter, "scope %s != domain when shared_domains specified", targetScope) + } + shareResult := apis.PerformPublicInput{ Scope: string(targetScope), } @@ -380,3 +406,10 @@ func SharableModelIsShared(model ISharableBaseModel) bool { } return false } + +func (base *SSharableBaseResource) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + base.IsPublic = false + base.PublicScope = string(rbacutils.ScopeNone) + base.PublicSrc = string(apis.OWNER_SOURCE_LOCAL) + return nil +} diff --git a/pkg/cloudcommon/db/sharablevirtual.go b/pkg/cloudcommon/db/sharablevirtual.go index bbef69ea2c..98a285055d 100644 --- a/pkg/cloudcommon/db/sharablevirtual.go +++ b/pkg/cloudcommon/db/sharablevirtual.go @@ -22,6 +22,7 @@ import ( "yunion.io/x/sqlchemy" "yunion.io/x/onecloud/pkg/apis" + "yunion.io/x/onecloud/pkg/apis/compute" "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/rbacutils" @@ -194,3 +195,41 @@ func (model *SSharableVirtualResourceBase) PerformChangeOwner( } return model.SVirtualResourceBase.PerformChangeOwner(ctx, userCred, query, input) } + +func (model *SSharableVirtualResourceBase) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + model.SSharableBaseResource.CustomizeCreate(ctx, userCred, ownerId, query, data) + return model.SVirtualResourceBase.CustomizeCreate(ctx, userCred, ownerId, query, data) +} + +func (model *SSharableVirtualResourceBase) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { + SharedResourceManager.CleanModelShares(ctx, userCred, model.GetISharableVirtualModel()) + return model.SVirtualResourceBase.Delete(ctx, userCred) +} + +func (model *SSharableVirtualResourceBase) SyncShareState(ctx context.Context, userCred mcclient.TokenCredential, shareInfo apis.SAccountShareInfo) { + if model.PublicScope != string(apis.OWNER_SOURCE_LOCAL) { + diff, _ := Update(model, func() error { + switch shareInfo.ShareMode { + case compute.CLOUD_ACCOUNT_SHARE_MODE_ACCOUNT_DOMAIN: + model.IsPublic = true + model.PublicScope = string(rbacutils.ScopeDomain) + case compute.CLOUD_ACCOUNT_SHARE_MODE_PROVIDER_DOMAIN: + model.IsPublic = true + model.PublicScope = string(rbacutils.ScopeDomain) + case compute.CLOUD_ACCOUNT_SHARE_MODE_SYSTEM: + model.IsPublic = true + if shareInfo.IsPublic && shareInfo.PublicScope == rbacutils.ScopeSystem { + model.PublicScope = string(rbacutils.ScopeSystem) + } else { + model.PublicScope = string(rbacutils.ScopeDomain) + SharedResourceManager.shareToTarget(ctx, userCred, model.GetISharableVirtualModel(), SharedTargetProject, nil) + SharedResourceManager.shareToTarget(ctx, userCred, model.GetISharableVirtualModel(), SharedTargetDomain, shareInfo.SharedDomains) + } + } + return nil + }) + if len(diff) > 0 { + OpsLog.LogEvent(model, ACT_SYNC_SHARE, diff, userCred) + } + } +} diff --git a/pkg/cloudcommon/db/sharedresource.go b/pkg/cloudcommon/db/sharedresource.go index 29d6d24b1a..7199ee4217 100644 --- a/pkg/cloudcommon/db/sharedresource.go +++ b/pkg/cloudcommon/db/sharedresource.go @@ -37,14 +37,14 @@ const ( type SSharedResource struct { SResourceBase - Id int64 `primary:"true" auto_increment:"true" list:"user"` + Id int64 `primary:"true" auto_increment:"true"` - ResourceType string `width:"32" charset:"ascii" nullable:"false" list:"user" json:"resource_type"` - ResourceId string `width:"128" charset:"ascii" nullable:"false" index:"true" list:"user" json:"resource_id"` - OwnerProjectId string `width:"128" charset:"ascii" nullable:"false" index:"true" list:"user" json:"owner_project_id"` - TargetProjectId string `width:"128" charset:"ascii" nullable:"false" index:"true" list:"user" json:"target_project_id"` + ResourceType string `width:"32" charset:"ascii" nullable:"false" json:"resource_type"` + ResourceId string `width:"128" charset:"ascii" nullable:"false" index:"true" json:"resource_id"` + // OwnerProjectId string `width:"128" charset:"ascii" nullable:"false" index:"true" json:"owner_project_id"` + TargetProjectId string `width:"128" charset:"ascii" nullable:"false" index:"true" json:"target_project_id"` - TargetType string `width:"8" charset:"ascii" default:"project" nullable:"false" list:"user" json:"target_type"` + TargetType string `width:"8" charset:"ascii" default:"project" nullable:"false" json:"target_type"` } type SSharedResourceManager struct { diff --git a/pkg/cloudcommon/db/tenantcache.go b/pkg/cloudcommon/db/tenantcache.go index d93d5fc637..e7cbb2490a 100644 --- a/pkg/cloudcommon/db/tenantcache.go +++ b/pkg/cloudcommon/db/tenantcache.go @@ -21,8 +21,6 @@ import ( "runtime/debug" "time" - "yunion.io/x/onecloud/pkg/httperrors" - "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/errors" @@ -31,6 +29,7 @@ import ( identityapi "yunion.io/x/onecloud/pkg/apis/identity" "yunion.io/x/onecloud/pkg/cloudcommon/consts" "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman" + "yunion.io/x/onecloud/pkg/httperrors" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/mcclient/auth" "yunion.io/x/onecloud/pkg/mcclient/modules" @@ -122,7 +121,7 @@ func (manager *STenantCacheManager) fetchTenant(ctx context.Context, idStr strin return nil, errors.Wrap(err, "CountWithError") } if tcnt > 1 { - return nil, httperrors.ErrDuplicateName + return nil, errors.Wrapf(httperrors.ErrDuplicateName, "duplicate tenant/domain name (%d)", tcnt) } tobj, err := NewModelObject(manager) if err != nil { diff --git a/pkg/cloudcommon/options/manager.go b/pkg/cloudcommon/options/manager.go index bcf1979afc..3df3353da7 100644 --- a/pkg/cloudcommon/options/manager.go +++ b/pkg/cloudcommon/options/manager.go @@ -18,6 +18,7 @@ import ( "reflect" "time" + "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/onecloud/pkg/appsrv" @@ -84,7 +85,7 @@ func (manager *SOptionManager) doSync(first bool) { merged := manager.session.Merge(newOpts, manager.serviceType, manager.serviceVersion) if merged && !reflect.DeepEqual(newOpts, manager.options) { - log.Infof("Service config changed ...") + log.Infof("Service config changed ... %s %s", jsonutils.Marshal(newOpts), jsonutils.Marshal(manager.options)) if manager.onOptionsChange != nil && manager.onOptionsChange(manager.options, newOpts) && !first { log.Infof("Option changes detected and going to restart the program...") appsrv.SetExitFlag() diff --git a/pkg/cloudprovider/resources.go b/pkg/cloudprovider/resources.go index bd2054a8fe..33f92b2274 100644 --- a/pkg/cloudprovider/resources.go +++ b/pkg/cloudprovider/resources.go @@ -24,7 +24,6 @@ import ( "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/billing" - "yunion.io/x/onecloud/pkg/util/rbacutils" ) type ICloudResource interface { @@ -458,8 +457,8 @@ type ICloudNetwork interface { GetIpMask() int8 GetGateway() string GetServerType() string - GetIsPublic() bool - GetPublicScope() rbacutils.TRbacScope + // GetIsPublic() bool + // GetPublicScope() rbacutils.TRbacScope Delete() error diff --git a/pkg/compute/models/baremetalagents.go b/pkg/compute/models/baremetalagents.go index c5737f4760..79c80400a3 100644 --- a/pkg/compute/models/baremetalagents.go +++ b/pkg/compute/models/baremetalagents.go @@ -93,11 +93,10 @@ func (self *SBaremetalagent) ValidateUpdateData(ctx context.Context, userCred mc } } if len(input.Zone) > 0 { - zoneObj, err := ValidateZoneResourceInput(userCred, input.ZoneResourceInput) + _, input.ZoneResourceInput, err = ValidateZoneResourceInput(userCred, input.ZoneResourceInput) if err != nil { return input, errors.Wrap(err, "ValidateZoneResourceInput") } - input.Zone = zoneObj.GetId() } input.StandaloneResourceBaseUpdateInput, err = self.SStandaloneResourceBase.ValidateUpdateData(ctx, userCred, query, input.StandaloneResourceBaseUpdateInput) if err != nil { @@ -122,11 +121,10 @@ func (manager *SBaremetalagentManager) ValidateCreateData(ctx context.Context, u if len(input.Zone) == 0 { return input, errors.Wrap(httperrors.ErrMissingParameter, "zone/zone_id") } - zoneObj, err := ValidateZoneResourceInput(userCred, input.ZoneResourceInput) + _, input.ZoneResourceInput, err = ValidateZoneResourceInput(userCred, input.ZoneResourceInput) if err != nil { return input, errors.Wrap(err, "ValidateZoneResourceInput") } - input.Zone = zoneObj.GetId() input.StandaloneResourceCreateInput, err = manager.SStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.StandaloneResourceCreateInput) if err != nil { return input, errors.Wrap(err, "SStandaloneResourceBaseManager.ValidateCreateData") diff --git a/pkg/compute/models/cloudaccounts.go b/pkg/compute/models/cloudaccounts.go index 18d5c833df..f43fd2998f 100644 --- a/pkg/compute/models/cloudaccounts.go +++ b/pkg/compute/models/cloudaccounts.go @@ -2208,3 +2208,12 @@ func (manager *SCloudaccountManager) getBrandsOfCapability(region *SCloudregion, } return ret, nil } + +func (account *SCloudaccount) getAccountShareInfo() apis.SAccountShareInfo { + return apis.SAccountShareInfo{ + ShareMode: account.ShareMode, + IsPublic: account.IsPublic, + PublicScope: rbacutils.String2Scope(account.PublicScope), + SharedDomains: account.GetSharedDomains(), + } +} diff --git a/pkg/compute/models/cloudproviders.go b/pkg/compute/models/cloudproviders.go index a8a16f8982..1b16a6bb49 100644 --- a/pkg/compute/models/cloudproviders.go +++ b/pkg/compute/models/cloudproviders.go @@ -1495,3 +1495,8 @@ func (provider *SCloudprovider) GetDetailsStorageClasses( ret.Add(jsonutils.NewStringArray(sc), "storage_classes") return ret, nil } + +func (provider *SCloudprovider) getAccountShareInfo() apis.SAccountShareInfo { + account := provider.GetCloudaccount() + return account.getAccountShareInfo() +} diff --git a/pkg/compute/models/cloudregionresource.go b/pkg/compute/models/cloudregionresource.go index 242cfe5c46..bd3484beb0 100644 --- a/pkg/compute/models/cloudregionresource.go +++ b/pkg/compute/models/cloudregionresource.go @@ -16,9 +16,11 @@ 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" @@ -36,6 +38,19 @@ type SCloudregionResourceBase struct { type SCloudregionResourceBaseManager struct{} +func ValidateCloudregionResourceInput(userCred mcclient.TokenCredential, input api.CloudregionResourceInput) (*SCloudregion, api.CloudregionResourceInput, error) { + regionObj, err := CloudregionManager.FetchByIdOrName(userCred, input.Cloudregion) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", CloudregionManager.Keyword(), input.Cloudregion) + } else { + return nil, input, errors.Wrap(err, "CloudregionManager.FetchByIdOrName") + } + } + input.Cloudregion = regionObj.GetId() + return regionObj.(*SCloudregion), input, nil +} + func (self *SCloudregionResourceBase) GetRegion() *SCloudregion { region, err := CloudregionManager.FetchById(self.CloudregionId) if err != nil { diff --git a/pkg/compute/models/cloudsync.go b/pkg/compute/models/cloudsync.go index 414a1fe543..f6f3d39c74 100644 --- a/pkg/compute/models/cloudsync.go +++ b/pkg/compute/models/cloudsync.go @@ -408,7 +408,7 @@ func syncWireNetworks(ctx context.Context, userCred mcclient.TokenCredential, sy log.Errorf(msg) return } - _, _, result := NetworkManager.SyncNetworks(ctx, userCred, localWire, nets, provider.GetOwnerId()) + _, _, result := NetworkManager.SyncNetworks(ctx, userCred, localWire, nets, provider) if syncResults != nil { syncResults.Add(NetworkManager, result) diff --git a/pkg/compute/models/dbinstanceresource.go b/pkg/compute/models/dbinstanceresource.go index cbfd060299..13d842ac97 100644 --- a/pkg/compute/models/dbinstanceresource.go +++ b/pkg/compute/models/dbinstanceresource.go @@ -39,6 +39,19 @@ type SDBInstanceResourceBaseManager struct { SVpcResourceBaseManager } +func ValidateDBInstanceResourceInput(userCred mcclient.TokenCredential, input api.DBInstanceResourceInput) (*SDBInstance, api.DBInstanceResourceInput, error) { + rdsObj, err := DBInstanceManager.FetchByIdOrName(userCred, input.DBInstance) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", DBInstanceManager.Keyword(), input.DBInstance) + } else { + return nil, input, errors.Wrap(err, "DBInstanceManager.FetchByIdOrName") + } + } + input.DBInstance = rdsObj.GetId() + return rdsObj.(*SDBInstance), input, nil +} + func (self *SDBInstanceResourceBase) GetDBInstance() (*SDBInstance, error) { instance, err := DBInstanceManager.FetchById(self.DBInstanceId) if err != nil { @@ -119,21 +132,19 @@ func (manager *SDBInstanceResourceBaseManager) ListItemFilter( userCred mcclient.TokenCredential, query api.DBInstanceFilterListInput, ) (*sqlchemy.SQuery, error) { + var err error if len(query.DBInstance) > 0 { - dbObj, err := DBInstanceManager.FetchByIdOrName(userCred, query.DBInstance) + var dbObj *SDBInstance + dbObj, _, err = ValidateDBInstanceResourceInput(userCred, query.DBInstanceResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(DBInstanceManager.Keyword(), query.DBInstance) - } else { - return nil, errors.Wrap(err, "DBInstanceManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "DBInstanceManager.FetchByIdOrName") } q = q.Equals("dbinstance_id", dbObj.GetId()) } subq := DBInstanceManager.Query("id").Snapshot() - subq, err := manager.SVpcResourceBaseManager.ListItemFilter(ctx, subq, userCred, query.VpcFilterListInput) + subq, err = manager.SVpcResourceBaseManager.ListItemFilter(ctx, subq, userCred, query.VpcFilterListInput) if err != nil { return nil, errors.Wrap(err, "SVpcResourceBaseManager.ListItemFilter") } diff --git a/pkg/compute/models/diskresource.go b/pkg/compute/models/diskresource.go index 1cc1aa39e6..5a0c4e8e56 100644 --- a/pkg/compute/models/diskresource.go +++ b/pkg/compute/models/diskresource.go @@ -39,6 +39,19 @@ type SDiskResourceBaseManager struct { SStorageResourceBaseManager } +func ValidateDiskResourceInput(userCred mcclient.TokenCredential, input api.DiskResourceInput) (*SDisk, api.DiskResourceInput, error) { + diskObj, err := DiskManager.FetchByIdOrName(userCred, input.Disk) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", DiskManager.Keyword(), input.Disk) + } else { + return nil, input, errors.Wrap(err, "DiskManager.FetchByIdOrName") + } + } + input.Disk = diskObj.GetId() + return diskObj.(*SDisk), input, nil +} + func (self *SDiskResourceBase) GetDisk() *SDisk { obj, _ := DiskManager.FetchById(self.DiskId) if obj != nil { @@ -127,13 +140,9 @@ func (manager *SDiskResourceBaseManager) ListItemFilter( ) (*sqlchemy.SQuery, error) { var err error if len(query.Disk) > 0 { - diskObj, err := DiskManager.FetchByIdOrName(userCred, query.Disk) + diskObj, _, err := ValidateDiskResourceInput(userCred, query.DiskResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(DiskManager.Keyword(), query.Disk) - } else { - return nil, errors.Wrap(err, "DiskManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateDiskResourceInput") } q = q.Equals("disk_id", diskObj.GetId()) } diff --git a/pkg/compute/models/elasticcacheresource.go b/pkg/compute/models/elasticcacheresource.go index b623f285e8..1cb0bca7a2 100644 --- a/pkg/compute/models/elasticcacheresource.go +++ b/pkg/compute/models/elasticcacheresource.go @@ -42,6 +42,19 @@ type SElasticcacheResourceBaseManager struct { SZoneResourceBaseManager } +func ValidateElasticcacheResourceInput(userCred mcclient.TokenCredential, input api.ELasticcacheResourceInput) (*SElasticcache, api.ELasticcacheResourceInput, error) { + cacheObj, err := ElasticcacheManager.FetchByIdOrName(userCred, input.Elasticcache) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", ElasticcacheManager.Keyword(), input.Elasticcache) + } else { + return nil, input, errors.Wrap(err, "ElasticcacheManager.FetchByIdOrName") + } + } + input.Elasticcache = cacheObj.GetId() + return cacheObj.(*SElasticcache), input, nil +} + func (self *SElasticcacheResourceBase) GetElasticcache() (*SElasticcache, error) { instance, err := ElasticcacheManager.FetchById(self.ElasticcacheId) if err != nil { @@ -131,13 +144,9 @@ func (manager *SElasticcacheResourceBaseManager) ListItemFilter( query api.ElasticcacheFilterListInput, ) (*sqlchemy.SQuery, error) { if len(query.Elasticcache) > 0 { - dbObj, err := ElasticcacheManager.FetchByIdOrName(userCred, query.Elasticcache) + dbObj, _, err := ValidateElasticcacheResourceInput(userCred, query.ELasticcacheResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(ElasticcacheManager.Keyword(), query.Elasticcache) - } else { - return nil, errors.Wrap(err, "ElasticcacheManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateElasticcacheResourceInput") } q = q.Equals("elasticcache_id", dbObj.GetId()) } diff --git a/pkg/compute/models/globalvpcresource.go b/pkg/compute/models/globalvpcresource.go index 6bf5ddd612..b12694e5cc 100644 --- a/pkg/compute/models/globalvpcresource.go +++ b/pkg/compute/models/globalvpcresource.go @@ -37,6 +37,19 @@ type SGlobalVpcResourceBase struct { type SGlobalVpcResourceBaseManager struct{} +func ValidateGlobalvpcResourceInput(userCred mcclient.TokenCredential, input api.GlobalVpcResourceInput) (*SGlobalVpc, api.GlobalVpcResourceInput, error) { + gvpcObj, err := GlobalVpcManager.FetchByIdOrName(userCred, input.Globalvpc) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", GlobalVpcManager.Keyword(), input.Globalvpc) + } else { + return nil, input, errors.Wrap(err, "GlobalVpcManager.FetchByIdOrName") + } + } + input.Globalvpc = gvpcObj.GetId() + return gvpcObj.(*SGlobalVpc), input, nil +} + func (self *SGlobalVpcResourceBase) GetGlobalVpc() (*SGlobalVpc, error) { if len(self.GlobalvpcId) == 0 { return nil, nil @@ -91,13 +104,9 @@ func (manager *SGlobalVpcResourceBaseManager) ListItemFilter( query api.GlobalVpcResourceListInput, ) (*sqlchemy.SQuery, error) { if len(query.Globalvpc) > 0 { - globalVpcObj, err := GlobalVpcManager.FetchByIdOrName(userCred, query.Globalvpc) + globalVpcObj, _, err := ValidateGlobalvpcResourceInput(userCred, query.GlobalVpcResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(GlobalVpcManager.Keyword(), query.Globalvpc) - } else { - return nil, errors.Wrap(err, "GlobalVpcManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateGlobalvpcResourceInput") } q = q.Equals("globalvpc_id", globalVpcObj.GetId()) } diff --git a/pkg/compute/models/groupguests.go b/pkg/compute/models/groupguests.go index e109ab75b9..c147e83cb8 100644 --- a/pkg/compute/models/groupguests.go +++ b/pkg/compute/models/groupguests.go @@ -167,7 +167,7 @@ func (manager *SGroupguestManager) ListItemFilter( if err != nil { return nil, errors.Wrap(err, "SGroupJointsManager.ListItemFilter") } - q, err = manager.SGuestResourceBaseManager.ListItemFilter(ctx, q, userCred, query.GuestFilterListInput) + q, err = manager.SGuestResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ServerFilterListInput) if err != nil { return nil, errors.Wrap(err, "SGuestResourceBaseManager.ListItemFilter") } @@ -191,7 +191,7 @@ func (manager *SGroupguestManager) OrderByExtraFields( if err != nil { return nil, errors.Wrap(err, "SGroupJointsManager.OrderByExtraFields") } - q, err = manager.SGuestResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.GuestFilterListInput) + q, err = manager.SGuestResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ServerFilterListInput) if err != nil { return nil, errors.Wrap(err, "SGuestResourceBaseManager.OrderByExtraFields") } diff --git a/pkg/compute/models/groupresource.go b/pkg/compute/models/groupresource.go index bfeed8f9e5..60b6f328e9 100644 --- a/pkg/compute/models/groupresource.go +++ b/pkg/compute/models/groupresource.go @@ -39,6 +39,19 @@ type SGroupResourceBase struct { type SGroupResourceBaseManager struct { } +func ValidateGroupResourceInput(userCred mcclient.TokenCredential, input api.GroupResourceInput) (*SGroup, api.GroupResourceInput, error) { + groupObj, err := GroupManager.FetchByIdOrName(userCred, input.Group) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", GroupManager.Keyword(), input.Group) + } else { + return nil, input, errors.Wrap(err, "GroupManager.FetchByIdOrName") + } + } + input.Group = groupObj.GetId() + return groupObj.(*SGroup), input, nil +} + func (self *SGroupResourceBase) GetGroup() *SGroup { obj, _ := GroupManager.FetchById(self.GroupId) if obj != nil { @@ -91,13 +104,9 @@ func (manager *SGroupResourceBaseManager) ListItemFilter( query api.GroupFilterListInput, ) (*sqlchemy.SQuery, error) { if len(query.Group) > 0 { - groupObj, err := GroupManager.FetchByIdOrName(userCred, query.Group) + groupObj, _, err := ValidateGroupResourceInput(userCred, query.GroupResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(GroupManager.Keyword(), query.Group) - } else { - return nil, errors.Wrap(err, "GroupManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateGroupResourceInput") } q = q.Equals("group_id", groupObj.GetId()) } diff --git a/pkg/compute/models/guestjoints.go b/pkg/compute/models/guestjoints.go index 92042f014f..a776695b63 100644 --- a/pkg/compute/models/guestjoints.go +++ b/pkg/compute/models/guestjoints.go @@ -123,7 +123,7 @@ func (manager *SGuestJointsManager) ListItemFilter( if err != nil { return nil, errors.Wrap(err, "SVirtualJointResourceBaseManager.ListItemFilter") } - q, err = manager.SGuestResourceBaseManager.ListItemFilter(ctx, q, userCred, query.GuestFilterListInput) + q, err = manager.SGuestResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ServerFilterListInput) if err != nil { return nil, errors.Wrap(err, "SGuestResourceBaseManager.ListItemFilter") } @@ -143,7 +143,7 @@ func (manager *SGuestJointsManager) OrderByExtraFields( if err != nil { return nil, errors.Wrap(err, "SVirtualJointResourceBaseManager.OrderByExtraFields") } - q, err = manager.SGuestResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.GuestFilterListInput) + q, err = manager.SGuestResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ServerFilterListInput) if err != nil { return nil, errors.Wrap(err, "SGuestResourceBaseManager.OrderByExtraFields") } diff --git a/pkg/compute/models/guestresource.go b/pkg/compute/models/guestresource.go index 0367ca430c..087dbbe725 100644 --- a/pkg/compute/models/guestresource.go +++ b/pkg/compute/models/guestresource.go @@ -39,6 +39,19 @@ type SGuestResourceBaseManager struct { SHostResourceBaseManager } +func ValidateGuestResourceInput(userCred mcclient.TokenCredential, input api.ServerResourceInput) (*SGuest, api.ServerResourceInput, error) { + srvObj, err := GuestManager.FetchByIdOrName(userCred, input.Server) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", GuestManager.Keyword(), input.Server) + } else { + return nil, input, errors.Wrap(err, "GuestManager.FetchByIdOrName") + } + } + input.Server = srvObj.GetId() + return srvObj.(*SGuest), input, nil +} + func (self *SGuestResourceBase) GetGuest() *SGuest { obj, _ := GuestManager.FetchById(self.GuestId) if obj != nil { @@ -122,17 +135,13 @@ func (manager *SGuestResourceBaseManager) ListItemFilter( ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, - query api.GuestFilterListInput, + query api.ServerFilterListInput, ) (*sqlchemy.SQuery, error) { var err error if len(query.Server) > 0 { - guestObj, err := GuestManager.FetchByIdOrName(userCred, query.Server) + guestObj, _, err := ValidateGuestResourceInput(userCred, query.ServerResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(GuestManager.Keyword(), query.Server) - } else { - return nil, errors.Wrap(err, "GuestManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateGuestResourceInput") } q = q.Equals("guest_id", guestObj.GetId()) } @@ -169,7 +178,7 @@ func (manager *SGuestResourceBaseManager) OrderByExtraFields( ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, - query api.GuestFilterListInput, + query api.ServerFilterListInput, ) (*sqlchemy.SQuery, error) { q, orders, fields := manager.GetOrderBySubQuery(q, userCred, query) if len(orders) > 0 { @@ -181,7 +190,7 @@ func (manager *SGuestResourceBaseManager) OrderByExtraFields( func (manager *SGuestResourceBaseManager) GetOrderBySubQuery( q *sqlchemy.SQuery, userCred mcclient.TokenCredential, - query api.GuestFilterListInput, + query api.ServerFilterListInput, ) (*sqlchemy.SQuery, []string, []sqlchemy.IQueryField) { guestQ := GuestManager.Query("id", "name") var orders []string @@ -207,7 +216,7 @@ func (manager *SGuestResourceBaseManager) GetOrderBySubQuery( return q, orders, fields } -func (manager *SGuestResourceBaseManager) GetOrderByFields(query api.GuestFilterListInput) []string { +func (manager *SGuestResourceBaseManager) GetOrderByFields(query api.ServerFilterListInput) []string { orders := make([]string, 0) hostOrders := manager.SHostResourceBaseManager.GetOrderByFields(query.HostFilterListInput) orders = append(orders, hostOrders...) diff --git a/pkg/compute/models/guests.go b/pkg/compute/models/guests.go index 958f6819de..e5316209ba 100644 --- a/pkg/compute/models/guests.go +++ b/pkg/compute/models/guests.go @@ -23,8 +23,6 @@ import ( "strings" "time" - "yunion.io/x/onecloud/pkg/apis" - "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/errors" @@ -39,6 +37,7 @@ import ( "yunion.io/x/pkg/utils" "yunion.io/x/sqlchemy" + "yunion.io/x/onecloud/pkg/apis" billing_api "yunion.io/x/onecloud/pkg/apis/billing" api "yunion.io/x/onecloud/pkg/apis/compute" imageapi "yunion.io/x/onecloud/pkg/apis/image" diff --git a/pkg/compute/models/hostresource.go b/pkg/compute/models/hostresource.go index 8b4d19ff04..343fbe13c1 100644 --- a/pkg/compute/models/hostresource.go +++ b/pkg/compute/models/hostresource.go @@ -41,6 +41,19 @@ type SHostResourceBaseManager struct { hostIdFieldName string } +func ValidateHostResourceInput(userCred mcclient.TokenCredential, input api.HostResourceInput) (*SHost, api.HostResourceInput, error) { + hostObj, err := HostManager.FetchByIdOrName(userCred, input.Host) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", HostManager.Keyword(), input.Host) + } else { + return nil, input, errors.Wrap(err, "HostManager.FetchByIdOrName") + } + } + input.Host = hostObj.GetId() + return hostObj.(*SHost), input, nil +} + func (manager *SHostResourceBaseManager) getHostIdFieldName() string { if len(manager.hostIdFieldName) > 0 { return manager.hostIdFieldName @@ -113,13 +126,9 @@ func (manager *SHostResourceBaseManager) ListItemFilter( query api.HostFilterListInput, ) (*sqlchemy.SQuery, error) { if len(query.Host) > 0 { - hostObj, err := HostManager.FetchByIdOrName(userCred, query.Host) + hostObj, _, err := ValidateHostResourceInput(userCred, query.HostResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(HostManager.Keyword(), query.Host) - } else { - return nil, errors.Wrap(err, "HostManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateHostResourceInput") } q = q.Equals(manager.getHostIdFieldName(), hostObj.GetId()) } diff --git a/pkg/compute/models/hosts.go b/pkg/compute/models/hosts.go index 2b77a0d318..e88ec13913 100644 --- a/pkg/compute/models/hosts.go +++ b/pkg/compute/models/hosts.go @@ -25,8 +25,6 @@ import ( "strings" "time" - "yunion.io/x/onecloud/pkg/util/rbacutils" - "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/errors" @@ -55,6 +53,7 @@ import ( "yunion.io/x/onecloud/pkg/mcclient/modules" "yunion.io/x/onecloud/pkg/util/httputils" "yunion.io/x/onecloud/pkg/util/logclient" + "yunion.io/x/onecloud/pkg/util/rbacutils" "yunion.io/x/onecloud/pkg/util/redfish/bmconsole" "yunion.io/x/onecloud/pkg/util/stringutils2" ) @@ -2822,11 +2821,10 @@ func (manager *SHostManager) ValidateCreateData( var err error if len(input.Zone) > 0 { - zoneObj, err := ValidateZoneResourceInput(userCred, input.ZoneResourceInput) + _, input.ZoneResourceInput, err = ValidateZoneResourceInput(userCred, input.ZoneResourceInput) if err != nil { return input, errors.Wrap(err, "ValidateZoneResourceInput") } - input.Zone = zoneObj.GetId() } noProbe := false diff --git a/pkg/compute/models/loadbalanceracls.go b/pkg/compute/models/loadbalanceracls.go index e99d6412bc..40103e49d6 100644 --- a/pkg/compute/models/loadbalanceracls.go +++ b/pkg/compute/models/loadbalanceracls.go @@ -422,7 +422,7 @@ func (man *SLoadbalancerAclManager) SyncLoadbalancerAcls(ctx context.Context, us return compare.SyncResult{} } -func (manager *SLoadbalancerAclManager) GetResourceCount() ([]db.SProjectResourceCount, error) { +func (manager *SLoadbalancerAclManager) GetResourceCount() ([]db.SScopeResourceCount, error) { virts := manager.Query().IsFalse("pending_deleted") return db.CalculateProjectResourceCount(virts) } diff --git a/pkg/compute/models/loadbalancerbackendgroupresource.go b/pkg/compute/models/loadbalancerbackendgroupresource.go index f00549520e..3436986af4 100644 --- a/pkg/compute/models/loadbalancerbackendgroupresource.go +++ b/pkg/compute/models/loadbalancerbackendgroupresource.go @@ -40,6 +40,19 @@ type SLoadbalancerBackendgroupResourceBaseManager struct { SLoadbalancerResourceBaseManager } +func ValidateLoadbalancerBackendgroupResourceInput(userCred mcclient.TokenCredential, input api.LoadbalancerBackendGroupResourceInput) (*SLoadbalancerBackendGroup, api.LoadbalancerBackendGroupResourceInput, error) { + lbbgObj, err := LoadbalancerBackendGroupManager.FetchByIdOrName(userCred, input.BackendGroup) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", LoadbalancerBackendGroupManager.Keyword(), input.BackendGroup) + } else { + return nil, input, errors.Wrap(err, "LoadbalancerBackendGroupManager.FetchByIdOrName") + } + } + input.BackendGroup = lbbgObj.GetId() + return lbbgObj.(*SLoadbalancerBackendGroup), input, nil +} + func (self *SLoadbalancerBackendgroupResourceBase) GetLoadbalancerBackendGroup() *SLoadbalancerBackendGroup { w, _ := LoadbalancerBackendGroupManager.FetchById(self.BackendGroupId) if w != nil { @@ -156,13 +169,9 @@ func (manager *SLoadbalancerBackendgroupResourceBaseManager) ListItemFilter( query api.LoadbalancerBackendGroupFilterListInput, ) (*sqlchemy.SQuery, error) { if len(query.BackendGroup) > 0 { - lbbgObj, err := LoadbalancerBackendGroupManager.FetchByIdOrName(userCred, query.BackendGroup) + lbbgObj, _, err := ValidateLoadbalancerBackendgroupResourceInput(userCred, query.LoadbalancerBackendGroupResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(LoadbalancerBackendGroupManager.Keyword(), query.BackendGroup) - } else { - return nil, errors.Wrap(err, "LoadbalancerBackendGroupManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateLoadbalancerBackendgroupResourceInput") } q = q.Equals("backend_group_id", lbbgObj.GetId()) } diff --git a/pkg/compute/models/loadbalancerbackendgroups.go b/pkg/compute/models/loadbalancerbackendgroups.go index 462049d9fb..26d491e45d 100644 --- a/pkg/compute/models/loadbalancerbackendgroups.go +++ b/pkg/compute/models/loadbalancerbackendgroups.go @@ -1041,7 +1041,7 @@ func (manager *SLoadbalancerBackendGroupManager) initBackendGroupRegion() error return nil }*/ -func (manager *SLoadbalancerBackendGroupManager) GetResourceCount() ([]db.SProjectResourceCount, error) { +func (manager *SLoadbalancerBackendGroupManager) GetResourceCount() ([]db.SScopeResourceCount, error) { virts := manager.Query().IsFalse("pending_deleted") return db.CalculateProjectResourceCount(virts) } diff --git a/pkg/compute/models/loadbalancerbackends.go b/pkg/compute/models/loadbalancerbackends.go index cdcb0fab4a..ae809765a2 100644 --- a/pkg/compute/models/loadbalancerbackends.go +++ b/pkg/compute/models/loadbalancerbackends.go @@ -638,7 +638,7 @@ func (manager *SLoadbalancerBackendManager) InitializeData() error { return nil } -func (manager *SLoadbalancerBackendManager) GetResourceCount() ([]db.SProjectResourceCount, error) { +func (manager *SLoadbalancerBackendManager) GetResourceCount() ([]db.SScopeResourceCount, error) { virts := manager.Query().IsFalse("pending_deleted") return db.CalculateProjectResourceCount(virts) } diff --git a/pkg/compute/models/loadbalancercertificateresource.go b/pkg/compute/models/loadbalancercertificateresource.go index 7b22e20a7a..811548dbfb 100644 --- a/pkg/compute/models/loadbalancercertificateresource.go +++ b/pkg/compute/models/loadbalancercertificateresource.go @@ -38,6 +38,19 @@ type SLoadbalancerCertificateResourceBase struct { type SLoadbalancerCertificateResourceBaseManager struct{} +func ValidateLoadbalancerCertificateResourceInput(userCred mcclient.TokenCredential, input api.LoadbalancerCertificateResourceInput) (*SLoadbalancerCertificate, api.LoadbalancerCertificateResourceInput, error) { + lbcertObj, err := LoadbalancerCertificateManager.FetchByIdOrName(userCred, input.Certificate) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", LoadbalancerCertificateManager.Keyword(), input.Certificate) + } else { + return nil, input, errors.Wrap(err, "LoadbalancerCertificateManager.FetchByIdOrName") + } + } + input.Certificate = lbcertObj.GetId() + return lbcertObj.(*SLoadbalancerCertificate), input, nil +} + func (self *SLoadbalancerCertificateResourceBase) GetCertificate() *SLoadbalancerCertificate { cert, err := LoadbalancerCertificateManager.FetchById(self.CertificateId) if err != nil { @@ -97,13 +110,9 @@ func (manager *SLoadbalancerCertificateResourceBaseManager) ListItemFilter( query api.LoadbalancerCertificateFilterListInput, ) (*sqlchemy.SQuery, error) { if len(query.Certificate) > 0 { - certObj, err := LoadbalancerCertificateManager.FetchByIdOrName(userCred, query.Certificate) + certObj, _, err := ValidateLoadbalancerCertificateResourceInput(userCred, query.LoadbalancerCertificateResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(LoadbalancerCertificateManager.Keyword(), query.Certificate) - } else { - return nil, errors.Wrap(err, "LoadbalancerCertificateManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateLoadbalancerCertificateResourceInput") } q = q.Equals("certificate_id", certObj.GetId()) } diff --git a/pkg/compute/models/loadbalancercertificates.go b/pkg/compute/models/loadbalancercertificates.go index 03bb490ac6..764f4dcec5 100644 --- a/pkg/compute/models/loadbalancercertificates.go +++ b/pkg/compute/models/loadbalancercertificates.go @@ -460,7 +460,7 @@ func (man *SLoadbalancerCertificateManager) CreateCertificate(userCred mcclient. return ret, nil } -func (manager *SLoadbalancerCertificateManager) GetResourceCount() ([]db.SProjectResourceCount, error) { +func (manager *SLoadbalancerCertificateManager) GetResourceCount() ([]db.SScopeResourceCount, error) { virts := manager.Query().IsFalse("pending_deleted") return db.CalculateProjectResourceCount(virts) } diff --git a/pkg/compute/models/loadbalancerclusterresource.go b/pkg/compute/models/loadbalancerclusterresource.go index d7f9cd6203..ab4b233501 100644 --- a/pkg/compute/models/loadbalancerclusterresource.go +++ b/pkg/compute/models/loadbalancerclusterresource.go @@ -41,6 +41,19 @@ type SLoadbalancerClusterResourceBaseManager struct { SWireResourceBaseManager } +func ValidateLoadbalancerClusterResourceInput(userCred mcclient.TokenCredential, input api.LoadbalancerClusterResourceInput) (*SLoadbalancerCluster, api.LoadbalancerClusterResourceInput, error) { + clusterObj, err := LoadbalancerClusterManager.FetchByIdOrName(userCred, input.Cluster) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", LoadbalancerClusterManager.Keyword(), input.Cluster) + } else { + return nil, input, errors.Wrap(err, "LoadbalancerClusterManager.FetchByIdOrName") + } + } + input.Cluster = clusterObj.GetId() + return clusterObj.(*SLoadbalancerCluster), input, nil +} + func (self *SLoadbalancerClusterResourceBase) GetLoadbalancerCluster() *SLoadbalancerCluster { cluster, err := LoadbalancerClusterManager.FetchById(self.ClusterId) if err != nil { @@ -118,13 +131,9 @@ func (manager *SLoadbalancerClusterResourceBaseManager) ListItemFilter( query api.LoadbalancerClusterFilterListInput, ) (*sqlchemy.SQuery, error) { if len(query.Cluster) > 0 { - clusterObj, err := LoadbalancerClusterManager.FetchByIdOrName(userCred, query.Cluster) + clusterObj, _, err := ValidateLoadbalancerClusterResourceInput(userCred, query.LoadbalancerClusterResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(LoadbalancerClusterManager.Keyword(), query.Cluster) - } else { - return nil, errors.Wrap(err, "LoadbalancerClusterManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateLoadbalancerClusterResourceInput") } q = q.Equals("cluster_id", clusterObj.GetId()) } diff --git a/pkg/compute/models/loadbalancerlistenerresource.go b/pkg/compute/models/loadbalancerlistenerresource.go index fb058aa078..fc6f821d6c 100644 --- a/pkg/compute/models/loadbalancerlistenerresource.go +++ b/pkg/compute/models/loadbalancerlistenerresource.go @@ -40,6 +40,19 @@ type SLoadbalancerListenerResourceBaseManager struct { SLoadbalancerResourceBaseManager } +func ValidateLoadbalancerListenerResourceInput(userCred mcclient.TokenCredential, input api.LoadbalancerListenerResourceInput) (*SLoadbalancerListener, api.LoadbalancerListenerResourceInput, error) { + listenerObj, err := LoadbalancerListenerManager.FetchByIdOrName(userCred, input.Listener) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", LoadbalancerListenerManager.Keyword(), input.Listener) + } else { + return nil, input, errors.Wrap(err, "LoadbalancerListenerManager.FetchByIdOrName") + } + } + input.Listener = listenerObj.GetId() + return listenerObj.(*SLoadbalancerListener), input, nil +} + func (self *SLoadbalancerListenerResourceBase) GetLoadbalancerListener() *SLoadbalancerListener { listener, err := LoadbalancerListenerManager.FetchById(self.ListenerId) if err != nil { @@ -125,13 +138,9 @@ func (manager *SLoadbalancerListenerResourceBaseManager) ListItemFilter( query api.LoadbalancerListenerFilterListInput, ) (*sqlchemy.SQuery, error) { if len(query.Listener) > 0 { - listenerObj, err := LoadbalancerListenerManager.FetchByIdOrName(userCred, query.Listener) + listenerObj, _, err := ValidateLoadbalancerListenerResourceInput(userCred, query.LoadbalancerListenerResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(LoadbalancerListenerManager.Keyword(), query.Listener) - } else { - return nil, errors.Wrap(err, "LoadbalancerListenerManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateLoadbalancerListenerResourceInput") } q = q.Equals("listener_id", listenerObj.GetId()) } diff --git a/pkg/compute/models/loadbalancerlistenerrules.go b/pkg/compute/models/loadbalancerlistenerrules.go index bed4b879fb..aec5de29d6 100644 --- a/pkg/compute/models/loadbalancerlistenerrules.go +++ b/pkg/compute/models/loadbalancerlistenerrules.go @@ -927,7 +927,7 @@ func (lbr *SLoadbalancerListenerRule) SyncWithCloudLoadbalancerListenerRule( return nil }*/ -func (manager *SLoadbalancerListenerRuleManager) GetResourceCount() ([]db.SProjectResourceCount, error) { +func (manager *SLoadbalancerListenerRuleManager) GetResourceCount() ([]db.SScopeResourceCount, error) { virts := manager.Query().IsFalse("pending_deleted") return db.CalculateProjectResourceCount(virts) } diff --git a/pkg/compute/models/loadbalancerlisteners.go b/pkg/compute/models/loadbalancerlisteners.go index dbce43900b..237aa88162 100644 --- a/pkg/compute/models/loadbalancerlisteners.go +++ b/pkg/compute/models/loadbalancerlisteners.go @@ -1224,7 +1224,7 @@ func (manager *SLoadbalancerListenerManager) InitializeData() error { return nil } -func (manager *SLoadbalancerListenerManager) GetResourceCount() ([]db.SProjectResourceCount, error) { +func (manager *SLoadbalancerListenerManager) GetResourceCount() ([]db.SScopeResourceCount, error) { virts := manager.Query().IsFalse("pending_deleted") return db.CalculateProjectResourceCount(virts) } diff --git a/pkg/compute/models/loadbalancerresource.go b/pkg/compute/models/loadbalancerresource.go index 04e902e581..6880142cf0 100644 --- a/pkg/compute/models/loadbalancerresource.go +++ b/pkg/compute/models/loadbalancerresource.go @@ -41,6 +41,19 @@ type SLoadbalancerResourceBaseManager struct { SZoneResourceBaseManager } +func ValidateLoadbalancerResourceInput(userCred mcclient.TokenCredential, input api.LoadbalancerResourceInput) (*SLoadbalancer, api.LoadbalancerResourceInput, error) { + lbObj, err := LoadbalancerManager.FetchByIdOrName(userCred, input.Loadbalancer) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", LoadbalancerManager.Keyword(), input.Loadbalancer) + } else { + return nil, input, errors.Wrap(err, "LoadbalancerManager.FetchByIdOrName") + } + } + input.Loadbalancer = lbObj.GetId() + return lbObj.(*SLoadbalancer), input, nil +} + func (self *SLoadbalancerResourceBase) GetLoadbalancer() *SLoadbalancer { w, _ := LoadbalancerManager.FetchById(self.LoadbalancerId) if w != nil { @@ -176,13 +189,9 @@ func (manager *SLoadbalancerResourceBaseManager) ListItemFilter( query api.LoadbalancerFilterListInput, ) (*sqlchemy.SQuery, error) { if len(query.Loadbalancer) > 0 { - lbObj, err := LoadbalancerManager.FetchByIdOrName(userCred, query.Loadbalancer) + lbObj, _, err := ValidateLoadbalancerResourceInput(userCred, query.LoadbalancerResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(LoadbalancerManager.Keyword(), query.Loadbalancer) - } else { - return nil, errors.Wrap(err, "LoadbalancerManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateLoadbalancerResourceInput") } q = q.Equals("loadbalancer_id", lbObj.GetId()) } diff --git a/pkg/compute/models/loadbalancers.go b/pkg/compute/models/loadbalancers.go index fc0b2d0101..73a419a253 100644 --- a/pkg/compute/models/loadbalancers.go +++ b/pkg/compute/models/loadbalancers.go @@ -81,7 +81,7 @@ type SLoadbalancer struct { SManagedResourceBase SCloudregionResourceBase - // LB must be in a VPC, vpc_id, manager_id, cloudregion_id + // LB might optionally be in a VPC, vpc_id, manager_id, cloudregion_id SVpcResourceBase `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"` // zone_id SZoneResourceBase @@ -241,43 +241,61 @@ func (man *SLoadbalancerManager) QueryDistinctExtraField(q *sqlchemy.SQuery, fie return q, httperrors.ErrNotFound } -func (man *SLoadbalancerManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.LoadbalancerCreateInput) (*jsonutils.JSONDict, error) { +func (man *SLoadbalancerManager) ValidateCreateData( + ctx context.Context, + userCred mcclient.TokenCredential, + ownerId mcclient.IIdentityProvider, + query jsonutils.JSONObject, + input api.LoadbalancerCreateInput, +) (*jsonutils.JSONDict, error) { + var err error + var region *SCloudregion if len(input.Vpc) > 0 { - vpc, err := db.FetchByIdOrName(VpcManager, userCred, input.Vpc) + var vpc *SVpc + vpc, input.VpcResourceInput, err = ValidateVpcResourceInput(userCred, input.VpcResourceInput) if err != nil { - return nil, httperrors.NewBadRequestError("getting vpc failed: %v", err) + return nil, errors.Wrap(err, "ValidateVpcResourceInput") } - input.VpcId = vpc.GetId() - region, _ = vpc.(*SVpc).GetRegion() + region, _ = vpc.GetRegion() } else if len(input.Zone) > 0 { - zone, err := db.FetchByIdOrName(ZoneManager, userCred, input.Zone) + var zone *SZone + zone, input.ZoneResourceInput, err = ValidateZoneResourceInput(userCred, input.ZoneResourceInput) if err != nil { - return nil, httperrors.NewBadRequestError("getting zone failed: %v", err) + return nil, errors.Wrap(err, "ValidateZoneResourceInput") } - input.ZoneId = zone.GetId() - region = zone.(*SZone).GetRegion() + region = zone.GetRegion() } else if len(input.Network) > 0 { - network, err := db.FetchByIdOrName(NetworkManager, userCred, strings.Split(input.Network, ",")[0]) - if err != nil { - return nil, httperrors.NewBadRequestError("getting network failed: %v", err) + if strings.IndexByte(input.Network, ',') >= 0 { + input.Network = strings.Split(input.Network, ",")[0] } - region = network.(*SNetwork).GetRegion() + var network *SNetwork + network, input.NetworkResourceInput, err = ValidateNetworkResourceInput(userCred, input.NetworkResourceInput) + if err != nil { + return nil, errors.Wrap(err, "ValidateNetworkResourceInput") + } + region = network.GetRegion() } if region == nil { return nil, httperrors.NewBadRequestError("cannot find region info") } - input.CloudregionId = region.GetId() - var err error + input.Cloudregion = region.GetId() + + if len(input.Cloudprovider) > 0 { + _, input.CloudproviderResourceInput, err = ValidateCloudproviderResourceInput(userCred, input.CloudproviderResourceInput) + if err != nil { + return nil, errors.Wrap(err, "ValidateCloudproviderResourceInput") + } + } + input.VirtualResourceCreateInput, err = man.SVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.VirtualResourceCreateInput) if err != nil { return nil, err } - ctx = context.WithValue(ctx, "ownerId", ownerId) - return region.GetDriver().ValidateCreateLoadbalancerData(ctx, userCred, input.JSON(input)) + return region.GetDriver().ValidateCreateLoadbalancerData(ctx, userCred, ownerId, input.JSON(input)) } func (lb *SLoadbalancer) AllowPerformStatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool { @@ -694,8 +712,8 @@ func (man *SLoadbalancerManager) newFromCloudLoadbalancer(ctx context.Context, u lb := SLoadbalancer{} lb.SetModelManager(man, &lb) - // lb.ManagerId = provider.Id - // lb.CloudregionId = region.Id + lb.ManagerId = provider.Id + lb.CloudregionId = region.Id lb.Address = extLb.GetAddress() lb.AddressType = extLb.GetAddressType() lb.NetworkType = extLb.GetNetworkType() @@ -940,7 +958,7 @@ func (man *SLoadbalancerManager) InitializeData() error { return nil } -func (manager *SLoadbalancerManager) GetResourceCount() ([]db.SProjectResourceCount, error) { +func (manager *SLoadbalancerManager) GetResourceCount() ([]db.SScopeResourceCount, error) { virts := manager.Query().IsFalse("pending_deleted") return db.CalculateProjectResourceCount(virts) } diff --git a/pkg/compute/models/managedresource.go b/pkg/compute/models/managedresource.go index e1b778de8c..4d27206cb6 100644 --- a/pkg/compute/models/managedresource.go +++ b/pkg/compute/models/managedresource.go @@ -19,14 +19,11 @@ import ( "database/sql" "strings" - "yunion.io/x/pkg/utils" - - "yunion.io/x/onecloud/pkg/util/rbacutils" - "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/errors" "yunion.io/x/pkg/util/reflectutils" + "yunion.io/x/pkg/utils" "yunion.io/x/sqlchemy" "yunion.io/x/onecloud/pkg/apis" @@ -36,6 +33,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "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" ) @@ -48,6 +46,19 @@ type SManagedResourceBaseManager struct { managerIdFieldName string } +func ValidateCloudproviderResourceInput(userCred mcclient.TokenCredential, query api.CloudproviderResourceInput) (*SCloudprovider, api.CloudproviderResourceInput, error) { + managerObj, err := CloudproviderManager.FetchByIdOrName(userCred, query.Cloudprovider) + if err != nil { + if err == sql.ErrNoRows { + return nil, query, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", CloudproviderManager.Keyword(), query.Cloudprovider) + } else { + return nil, query, errors.Wrap(err, "CloudproviderManager.FetchByIdOrName") + } + } + query.Cloudprovider = managerObj.GetId() + return managerObj.(*SCloudprovider), query, nil +} + func (manager *SManagedResourceBaseManager) getManagerIdFileName() string { if len(manager.managerIdFieldName) > 0 { return manager.managerIdFieldName @@ -499,7 +510,7 @@ func managedResourceFilterByZone(q *sqlchemy.SQuery, query api.ZonalFilterListIn q = q.Filter(sqlchemy.In(q.Field(filterField), sq.SubQuery())) } } else if len(query.Zone) > 0 { - zoneObj, err := ValidateZoneResourceInput(nil, query.ZoneResourceInput) + zoneObj, _, err := ValidateZoneResourceInput(nil, query.ZoneResourceInput) if err != nil { return nil, errors.Wrap(err, "ValidateZoneResourceInput") } @@ -518,13 +529,9 @@ func managedResourceFilterByZone(q *sqlchemy.SQuery, query api.ZonalFilterListIn func managedResourceFilterByRegion(q *sqlchemy.SQuery, query api.RegionalFilterListInput, filterField string, subqFunc func() *sqlchemy.SQuery) (*sqlchemy.SQuery, error) { regionStr := query.Cloudregion if len(regionStr) > 0 { - regionObj, err := CloudregionManager.FetchByIdOrName(nil, regionStr) + regionObj, _, err := ValidateCloudregionResourceInput(nil, query.CloudregionResourceInput) if err != nil { - if err == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(CloudregionManager.Keyword(), regionStr) - } else { - return nil, httperrors.NewGeneralError(err) - } + return nil, errors.Wrap(err, "ValidateCloudregionResourceInput") } if len(filterField) == 0 { q = q.Filter(sqlchemy.Equals(q.Field("cloudregion_id"), regionObj.GetId())) diff --git a/pkg/compute/models/natgatewayresource.go b/pkg/compute/models/natgatewayresource.go index 302e3c36fd..305a6077a8 100644 --- a/pkg/compute/models/natgatewayresource.go +++ b/pkg/compute/models/natgatewayresource.go @@ -39,6 +39,19 @@ type SNatgatewayResourceBaseManager struct { SVpcResourceBaseManager } +func ValidateNatGatewayResourceInput(userCred mcclient.TokenCredential, input api.NatGatewayResourceInput) (*SNatGateway, api.NatGatewayResourceInput, error) { + natObj, err := NatGatewayManager.FetchByIdOrName(userCred, input.Natgateway) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", NatGatewayManager.Keyword(), input.Natgateway) + } else { + return nil, input, errors.Wrap(err, "NatGatewayManager.FetchByIdOrName") + } + } + input.Natgateway = natObj.GetId() + return natObj.(*SNatGateway), input, nil +} + func (self *SNatgatewayResourceBase) GetNatgateway() (*SNatGateway, error) { obj, err := NatGatewayManager.FetchById(self.NatgatewayId) if err != nil { @@ -108,13 +121,9 @@ func (manager *SNatgatewayResourceBaseManager) ListItemFilter( query api.NatGatewayFilterListInput, ) (*sqlchemy.SQuery, error) { if len(query.Natgateway) > 0 { - natObj, err := NatGatewayManager.FetchByIdOrName(userCred, query.Natgateway) + natObj, _, err := ValidateNatGatewayResourceInput(userCred, query.NatGatewayResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(NatGatewayManager.Keyword(), query.Natgateway) - } else { - return nil, errors.Wrap(err, "NatGatewayManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateNatGatewayResourceInput") } q = q.Equals("natgateway_id", natObj.GetId()) } diff --git a/pkg/compute/models/networkresource.go b/pkg/compute/models/networkresource.go index 170569f149..76cc32a812 100644 --- a/pkg/compute/models/networkresource.go +++ b/pkg/compute/models/networkresource.go @@ -39,6 +39,19 @@ type SNetworkResourceBaseManager struct { SWireResourceBaseManager } +func ValidateNetworkResourceInput(userCred mcclient.TokenCredential, query api.NetworkResourceInput) (*SNetwork, api.NetworkResourceInput, error) { + netObj, err := NetworkManager.FetchByIdOrName(userCred, query.Network) + if err != nil { + if err == sql.ErrNoRows { + return nil, query, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", NetworkManager.Keyword(), query.Network) + } else { + return nil, query, errors.Wrap(err, "NetworkManager.FetchByIdOrName") + } + } + query.Network = netObj.GetId() + return netObj.(*SNetwork), query, nil +} + func (self *SNetworkResourceBase) GetNetwork() *SNetwork { obj, _ := NetworkManager.FetchById(self.NetworkId) if obj != nil { @@ -135,13 +148,9 @@ func (manager *SNetworkResourceBaseManager) ListItemFilter( query api.NetworkFilterListInput, ) (*sqlchemy.SQuery, error) { if len(query.Network) > 0 { - netObj, err := NetworkManager.FetchByIdOrName(userCred, query.Network) + netObj, _, err := ValidateNetworkResourceInput(userCred, query.NetworkResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(NetworkManager.Keyword(), query.Network) - } else { - return nil, errors.Wrap(err, "NetworkManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateNetworkResourceInput") } q = q.Equals("network_id", netObj.GetId()) } diff --git a/pkg/compute/models/networks.go b/pkg/compute/models/networks.go index 5a95392959..1f6366c159 100644 --- a/pkg/compute/models/networks.go +++ b/pkg/compute/models/networks.go @@ -36,7 +36,6 @@ import ( "yunion.io/x/onecloud/pkg/apis" api "yunion.io/x/onecloud/pkg/apis/compute" - "yunion.io/x/onecloud/pkg/cloudcommon/consts" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman" "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman" @@ -566,7 +565,9 @@ func (manager *SNetworkManager) getNetworksByWire(wire *SWire) ([]SNetwork, erro return nets, nil */ } -func (manager *SNetworkManager) SyncNetworks(ctx context.Context, userCred mcclient.TokenCredential, wire *SWire, nets []cloudprovider.ICloudNetwork, syncOwnerId mcclient.IIdentityProvider) ([]SNetwork, []cloudprovider.ICloudNetwork, compare.SyncResult) { +func (manager *SNetworkManager) SyncNetworks(ctx context.Context, userCred mcclient.TokenCredential, wire *SWire, nets []cloudprovider.ICloudNetwork, provider *SCloudprovider) ([]SNetwork, []cloudprovider.ICloudNetwork, compare.SyncResult) { + syncOwnerId := provider.GetOwnerId() + lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, syncOwnerId)) defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, syncOwnerId)) @@ -607,7 +608,7 @@ func (manager *SNetworkManager) SyncNetworks(ctx context.Context, userCred mccli } } for i := 0; i < len(commondb); i += 1 { - err = commondb[i].SyncWithCloudNetwork(ctx, userCred, commonext[i], syncOwnerId) + err = commondb[i].SyncWithCloudNetwork(ctx, userCred, commonext[i], syncOwnerId, provider) if err != nil { syncResult.UpdateError(err) } else { @@ -618,7 +619,7 @@ func (manager *SNetworkManager) SyncNetworks(ctx context.Context, userCred mccli } } for i := 0; i < len(added); i += 1 { - new, err := manager.newFromCloudNetwork(ctx, userCred, added[i], wire, syncOwnerId) + new, err := manager.newFromCloudNetwork(ctx, userCred, added[i], wire, syncOwnerId, provider) if err != nil { syncResult.AddError(err) } else { @@ -650,7 +651,7 @@ func (self *SNetwork) syncRemoveCloudNetwork(ctx context.Context, userCred mccli return err } -func (self *SNetwork) SyncWithCloudNetwork(ctx context.Context, userCred mcclient.TokenCredential, extNet cloudprovider.ICloudNetwork, syncOwnerId mcclient.IIdentityProvider) error { +func (self *SNetwork) SyncWithCloudNetwork(ctx context.Context, userCred mcclient.TokenCredential, extNet cloudprovider.ICloudNetwork, syncOwnerId mcclient.IIdentityProvider, provider *SCloudprovider) error { vpc := self.GetVpc() diff, err := db.UpdateWithLock(ctx, self, func() error { extNet.Refresh() @@ -673,10 +674,14 @@ func (self *SNetwork) SyncWithCloudNetwork(ctx context.Context, userCred mcclien SyncCloudProject(userCred, self, syncOwnerId, extNet, vpc.ManagerId) + if provider != nil { + self.SyncShareState(ctx, userCred, provider.getAccountShareInfo()) + } + return nil } -func (manager *SNetworkManager) newFromCloudNetwork(ctx context.Context, userCred mcclient.TokenCredential, extNet cloudprovider.ICloudNetwork, wire *SWire, syncOwnerId mcclient.IIdentityProvider) (*SNetwork, error) { +func (manager *SNetworkManager) newFromCloudNetwork(ctx context.Context, userCred mcclient.TokenCredential, extNet cloudprovider.ICloudNetwork, wire *SWire, syncOwnerId mcclient.IIdentityProvider, provider *SCloudprovider) (*SNetwork, error) { net := SNetwork{} net.SetModelManager(manager, &net) @@ -693,12 +698,12 @@ func (manager *SNetworkManager) newFromCloudNetwork(ctx context.Context, userCre net.GuestIpMask = extNet.GetIpMask() net.GuestGateway = extNet.GetGateway() net.ServerType = extNet.GetServerType() - net.IsPublic = extNet.GetIsPublic() - extScope := extNet.GetPublicScope() - if extScope == rbacutils.ScopeDomain && !consts.GetNonDefaultDomainProjects() { - extScope = rbacutils.ScopeSystem - } - net.PublicScope = string(extScope) + // net.IsPublic = extNet.GetIsPublic() + // extScope := extNet.GetPublicScope() + // if extScope == rbacutils.ScopeDomain && !consts.GetNonDefaultDomainProjects() { + // extScope = rbacutils.ScopeSystem + // } + // net.PublicScope = string(extScope) net.AllocTimoutSeconds = extNet.GetAllocTimeoutSeconds() @@ -711,6 +716,10 @@ func (manager *SNetworkManager) newFromCloudNetwork(ctx context.Context, userCre vpc := wire.GetVpc() SyncCloudProject(userCred, &net, syncOwnerId, extNet, vpc.ManagerId) + if provider != nil { + net.SyncShareState(ctx, userCred, provider.getAccountShareInfo()) + } + db.OpsLog.LogEvent(&net, db.ACT_CREATE, net.GetShortDesc(ctx), userCred) return &net, nil diff --git a/pkg/compute/models/regiondrivers.go b/pkg/compute/models/regiondrivers.go index 74615b21a0..353e8596b7 100644 --- a/pkg/compute/models/regiondrivers.go +++ b/pkg/compute/models/regiondrivers.go @@ -38,7 +38,7 @@ type IRegionDriver interface { IElasticcacheBackup IDBInstanceDriver - ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) + ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) ValidateDeleteLoadbalancerCondition(ctx context.Context, lb *SLoadbalancer) error RequestCreateLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, task taskman.ITask) error RequestDeleteLoadbalancer(ctx context.Context, userCred mcclient.TokenCredential, lb *SLoadbalancer, task taskman.ITask) error diff --git a/pkg/compute/models/routetables.go b/pkg/compute/models/routetables.go index d81df739c3..edc751ab9a 100644 --- a/pkg/compute/models/routetables.go +++ b/pkg/compute/models/routetables.go @@ -154,11 +154,10 @@ func (man *SRouteTableManager) ValidateCreateData( if err != nil { return input, errors.Wrap(err, "validateRoutes") } - vpcObj, err := ValidateVpcResourceInput(userCred, input.VpcResourceInput) + _, input.VpcResourceInput, err = ValidateVpcResourceInput(userCred, input.VpcResourceInput) if err != nil { return input, errors.Wrap(err, "ValidateVpcResourceInput") } - input.Vpc = vpcObj.Id input.StatusInfrasResourceBaseCreateInput, err = man.SStatusInfrasResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.StatusInfrasResourceBaseCreateInput) if err != nil { return input, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ValidateCreateData") diff --git a/pkg/compute/models/schedtagresource.go b/pkg/compute/models/schedtagresource.go index 5ac9c3e4a4..5facfbd233 100644 --- a/pkg/compute/models/schedtagresource.go +++ b/pkg/compute/models/schedtagresource.go @@ -38,6 +38,19 @@ type SSchedtagResourceBase struct { type SSchedtagResourceBaseManager struct{} +func ValidateSchedtagResourceInput(userCred mcclient.TokenCredential, query api.SchedtagResourceInput) (*SSchedtag, api.SchedtagResourceInput, error) { + tagObj, err := SchedtagManager.FetchByIdOrName(userCred, query.Schedtag) + if err != nil { + if err == sql.ErrNoRows { + return nil, query, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", SchedtagManager.Keyword(), query.Schedtag) + } else { + return nil, query, errors.Wrap(err, "SchedtagManager.FetchByIdOrName") + } + } + query.Schedtag = tagObj.GetId() + return tagObj.(*SSchedtag), query, nil +} + func (self *SSchedtagResourceBase) GetSchedtag() *SSchedtag { obj, err := SchedtagManager.FetchById(self.SchedtagId) if err != nil { @@ -98,13 +111,9 @@ func (manager *SSchedtagResourceBaseManager) ListItemFilter( query api.SchedtagFilterListInput, ) (*sqlchemy.SQuery, error) { if len(query.Schedtag) > 0 { - tagObj, err := SchedtagManager.FetchByIdOrName(userCred, query.Schedtag) + tagObj, _, err := ValidateSchedtagResourceInput(userCred, query.SchedtagResourceInput) if err != nil { - if err == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(SchedtagManager.Keyword(), query.Schedtag) - } else { - return nil, errors.Wrap(err, "SchedtagManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateSchedtagResourceInput") } q = q.Equals("schedtag_id", tagObj.GetId()) } diff --git a/pkg/compute/models/secgroupresource.go b/pkg/compute/models/secgroupresource.go index 0947c1d5c8..04272f1b1b 100644 --- a/pkg/compute/models/secgroupresource.go +++ b/pkg/compute/models/secgroupresource.go @@ -38,6 +38,19 @@ type SSecurityGroupResourceBase struct { type SSecurityGroupResourceBaseManager struct{} +func ValidateSecurityGroupResourceInput(userCred mcclient.TokenCredential, query api.SecgroupResourceInput) (*SSecurityGroup, api.SecgroupResourceInput, error) { + secgrpObj, err := SecurityGroupManager.FetchByIdOrName(userCred, query.Secgroup) + if err != nil { + if err == sql.ErrNoRows { + return nil, query, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", SecurityGroupManager.Keyword(), query.Secgroup) + } else { + return nil, query, errors.Wrap(err, "SecurityGroupManager.FetchByIdOrName") + } + } + query.Secgroup = secgrpObj.GetId() + return secgrpObj.(*SSecurityGroup), query, nil +} + func (self *SSecurityGroupResourceBase) GetSecGroup() *SSecurityGroup { secgrp, err := SecurityGroupManager.FetchById(self.SecgroupId) if err != nil { @@ -95,13 +108,9 @@ func (manager *SSecurityGroupResourceBaseManager) ListItemFilter( query api.SecgroupFilterListInput, ) (*sqlchemy.SQuery, error) { if len(query.Secgroup) > 0 { - secgrpObj, err := SecurityGroupManager.FetchByIdOrName(userCred, query.Secgroup) + secgrpObj, _, err := ValidateSecurityGroupResourceInput(userCred, query.SecgroupResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(SecurityGroupManager.Keyword(), query.Secgroup) - } else { - return nil, errors.Wrap(err, "SecurityGroupManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateSecurityGroupResourceInput") } q = q.Equals("secgroup_id", secgrpObj.GetId()) } diff --git a/pkg/compute/models/secgroups.go b/pkg/compute/models/secgroups.go index 293e962bfd..38c9897017 100644 --- a/pkg/compute/models/secgroups.go +++ b/pkg/compute/models/secgroups.go @@ -119,12 +119,9 @@ func (manager *SSecurityGroupManager) ListItemFilter( } serverStr := input.Server if len(serverStr) > 0 { - guest, err := GuestManager.FetchByIdOrName(userCred, serverStr) + guest, _, err := ValidateGuestResourceInput(userCred, input.ServerResourceInput) if err != nil { - if err != sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(GuestManager.Keyword(), serverStr) - } - return nil, httperrors.NewGeneralError(err) + return nil, errors.Wrap(err, "ValidateGuestResourceInput") } serverId := guest.GetId() filters := []sqlchemy.ICondition{} @@ -132,7 +129,7 @@ func (manager *SSecurityGroupManager) ListItemFilter( filters = append(filters, sqlchemy.In(q.Field("id"), GuestsecgroupManager.Query("secgroup_id").Equals("guest_id", serverId).SubQuery())) isAdmin := false - admin := (input.Admin != nil && *input.Admin) + admin := (input.ServerFilterListInput.Admin != nil && *input.ServerFilterListInput.Admin) if consts.IsRbacEnabled() { allowScope := policy.PolicyManager.AllowScope(userCred, consts.GetServiceType(), manager.KeywordPlural(), policy.PolicyActionList) if allowScope == rbacutils.ScopeSystem || allowScope == rbacutils.ScopeDomain { diff --git a/pkg/compute/models/snapshotpolicyresource.go b/pkg/compute/models/snapshotpolicyresource.go index f313b924ee..826becf966 100644 --- a/pkg/compute/models/snapshotpolicyresource.go +++ b/pkg/compute/models/snapshotpolicyresource.go @@ -38,6 +38,19 @@ type SSnapshotPolicyResourceBase struct { type SSnapshotPolicyResourceBaseManager struct{} +func ValidateSnapshotPolicyResourceInput(userCred mcclient.TokenCredential, query api.SnapshotPolicyResourceInput) (*SSnapshotPolicy, api.SnapshotPolicyResourceInput, error) { + snapPolicyObj, err := SnapshotPolicyManager.FetchByIdOrName(userCred, query.Snapshotpolicy) + if err != nil { + if err == sql.ErrNoRows { + return nil, query, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", SnapshotPolicyManager.Keyword(), query.Snapshotpolicy) + } else { + return nil, query, errors.Wrap(err, "SnapshotPolicyManager.FetchByIdOrName") + } + } + query.Snapshotpolicy = snapPolicyObj.GetId() + return snapPolicyObj.(*SSnapshotPolicy), query, nil +} + func (self *SSnapshotPolicyResourceBase) GetSnapshotPolicy() *SSnapshotPolicy { spObj, err := SnapshotPolicyManager.FetchById(self.SnapshotpolicyId) if err != nil { @@ -95,13 +108,9 @@ func (manager *SSnapshotPolicyResourceBaseManager) ListItemFilter( query api.SnapshotPolicyFilterListInput, ) (*sqlchemy.SQuery, error) { if len(query.Snapshotpolicy) > 0 { - snapPObj, err := SnapshotPolicyManager.FetchByIdOrName(userCred, query.Snapshotpolicy) + snapPObj, _, err := ValidateSnapshotPolicyResourceInput(userCred, query.SnapshotPolicyResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(SnapshotPolicyManager.Keyword(), query.Snapshotpolicy) - } else { - return nil, errors.Wrap(err, "SnapshotPolicyManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateSnapshotPolicyResourceInput") } q = q.Equals("snapshotpolicy_id", snapPObj.GetId()) } diff --git a/pkg/compute/models/snapshots.go b/pkg/compute/models/snapshots.go index 4af11e5fb3..b656b4174d 100644 --- a/pkg/compute/models/snapshots.go +++ b/pkg/compute/models/snapshots.go @@ -1014,7 +1014,7 @@ func (self *SSnapshot) getCloudProviderInfo() SCloudProviderInfo { return MakeCloudProviderInfo(region, nil, provider) } -func (manager *SSnapshotManager) GetResourceCount() ([]db.SProjectResourceCount, error) { +func (manager *SSnapshotManager) GetResourceCount() ([]db.SScopeResourceCount, error) { virts := manager.Query().IsFalse("fake_deleted") return db.CalculateProjectResourceCount(virts) } diff --git a/pkg/compute/models/storageresource.go b/pkg/compute/models/storageresource.go index 4bb32db822..9c40daf435 100644 --- a/pkg/compute/models/storageresource.go +++ b/pkg/compute/models/storageresource.go @@ -40,6 +40,19 @@ type SStorageResourceBaseManager struct { SManagedResourceBaseManager } +func ValidateStorageResourceInput(userCred mcclient.TokenCredential, query api.StorageResourceInput) (*SStorage, api.StorageResourceInput, error) { + storageObj, err := StorageManager.FetchByIdOrName(userCred, query.Storage) + if err != nil { + if err == sql.ErrNoRows { + return nil, query, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", StorageManager.Keyword(), query.Storage) + } else { + return nil, query, errors.Wrap(err, "StorageManager.FetchByIdOrName") + } + } + query.Storage = storageObj.GetId() + return storageObj.(*SStorage), query, nil +} + func (self *SStorageResourceBase) GetExtraDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) api.StorageResourceInfo { return api.StorageResourceInfo{} } @@ -104,13 +117,9 @@ func (manager *SStorageResourceBaseManager) ListItemFilter( query api.StorageFilterListInput, ) (*sqlchemy.SQuery, error) { if len(query.Storage) > 0 { - storageObj, err := StorageManager.FetchByIdOrName(userCred, query.Storage) + storageObj, _, err := ValidateStorageResourceInput(userCred, query.StorageResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(StorageManager.Keyword(), query.Storage) - } else { - return nil, errors.Wrap(err, "StorageManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateStorageResourceInput") } q = q.Equals("storage_id", storageObj.GetId()) } diff --git a/pkg/compute/models/storages.go b/pkg/compute/models/storages.go index 36004937a2..79e5cf4986 100644 --- a/pkg/compute/models/storages.go +++ b/pkg/compute/models/storages.go @@ -196,6 +196,8 @@ func (manager *SStorageManager) ValidateCreateData( query jsonutils.JSONObject, input api.StorageCreateInput, ) (api.StorageCreateInput, error) { + var err error + if !utils.IsInStringArray(input.StorageType, api.STORAGE_TYPES) { return input, httperrors.NewInputParameterError("Invalid storage type %s", input.StorageType) } @@ -205,11 +207,10 @@ func (manager *SStorageManager) ValidateCreateData( if len(input.Zone) == 0 { return input, httperrors.NewMissingParameterError("zone") } - zone, err := ValidateZoneResourceInput(userCred, input.ZoneResourceInput) + _, input.ZoneResourceInput, err = ValidateZoneResourceInput(userCred, input.ZoneResourceInput) if err != nil { return input, errors.Wrap(err, "ValidateZoneResourceInput") } - input.Zone = zone.GetId() storageDirver := GetStorageDriver(input.StorageType) if storageDirver == nil { diff --git a/pkg/compute/models/vpcresource.go b/pkg/compute/models/vpcresource.go index 6771c3a53c..236a727e18 100644 --- a/pkg/compute/models/vpcresource.go +++ b/pkg/compute/models/vpcresource.go @@ -41,16 +41,17 @@ type SVpcResourceBaseManager struct { SManagedResourceBaseManager } -func ValidateVpcResourceInput(userCred mcclient.TokenCredential, input api.VpcResourceInput) (*SVpc, error) { +func ValidateVpcResourceInput(userCred mcclient.TokenCredential, input api.VpcResourceInput) (*SVpc, api.VpcResourceInput, error) { vpcObj, err := VpcManager.FetchByIdOrName(userCred, input.Vpc) if err != nil { if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(VpcManager.Keyword(), input.Vpc) + return nil, input, httperrors.NewResourceNotFoundError2(VpcManager.Keyword(), input.Vpc) } else { - return nil, errors.Wrap(err, "VpcManager.FetchByIdOrName") + return nil, input, errors.Wrap(err, "VpcManager.FetchByIdOrName") } } - return vpcObj.(*SVpc), nil + input.Vpc = vpcObj.GetId() + return vpcObj.(*SVpc), input, nil } func (self *SVpcResourceBase) GetVpc() *SVpc { @@ -174,7 +175,7 @@ func (manager *SVpcResourceBaseManager) ListItemFilter( ) (*sqlchemy.SQuery, error) { var err error if len(query.Vpc) > 0 { - vpcObj, err := ValidateVpcResourceInput(userCred, query.VpcResourceInput) + vpcObj, _, err := ValidateVpcResourceInput(userCred, query.VpcResourceInput) if err != nil { return nil, errors.Wrap(err, "ValidateVpcResourceInput") } diff --git a/pkg/compute/models/vpcs.go b/pkg/compute/models/vpcs.go index 64be9e15df..eb0fe7a790 100644 --- a/pkg/compute/models/vpcs.go +++ b/pkg/compute/models/vpcs.go @@ -20,8 +20,6 @@ import ( "fmt" "strings" - "yunion.io/x/onecloud/pkg/util/rbacutils" - "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/errors" @@ -37,6 +35,7 @@ import ( "yunion.io/x/onecloud/pkg/cloudprovider" "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" ) diff --git a/pkg/compute/models/wireresource.go b/pkg/compute/models/wireresource.go index d60b5af3ec..1c05215ba5 100644 --- a/pkg/compute/models/wireresource.go +++ b/pkg/compute/models/wireresource.go @@ -41,6 +41,19 @@ type SWireResourceBaseManager struct { SZoneResourceBaseManager } +func ValidateWireResourceInput(userCred mcclient.TokenCredential, input api.WireResourceInput) (*SWire, api.WireResourceInput, error) { + wireObj, err := WireManager.FetchByIdOrName(userCred, input.Wire) + if err != nil { + if errors.Cause(err) == sql.ErrNoRows { + return nil, input, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", WireManager.Keyword(), input.Wire) + } else { + return nil, input, errors.Wrap(err, "WireManager.FetchByIdOrName") + } + } + input.Wire = wireObj.GetId() + return wireObj.(*SWire), input, nil +} + func (self *SWireResourceBase) GetWire() *SWire { w, _ := WireManager.FetchById(self.WireId) if w != nil { @@ -138,13 +151,9 @@ func (manager *SWireResourceBaseManager) ListItemFilter( ) (*sqlchemy.SQuery, error) { var err error if len(query.Wire) > 0 { - wireObj, err := WireManager.FetchByIdOrName(userCred, query.Wire) + wireObj, _, err := ValidateWireResourceInput(userCred, query.WireResourceInput) if err != nil { - if errors.Cause(err) == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(WireManager.Keyword(), query.Wire) - } else { - return nil, errors.Wrap(err, "WireManager.FetchByIdOrName") - } + return nil, errors.Wrap(err, "ValidateWireResourceInput") } q = q.Equals("wire_id", wireObj.GetId()) } diff --git a/pkg/compute/models/wires.go b/pkg/compute/models/wires.go index 28f4553d1f..f5354455f8 100644 --- a/pkg/compute/models/wires.go +++ b/pkg/compute/models/wires.go @@ -97,6 +97,8 @@ func (manager *SWireManager) ValidateCreateData( query jsonutils.JSONObject, input api.WireCreateInput, ) (api.WireCreateInput, error) { + var err error + if input.Bandwidth < 0 { return input, httperrors.NewOutOfRangeError("bandwidth must be greater than 0") } @@ -109,11 +111,12 @@ func (manager *SWireManager) ValidateCreateData( return input, httperrors.NewMissingParameterError("vpc") } - vpc, err := ValidateVpcResourceInput(userCred, input.VpcResourceInput) + var vpc *SVpc + vpc, input.VpcResourceInput, err = ValidateVpcResourceInput(userCred, input.VpcResourceInput) if err != nil { return input, errors.Wrap(err, "ValidateVpcResourceInput") } - input.Vpc = vpc.Id + if len(vpc.ManagerId) > 0 { return input, httperrors.NewNotSupportedError("Currently only kvm platform supports creating wire") } @@ -122,11 +125,10 @@ func (manager *SWireManager) ValidateCreateData( return input, httperrors.NewMissingParameterError("zone") } - zone, err := ValidateZoneResourceInput(userCred, input.ZoneResourceInput) + _, input.ZoneResourceInput, err = ValidateZoneResourceInput(userCred, input.ZoneResourceInput) if err != nil { return input, errors.Wrap(err, "ValidateZoneResourceInput") } - input.Zone = zone.GetId() input.InfrasResourceBaseCreateInput, err = manager.SInfrasResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.InfrasResourceBaseCreateInput) if err != nil { diff --git a/pkg/compute/models/zoneresource.go b/pkg/compute/models/zoneresource.go index dc154d7c04..5ee10dba3c 100644 --- a/pkg/compute/models/zoneresource.go +++ b/pkg/compute/models/zoneresource.go @@ -39,16 +39,17 @@ type SZoneResourceBaseManager struct { SCloudregionResourceBaseManager } -func ValidateZoneResourceInput(userCred mcclient.TokenCredential, query api.ZoneResourceInput) (*SZone, error) { +func ValidateZoneResourceInput(userCred mcclient.TokenCredential, query api.ZoneResourceInput) (*SZone, api.ZoneResourceInput, error) { zoneObj, err := ZoneManager.FetchByIdOrName(userCred, query.Zone) if err != nil { if err == sql.ErrNoRows { - return nil, httperrors.NewResourceNotFoundError2(ZoneManager.Keyword(), query.Zone) + return nil, query, errors.Wrapf(httperrors.ErrResourceNotFound, "%s %s", ZoneManager.Keyword(), query.Zone) } else { - return nil, httperrors.NewGeneralError(err) + return nil, query, errors.Wrap(err, "ZoneManager.FetchByIdOrName") } } - return zoneObj.(*SZone), nil + query.Zone = zoneObj.GetId() + return zoneObj.(*SZone), query, nil } func (self *SZoneResourceBase) GetZone() *SZone { diff --git a/pkg/compute/regiondrivers/aliyun.go b/pkg/compute/regiondrivers/aliyun.go index 9134cae410..8a7739103c 100644 --- a/pkg/compute/regiondrivers/aliyun.go +++ b/pkg/compute/regiondrivers/aliyun.go @@ -143,8 +143,7 @@ func (self *SAliyunRegionDriver) validateCreateInternetLBData(ownerId mcclient.I return data, nil } -func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - ownerId := ctx.Value("ownerId").(mcclient.IIdentityProvider) +func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { addressTypeV := validators.NewStringChoicesValidator("address_type", api.LB_ADDR_TYPES) if err := addressTypeV.Validate(data); err != nil { return nil, err @@ -160,7 +159,7 @@ func (self *SAliyunRegionDriver) ValidateCreateLoadbalancerData(ctx context.Cont if _, err := validator(ownerId, data); err != nil { return nil, err } - return self.SManagedVirtualizationRegionDriver.ValidateCreateLoadbalancerData(ctx, userCred, data) + return self.SManagedVirtualizationRegionDriver.ValidateCreateLoadbalancerData(ctx, userCred, ownerId, data) } func (self *SAliyunRegionDriver) ValidateUpdateLoadbalancerCertificateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { diff --git a/pkg/compute/regiondrivers/aws.go b/pkg/compute/regiondrivers/aws.go index 4ffa793b4c..006de110fc 100644 --- a/pkg/compute/regiondrivers/aws.go +++ b/pkg/compute/regiondrivers/aws.go @@ -170,8 +170,7 @@ func (self *SAwsRegionDriver) validateCreateNetworkLBData(ownerId mcclient.IIden return data, nil } -func (self *SAwsRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - ownerId := ctx.Value("ownerId").(mcclient.IIdentityProvider) +func (self *SAwsRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { if spec, _ := data.GetString("loadbalancer_spec"); spec == api.LB_AWS_SPEC_APPLICATION { if _, err := self.validateCreateApplicationLBData(ownerId, data); err != nil { return nil, err @@ -184,7 +183,7 @@ func (self *SAwsRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context return nil, httperrors.NewInputParameterError("invalid parameter loadbalancer_spec %s", spec) } - return self.SManagedVirtualizationRegionDriver.ValidateCreateLoadbalancerData(ctx, userCred, data) + return self.SManagedVirtualizationRegionDriver.ValidateCreateLoadbalancerData(ctx, userCred, ownerId, data) } func (self *SAwsRegionDriver) validateCreateApplicationListenerData(ctx context.Context, ownerId mcclient.IIdentityProvider, lb *models.SLoadbalancer, backendGroup *models.SLoadbalancerBackendGroup, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { diff --git a/pkg/compute/regiondrivers/azure.go b/pkg/compute/regiondrivers/azure.go index 283f41dda9..daa2c2402d 100644 --- a/pkg/compute/regiondrivers/azure.go +++ b/pkg/compute/regiondrivers/azure.go @@ -38,7 +38,7 @@ func (self *SAzureRegionDriver) GetProvider() string { return api.CLOUD_PROVIDER_AZURE } -func (self *SAzureRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { +func (self *SAzureRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, owerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { return nil, httperrors.NewNotImplementedError("%s does not currently support creating loadbalancer", self.GetProvider()) } diff --git a/pkg/compute/regiondrivers/ctyun.go b/pkg/compute/regiondrivers/ctyun.go index b6186d42f6..af8f2f0b42 100644 --- a/pkg/compute/regiondrivers/ctyun.go +++ b/pkg/compute/regiondrivers/ctyun.go @@ -38,7 +38,7 @@ func (self *SCtyunRegionDriver) GetProvider() string { return api.CLOUD_PROVIDER_CTYUN } -func (self *SCtyunRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { +func (self *SCtyunRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { return nil, httperrors.NewNotImplementedError("%s does not currently support creating loadbalancer", self.GetProvider()) } diff --git a/pkg/compute/regiondrivers/esxi.go b/pkg/compute/regiondrivers/esxi.go index 0f985dfca5..cbba50ed95 100644 --- a/pkg/compute/regiondrivers/esxi.go +++ b/pkg/compute/regiondrivers/esxi.go @@ -39,7 +39,7 @@ func (self *SEsxiRegionDriver) GetProvider() string { return api.CLOUD_PROVIDER_VMWARE } -func (self *SEsxiRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { +func (self *SEsxiRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { return nil, httperrors.NewUnsupportOperationError("%s does not support creating loadbalancer", self.GetProvider()) } diff --git a/pkg/compute/regiondrivers/huawei.go b/pkg/compute/regiondrivers/huawei.go index 5d0f7943c7..a0066725c8 100644 --- a/pkg/compute/regiondrivers/huawei.go +++ b/pkg/compute/regiondrivers/huawei.go @@ -56,8 +56,7 @@ func (self *SHuaWeiRegionDriver) GetProvider() string { return api.CLOUD_PROVIDER_HUAWEI } -func (self *SHuaWeiRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - ownerId := ctx.Value("ownerId").(mcclient.IIdentityProvider) +func (self *SHuaWeiRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { zoneV := validators.NewModelIdOrNameValidator("zone", "zone", ownerId) managerIdV := validators.NewModelIdOrNameValidator("manager", "cloudprovider", ownerId) addressTypeV := validators.NewStringChoicesValidator("address_type", api.LB_ADDR_TYPES) @@ -113,7 +112,7 @@ func (self *SHuaWeiRegionDriver) ValidateCreateLoadbalancerData(ctx context.Cont data.Set("network_type", jsonutils.NewString(api.LB_NETWORK_TYPE_VPC)) data.Set("cloudregion_id", jsonutils.NewString(region.GetId())) data.Set("vpc_id", jsonutils.NewString(vpc.GetId())) - return self.SManagedVirtualizationRegionDriver.ValidateCreateLoadbalancerData(ctx, userCred, data) + return self.SManagedVirtualizationRegionDriver.ValidateCreateLoadbalancerData(ctx, userCred, ownerId, data) } // https://support.huaweicloud.com/api-elb/zh-cn_topic_0143878053.html diff --git a/pkg/compute/regiondrivers/kvm.go b/pkg/compute/regiondrivers/kvm.go index 13f74e7e0f..abec310cb9 100644 --- a/pkg/compute/regiondrivers/kvm.go +++ b/pkg/compute/regiondrivers/kvm.go @@ -62,8 +62,7 @@ func (self *SKVMRegionDriver) GetProvider() string { return api.CLOUD_PROVIDER_ONECLOUD } -func (self *SKVMRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - ownerId := ctx.Value("ownerId").(mcclient.IIdentityProvider) +func (self *SKVMRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { networkV := validators.NewModelIdOrNameValidator("network", "network", ownerId) addressV := validators.NewIPv4AddrValidator("address") clusterV := validators.NewModelIdOrNameValidator("cluster", "loadbalancercluster", ownerId) diff --git a/pkg/compute/regiondrivers/managedvirtual.go b/pkg/compute/regiondrivers/managedvirtual.go index 7cfcecf29c..d482bc4d4d 100644 --- a/pkg/compute/regiondrivers/managedvirtual.go +++ b/pkg/compute/regiondrivers/managedvirtual.go @@ -46,7 +46,7 @@ type SManagedVirtualizationRegionDriver struct { SVirtualizationRegionDriver } -func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { +func (self *SManagedVirtualizationRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, owerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { return self.ValidateManagerId(ctx, userCred, data) } diff --git a/pkg/compute/regiondrivers/openstack.go b/pkg/compute/regiondrivers/openstack.go index f770581b4f..eae1661151 100644 --- a/pkg/compute/regiondrivers/openstack.go +++ b/pkg/compute/regiondrivers/openstack.go @@ -39,7 +39,7 @@ func (self *SOpenStackRegionDriver) GetProvider() string { return api.CLOUD_PROVIDER_OPENSTACK } -func (self *SOpenStackRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { +func (self *SOpenStackRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { return nil, httperrors.NewNotImplementedError("%s does not currently support creating loadbalancer", self.GetProvider()) } diff --git a/pkg/compute/regiondrivers/qcloud.go b/pkg/compute/regiondrivers/qcloud.go index 57dea58f42..59a63303a1 100644 --- a/pkg/compute/regiondrivers/qcloud.go +++ b/pkg/compute/regiondrivers/qcloud.go @@ -49,8 +49,7 @@ func (self *SQcloudRegionDriver) GetProvider() string { return api.CLOUD_PROVIDER_QCLOUD } -func (self *SQcloudRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { - ownerId := ctx.Value("ownerId").(mcclient.IIdentityProvider) +func (self *SQcloudRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { zoneV := validators.NewModelIdOrNameValidator("zone", "zone", ownerId) vpcV := validators.NewModelIdOrNameValidator("vpc", "vpc", ownerId) managerIdV := validators.NewModelIdOrNameValidator("manager", "cloudprovider", ownerId) @@ -93,7 +92,7 @@ func (self *SQcloudRegionDriver) ValidateCreateLoadbalancerData(ctx context.Cont data.Set("network_type", jsonutils.NewString(api.LB_NETWORK_TYPE_VPC)) data.Set("cloudregion_id", jsonutils.NewString(region.GetId())) - return self.SManagedVirtualizationRegionDriver.ValidateCreateLoadbalancerData(ctx, userCred, data) + return self.SManagedVirtualizationRegionDriver.ValidateCreateLoadbalancerData(ctx, userCred, ownerId, data) } func (self *SQcloudRegionDriver) ValidateCreateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict, lb *models.SLoadbalancer, backendGroup db.IModel) (*jsonutils.JSONDict, error) { diff --git a/pkg/compute/regiondrivers/ucloud.go b/pkg/compute/regiondrivers/ucloud.go index f4423bba94..3cbfd8be49 100644 --- a/pkg/compute/regiondrivers/ucloud.go +++ b/pkg/compute/regiondrivers/ucloud.go @@ -38,7 +38,7 @@ func (self *SUcloudRegionDriver) GetProvider() string { return api.CLOUD_PROVIDER_UCLOUD } -func (self *SUcloudRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { +func (self *SUcloudRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { return nil, httperrors.NewNotImplementedError("%s does not currently support creating loadbalancer", self.GetProvider()) } diff --git a/pkg/compute/regiondrivers/zstack.go b/pkg/compute/regiondrivers/zstack.go index ed14eec1fe..bfe954d498 100644 --- a/pkg/compute/regiondrivers/zstack.go +++ b/pkg/compute/regiondrivers/zstack.go @@ -39,7 +39,7 @@ func (self *SZStackRegionDriver) GetProvider() string { return api.CLOUD_PROVIDER_ZSTACK } -func (self *SZStackRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { +func (self *SZStackRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { return nil, httperrors.NewNotImplementedError("%s does not currently support creating loadbalancer", self.GetProvider()) } diff --git a/pkg/compute/tasks/network_create_task.go b/pkg/compute/tasks/network_create_task.go index 489b3276ee..e962df1153 100644 --- a/pkg/compute/tasks/network_create_task.go +++ b/pkg/compute/tasks/network_create_task.go @@ -82,7 +82,7 @@ func (self *NetworkCreateTask) OnInit(ctx context.Context, obj db.IStandaloneMod return } - err = network.SyncWithCloudNetwork(ctx, self.UserCred, inet, nil) + err = network.SyncWithCloudNetwork(ctx, self.UserCred, inet, nil, nil) if err != nil { self.taskFailed(ctx, network, "SyncWithCloudNetwork", err) diff --git a/pkg/compute/tasks/network_syncstatus_task.go b/pkg/compute/tasks/network_syncstatus_task.go index 755bce680c..05c9a89ded 100644 --- a/pkg/compute/tasks/network_syncstatus_task.go +++ b/pkg/compute/tasks/network_syncstatus_task.go @@ -59,7 +59,7 @@ func (self *NetworkSyncstatusTask) OnInit(ctx context.Context, obj db.IStandalon return } - err = net.SyncWithCloudNetwork(ctx, self.UserCred, extNet, nil) + err = net.SyncWithCloudNetwork(ctx, self.UserCred, extNet, nil, nil) if err != nil { msg := fmt.Sprintf("fail to sync network status %s", err) self.taskFail(ctx, net, msg) diff --git a/pkg/keystone/cronjobs/project_resources.go b/pkg/keystone/cronjobs/project_resources.go index 30d493543d..b736a88aa9 100644 --- a/pkg/keystone/cronjobs/project_resources.go +++ b/pkg/keystone/cronjobs/project_resources.go @@ -46,7 +46,7 @@ type sServiceEndpoints struct { } func FetchProjectResourceCount(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) { - //log.Debugf("FetchProjectResourceCount") + log.Debugf("FetchProjectResourceCount") eps, err := models.EndpointManager.FetchAll() if err != nil { return @@ -106,7 +106,7 @@ func FetchProjectResourceCount(ctx context.Context, userCred mcclient.TokenCrede if _, ok := serviceBlackList[srvId]; ok { delete(serviceBlackList, srvId) } - projectResCounts := make(map[string][]db.SProjectResourceCount) + projectResCounts := make(map[string][]db.SScopeResourceCount) err = ret.Unmarshal(&projectResCounts) if err != nil { continue @@ -115,22 +115,26 @@ func FetchProjectResourceCount(ctx context.Context, userCred mcclient.TokenCrede } } -func syncProjectResourceCount(regionId string, serviceId string, projResCnt map[string][]db.SProjectResourceCount) { +func syncProjectResourceCount(regionId string, serviceId string, projResCnt map[string][]db.SScopeResourceCount) { projList := make([]string, 0) for res, resCnts := range projResCnt { for i := range resCnts { - if resCnts[i].TenantId == "" { + if len(resCnts[i].TenantId) == 0 && len(resCnts[i].DomainId) == 0 { continue } projRes := models.SProjectResource{} - projRes.ProjectId = resCnts[i].TenantId + if len(resCnts[i].TenantId) > 0 { + projRes.ProjectId = resCnts[i].TenantId + } else { + projRes.ProjectId = resCnts[i].DomainId + } projRes.RegionId = regionId projRes.ServiceId = serviceId projRes.Resource = res projRes.Count = resCnts[i].ResCount - projList = append(projList, resCnts[i].TenantId) + projList = append(projList, projRes.ProjectId) err := models.ProjectResourceManager.TableSpec().InsertOrUpdate(&projRes) if err != nil { diff --git a/pkg/keystone/models/domains.go b/pkg/keystone/models/domains.go index 2e4164582d..09016e48fd 100644 --- a/pkg/keystone/models/domains.go +++ b/pkg/keystone/models/domains.go @@ -17,6 +17,7 @@ package models import ( "context" "database/sql" + "time" "yunion.io/x/jsonutils" "yunion.io/x/log" @@ -27,6 +28,7 @@ import ( api "yunion.io/x/onecloud/pkg/apis/identity" "yunion.io/x/onecloud/pkg/cloudcommon/db" "yunion.io/x/onecloud/pkg/httperrors" + "yunion.io/x/onecloud/pkg/keystone/options" "yunion.io/x/onecloud/pkg/mcclient" "yunion.io/x/onecloud/pkg/util/logclient" "yunion.io/x/onecloud/pkg/util/stringutils2" @@ -272,6 +274,10 @@ func (domain *SDomain) ValidatePurgeCondition(ctx context.Context) error { if policyCnt > 0 { return httperrors.NewNotEmptyError("domain is in use by policy") } + external, _, _ := domain.getExternalResources() + if len(external) > 0 { + return httperrors.NewNotEmptyError("domain contains external resources") + } return nil } @@ -345,6 +351,17 @@ func (manager *SDomainManager) FetchCustomizeColumns( rows[i].RoleCount, _ = domain.GetRoleCount() rows[i].PolicyCount, _ = domain.GetPolicyCount() rows[i].IdpCount, _ = domain.GetIdpCount() + + external, update, _ := domain.getExternalResources() + if len(external) > 0 { + rows[i].ExtResource = jsonutils.Marshal(external) + rows[i].ExtResourcesLastUpdate = update + if update.IsZero() { + update = time.Now() + } + nextUpdate := update.Add(time.Duration(options.Options.FetchProjectResourceCountIntervalSeconds) * time.Second) + rows[i].ExtResourcesNextUpdate = nextUpdate + } } idpRows := expandIdpAttributes(api.IdMappingEntityDomain, idList, fields) @@ -466,3 +483,7 @@ func (domain *SDomain) UnlinkIdp(idpId string) error { } return IdmappingManager.deleteAny(idpId, api.IdMappingEntityDomain, domain.Id) } + +func (domain *SDomain) getExternalResources() (map[string]int, time.Time, error) { + return ProjectResourceManager.getProjectResource(domain.Id) +} diff --git a/pkg/keystone/models/policies.go b/pkg/keystone/models/policies.go index ffaec295b6..c735f52d20 100644 --- a/pkg/keystone/models/policies.go +++ b/pkg/keystone/models/policies.go @@ -18,12 +18,11 @@ import ( "context" "database/sql" - "yunion.io/x/onecloud/pkg/apis" - "yunion.io/x/jsonutils" "yunion.io/x/pkg/errors" "yunion.io/x/sqlchemy" + "yunion.io/x/onecloud/pkg/apis" api "yunion.io/x/onecloud/pkg/apis/identity" "yunion.io/x/onecloud/pkg/cloudcommon/db" policyman "yunion.io/x/onecloud/pkg/cloudcommon/policy" @@ -204,8 +203,18 @@ func (policy *SPolicy) PerformPrivate(ctx context.Context, userCred mcclient.Tok return nil, nil } +func (policy *SPolicy) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + policy.SSharableBaseResource.CustomizeCreate(ctx, userCred, ownerId, query, data) + return policy.SEnabledIdentityBaseResource.CustomizeCreate(ctx, userCred, ownerId, query, data) +} + +func (policy *SPolicy) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { + db.SharedResourceManager.CleanModelShares(ctx, userCred, policy) + return policy.SEnabledIdentityBaseResource.Delete(ctx, userCred) +} + func (policy *SPolicy) ValidateDeleteCondition(ctx context.Context) error { - if policy.IsPublic { + if policy.IsShared() { return httperrors.NewInvalidStatusError("cannot delete shared policy") } if policy.Enabled.IsTrue() { diff --git a/pkg/keystone/models/roles.go b/pkg/keystone/models/roles.go index 07cb9047f9..9c4139e23d 100644 --- a/pkg/keystone/models/roles.go +++ b/pkg/keystone/models/roles.go @@ -19,13 +19,12 @@ import ( "database/sql" "fmt" - "yunion.io/x/onecloud/pkg/apis" - "yunion.io/x/jsonutils" "yunion.io/x/log" "yunion.io/x/pkg/errors" "yunion.io/x/sqlchemy" + "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/cloudcommon/policy" @@ -187,7 +186,7 @@ func (role *SRole) IsSystemRole() bool { } func (role *SRole) ValidateDeleteCondition(ctx context.Context) error { - if role.IsPublic { + if role.IsShared() { return httperrors.NewInvalidStatusError("cannot delete shared role") } if role.IsSystemRole() { @@ -442,6 +441,16 @@ func (role *SRole) PerformPrivate(ctx context.Context, userCred mcclient.TokenCr return nil, nil } +func (role *SRole) CustomizeCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error { + role.SSharableBaseResource.CustomizeCreate(ctx, userCred, ownerId, query, data) + return role.SIdentityBaseResource.CustomizeCreate(ctx, userCred, ownerId, query, data) +} + +func (role *SRole) Delete(ctx context.Context, userCred mcclient.TokenCredential) error { + db.SharedResourceManager.CleanModelShares(ctx, userCred, role) + return role.SIdentityBaseResource.Delete(ctx, userCred) +} + func (manager *SRoleManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) { err := db.ValidateCreateDomainId(ownerId.GetProjectDomainId()) if err != nil { diff --git a/pkg/keystone/service/handlers.go b/pkg/keystone/service/handlers.go index fc5fafac65..3a1a8529e8 100644 --- a/pkg/keystone/service/handlers.go +++ b/pkg/keystone/service/handlers.go @@ -62,6 +62,8 @@ func InitHandlers(app *appsrv.Application) { models.FernetKeyManager, models.ProjectResourceManager, + + db.SharedResourceManager, } { db.RegisterModelManager(manager) } diff --git a/pkg/keystone/service/service.go b/pkg/keystone/service/service.go index 61ec7c89d0..6432a269d2 100644 --- a/pkg/keystone/service/service.go +++ b/pkg/keystone/service/service.go @@ -80,7 +80,7 @@ func StartService() { cron := cronman.InitCronJobManager(true, opts.CronJobWorkerCount) cron.AddJobAtIntervalsWithStartRun("AutoSyncIdentityProviderTask", time.Duration(opts.AutoSyncIntervalSeconds)*time.Second, models.AutoSyncIdentityProviderTask, true) - cron.AddJobAtIntervals("FetchProjectResourceCount", time.Duration(opts.FetchProjectResourceCountIntervalSeconds)*time.Second, cronjobs.FetchProjectResourceCount) + cron.AddJobAtIntervalsWithStartRun("FetchProjectResourceCount", time.Duration(opts.FetchProjectResourceCountIntervalSeconds)*time.Second, cronjobs.FetchProjectResourceCount, false) cron.Start() defer cron.Stop()