Compare commits

...

120 Commits

Author SHA1 Message Date
yunion-ci-robot
a5ec90abdb Merge pull request #7907 from wanyaoqi/automated-cherry-pick-of-#7905-upstream-release-3.3
Automated cherry pick of #7905: webconsole: fix defer order to release zombie process
2020-09-15 10:26:11 +08:00
wanyaoqi
77c3e490c2 webconsole: fix defer order to release zombie process 2020-09-14 18:21:38 +08:00
Zexi Li
12aef33055 Merge pull request #7904 from rainzm/automated-cherry-pick-of-#7902-upstream-release-3.3
Automated cherry pick of #7902: fix(esxi): return when host.Vm is empty
2020-09-14 16:28:11 +08:00
rainzm
c4180811b5 fix(esxi): return when host.Vm is empty 2020-09-14 16:27:04 +08:00
yunion-ci-robot
8d8439db4f Merge pull request #7901 from ioito/automated-cherry-pick-of-#7899-upstream-release-3.3
Automated cherry pick of #7899: fix: cos use proxy
2020-09-14 14:03:15 +08:00
Zexi Li
871df54d3b Merge pull request #7897 from wanyaoqi/automated-cherry-pick-of-#7895-upstream-release-3.3
Automated cherry pick of #7895: disk: check disk is need renew on guest set renew
2020-09-14 13:02:11 +08:00
Qu Xuan
24e3da7818 fix: cos use proxy 2020-09-14 13:01:36 +08:00
wanyaoqi
6f5bb55ea0 disk: check disk is need renew on guest set renew 2020-09-14 12:08:17 +08:00
yunion-ci-robot
1d006efc78 Merge pull request #7892 from swordqiu/automated-cherry-pick-of-#7890-upstream-release-3.3
Automated cherry pick of #7890: fix: disable webkms for esxi older than 6.5
2020-09-12 23:55:16 +08:00
yunion-ci-robot
5a91d66939 Merge pull request #7889 from yousong/automated-cherry-pick-of-#7887-upstream-release-3.3
Automated cherry pick of #7887: elasticips: filter by owner when doing auto allocation
2020-09-12 23:54:10 +08:00
Qiu Jian
c2fbe4faf1 fix: disable webkms for esxi older than 6.5 2020-09-12 17:32:41 +08:00
Yousong Zhou
ef8b9e6aea elasticips: filter by owner when doing auto allocation 2020-09-12 17:15:02 +08:00
yunion-ci-robot
2a3464e8e7 Merge pull request #7878 from ioito/automated-cherry-pick-of-#7876-upstream-release-3.3
Automated cherry pick of #7876: fix: 默认不自动合并安全组
2020-09-11 21:03:55 +08:00
Zexi Li
db596b0db1 Merge pull request #7881 from ioito/automated-cherry-pick-of-#7879-upstream-release-3.3
Automated cherry pick of #7879: fix: avoid sync natgateway eip panic
2020-09-11 21:03:50 +08:00
Zexi Li
c766696df9 Merge pull request #7872 from rainzm/automated-cherry-pick-of-#7870-upstream-release-3.3
Automated cherry pick of #7870: fix(esxiagent): add HostDelayTaskWorkerCount
2020-09-11 20:55:42 +08:00
Zexi Li
bc4540649a Merge pull request #7864 from wanyaoqi/automated-cherry-pick-of-#7836-upstream-release-3.3
Automated cherry pick of #7836: host: fix rbd storage cache iso image
2020-09-11 20:54:12 +08:00
Zexi Li
c3a2349f41 Merge pull request #7861 from ioito/automated-cherry-pick-of-#7859-upstream-release-3.3
Automated cherry pick of #7859: fix: 平滑迁移数据
2020-09-11 20:52:22 +08:00
Qu Xuan
9920e3b50d fix: avoid sync natgateway eip panic 2020-09-11 19:17:52 +08:00
Qu Xuan
e5d7fee933 fix: 默认不自动合并安全组 2020-09-11 17:38:16 +08:00
rainzm
da0246e667 fix(esxiagent): add HostDelayTaskWorkerCount
之前,HostDelayWorker 是通过 hostutils.InitWorkerManager 来初始化,
worker的数量依赖于options.HostOptions.DefaultRequestWorkerCount, 因为
这个options没有经过初始化,所以就是0,导致worker count的数量变为1。

现在增加了 HostDelayTaskWorkerCount 来管理这个count,默认值为8。
2020-09-11 17:22:30 +08:00
wanyaoqi
f017daafc2 host: fix rbd storage cache iso image 2020-09-10 23:17:08 +08:00
yunion-ci-robot
bd4d0e11b2 Merge pull request #7857 from ioito/automated-cherry-pick-of-#7855-upstream-release-3.3
Automated cherry pick of #7855: fix: optimized qcloud keypair
2020-09-10 21:34:33 +08:00
Qu Xuan
0428425011 fix: 平滑迁移数据 2020-09-10 17:40:07 +08:00
Qu Xuan
dfafa03364 fix: 腾讯云不支持同时设置秘钥和密码,若设置秘钥,则将密码置空 2020-09-10 17:26:22 +08:00
Qu Xuan
a1aafa67df fix: optimized qcloud keypair 2020-09-10 17:26:22 +08:00
yunion-ci-robot
1041d6e017 Merge pull request #7833 from rainzm/automated-cherry-pick-of-#7832-upstream-release-3.3
Automated cherry pick of #7832: refactor(region): optimize preparenet of cloudaccount
2020-09-10 16:04:56 +08:00
rainzm
df64b90805 refactor(region): optimize preparenet of cloudaccount
1. 从vcenter中获取host和vm的信息时,只需要获取网络相关的字段就可以了。
2. 每个host的vms,单独启用一个goroutine。
3. 优化了处理vms ip的逻辑,现在的时间复杂度是O(n)。
2020-09-10 15:48:40 +08:00
yunion-ci-robot
c90ee3522f Merge pull request #7850 from ioito/automated-cherry-pick-of-#7834-upstream-release-3.3
Automated cherry pick of #7834: fix: uniform cachedimage active status
2020-09-10 14:36:04 +08:00
Qu Xuan
cb288f65eb fix: uniform cachedimage active status 2020-09-10 10:22:57 +08:00
yunion-ci-robot
e073fab189 Merge pull request #7847 from rainzm/automated-cherry-pick-of-#7845-upstream-release-3.3
Automated cherry pick of #7845: Feat & Fix & Refactor for ESXi
2020-09-10 09:41:58 +08:00
rainzm
13608b43e7 fix(region): add RequestSyncstatusOnHost for SESXiGuestDriver
esxi 平台 Guest 进行 syncstatus 和其他平台有所区别,Vcenter 可能会更改
 VM 所在的 Host,所以在 Host 上寻找 VM 可能会出现 ErrNotFound。此时,应该
主动去整个 datacenter 中寻找 VM,然后更改 Host,进行同步。
2020-09-09 21:57:11 +08:00
rainzm
be4a95ca80 fix(esxi): fetch templatevm from datacenter before clone vm
这里应该和image_cache那里保持一直,对template的获取应该从datacenter
中获取,而不是host。
2020-09-09 21:56:20 +08:00
rainzm
35919e1ece refactor(esxi): replace GetTemplateVMById with FetchTemplateVMById
FetchTemplateVMById 更好,因为它更轻量,更快。
2020-09-09 21:56:20 +08:00
rainzm
af76ae975e feat(esxicli): better vm operator
现在,可以通过Datacenter来获取vm,不一定要指定HostIp,
Datacenter和HostIp必须指定一个。
2020-09-09 21:56:20 +08:00
rainzm
3a8c90d7df feat(esxi): support fetchVM form datacenter 2020-09-09 21:56:20 +08:00
rainzm
86c0af8ca5 refactor(esxi): fetchVms and fetchHardwareInfo
1. fetchHardwareInfo 只有一种error,原因是moVM的某些字段为nil,这种情况下,完全可以打印日志直接返回。
2. fetchVms 现在只返回[]*SVirtualMachine, 进一步的过滤(是不是template)交给调用者。
2020-09-09 21:56:20 +08:00
yunion-ci-robot
44313bb394 Merge pull request #7830 from swordqiu/automated-cherry-pick-of-#7828-upstream-release-3.3
Automated cherry pick of #7828: fix: wire usage stats incorrect
2020-09-08 20:28:56 +08:00
yunion-ci-robot
2be6a06580 Merge pull request #7824 from swordqiu/automated-cherry-pick-of-#7820-upstream-release-3.3
Automated cherry pick of #7820: fix: ignore 409 error when doing redfish power on
2020-09-08 20:24:53 +08:00
yunion-ci-robot
8fe49104cb Merge pull request #7823 from rainzm/automated-cherry-pick-of-#7821-upstream-release-3.3
Automated cherry pick of #7821: fix(esxiagent): return image extid not id
2020-09-08 20:23:55 +08:00
Qiu Jian
45d6686a39 fix: wire usage stats incorrect 2020-09-08 16:43:44 +08:00
rainzm
171c95bf55 fix(esxiagent): return image extid not id
调用 disk/image_cache 接口的Task StorageCacheImageTask 会根据回调
回来数据中的 image_id,来设置 storagecachedimage 中的 externalid,
所以这里的 image_id 应该是 externalid。
2020-09-08 15:33:48 +08:00
Qiu Jian
508c934e8a fix: ignore 409 error when doing redfish power on 2020-09-08 15:22:48 +08:00
yunion-ci-robot
dc5eb6c09e Merge pull request #7806 from yousong/automated-cherry-pick-of-#7804-upstream-release-3.3
Automated cherry pick of #7804: vpcagent: guard against foul eip records
2020-09-08 10:07:51 +08:00
yunion-ci-robot
af0e87bd54 Merge pull request #7800 from wanyaoqi/automated-cherry-pick-of-#7798-upstream-release-3.3
Automated cherry pick of #7798: guest short desc add backup host id
2020-09-07 21:01:51 +08:00
yunion-ci-robot
d77616fb5f Merge pull request #7791 from wanyaoqi/automated-cherry-pick-of-#7789-upstream-release-3.3
Automated cherry pick of #7789: fix get ubuntu version
2020-09-07 20:59:45 +08:00
Zexi Li
def5bad5f5 Merge pull request #7795 from ioito/automated-cherry-pick-of-#7793-upstream-release-3.3
Automated cherry pick of #7793: fix: aliyun wulanchabu region
2020-09-07 20:55:42 +08:00
yunion-ci-robot
15ec57cad6 Merge pull request #7812 from swordqiu/automated-cherry-pick-of-#7811-upstream-release-3.3
Automated cherry pick of #7811: fix: prevent users in disabled idp from login
2020-09-07 20:55:13 +08:00
Qiu Jian
e64af28e89 fix: prevent users in disabled idp from login 2020-09-07 18:25:12 +08:00
Yousong Zhou
96058b4afe vpcagent: guard against foul eip records 2020-09-07 17:27:36 +08:00
wanyaoqi
b120b87c4f guest short desc add backup host id 2020-09-07 17:06:02 +08:00
Qu Xuan
fb9ae22fec fix: aliyun wulanchabu region 2020-09-07 16:11:02 +08:00
wanyaoqi
22e4181b37 fix get ubuntu version 2020-09-07 16:00:56 +08:00
yunion-ci-robot
6fef273e9c Merge pull request #7788 from rainzm/automated-cherry-pick-of-#7786-upstream-release-3.3
Automated cherry pick of #7786: fix(scheduler): fix array out of bounds when sorting hosts
2020-09-07 15:33:41 +08:00
yunion-ci-robot
cf1b81c70e Merge pull request #7784 from rainzm/automated-cherry-pick-of-#7782-upstream-release-3.3
Automated cherry pick of #7782: fix(notify): Replace String() with GetString()
2020-09-07 15:26:42 +08:00
rainzm
6874b94404 fix(scheduler): fix array out of bounds when sorting hosts 2020-09-07 15:21:58 +08:00
rainzm
4da5a00422 fix(notify): Replace String() with GetString()
The String() of jsonutils.JSONObject will add a pair of
double quotes around the content. The GetString() will
get a clean content.
2020-09-07 15:11:25 +08:00
yunion-ci-robot
92c99fe828 Merge pull request #7779 from ioito/automated-cherry-pick-of-#7729-upstream-release-3.3
Automated cherry pick of #7729: optimized cachedimages sync
2020-09-07 11:08:42 +08:00
Qu Xuan
23b02045a1 optimized cachedimages sync 2020-09-07 10:18:15 +08:00
yunion-ci-robot
86dca4ec62 Merge pull request #7771 from swordqiu/automated-cherry-pick-of-#7769-upstream-release-3.3
Automated cherry pick of #7769: fix: network address list respect privilige of user
2020-09-05 15:50:43 +08:00
yunion-ci-robot
9c71b76e79 Merge pull request #7774 from swordqiu/automated-cherry-pick-of-#7772-upstream-release-3.3
Automated cherry pick of #7772: fix: skup syncing lb, rds, redis instances in tasks
2020-09-05 15:47:42 +08:00
Qiu Jian
ec659ddd44 fix: skup syncing lb, rds, redis instances in tasks 2020-09-05 14:30:40 +08:00
Qiu Jian
e2d98a4ce3 fix: network address list respect privilige of user 2020-09-05 12:02:35 +08:00
yunion-ci-robot
47e515cb1f Merge pull request #7765 from tb365/automated-cherry-pick-of-#7764-upstream-release-3.3
Automated cherry pick of #7764: pex register add optional column mac_access
2020-09-04 20:15:41 +08:00
TangBin
6eb7c39d3b pex register add optional column mac_access 2020-09-04 15:57:07 +08:00
Zexi Li
52d06ec9c4 Merge pull request #7749 from rainzm/automated-cherry-pick-of-#7748-upstream-release-3.3
Automated cherry pick of #7748: feat(esxi): correctly judge whether inet is nil
2020-09-04 10:32:27 +08:00
Zexi Li
d8fcdaa023 Merge pull request #7756 from swordqiu/automated-cherry-pick-of-#7740-upstream-release-3.3
Automated cherry pick of #7740: fix: find correct esxi host access ip
2020-09-04 10:32:01 +08:00
Zexi Li
b4e57895f6 Merge pull request #7759 from swordqiu/automated-cherry-pick-of-#7757-upstream-release-3.3
Automated cherry pick of #7757: fix: support VirtualDiskRawDiskMappingVer1BackingInfo
2020-09-04 10:31:23 +08:00
Zexi Li
015bb265d3 Merge pull request #7746 from wanyaoqi/automated-cherry-pick-of-#7744-upstream-release-3.3
Automated cherry pick of #7744: glance: check min disk size on update
2020-09-04 10:29:54 +08:00
Zexi Li
8ee2bc0153 Merge pull request #7743 from swordqiu/automated-cherry-pick-of-#7741-upstream-release-3.3
Automated cherry pick of #7741: fix: search by chs projectname or domainname
2020-09-04 10:29:07 +08:00
Zexi Li
3077c49255 Merge pull request #7737 from rainzm/automated-cherry-pick-of-#7735-upstream-release-3.3
Automated cherry pick of #7735: fix(compute): return InputParameterError while ValidateCreateData
2020-09-04 10:27:51 +08:00
Qiu Jian
79ef55b4f6 fix: support VirtualDiskRawDiskMappingVer1BackingInfo 2020-09-04 00:15:40 +08:00
Qiu Jian
c7c1082e94 fix: find correct esxi host access ip 2020-09-03 23:56:53 +08:00
yunion-ci-robot
78eb02e501 Merge pull request #7732 from swordqiu/automated-cherry-pick-of-#7730-upstream-release-3.3
Automated cherry pick of #7730: fix: compatiblity fixes with lenovo RD620 and huawei 2288 fix: compatiblity fixes with lenovo RD620 and huawei 2288
2020-09-03 21:54:51 +08:00
rainzm
03590d9f9b feat(esxi): correctly judge whether inet is nil 2020-09-03 20:33:35 +08:00
wanyaoqi
a0246b410f glance: check min disk size on update 2020-09-03 20:01:43 +08:00
Qiu Jian
03de172d85 fix: search by chs projectname or domainname 2020-09-03 18:42:34 +08:00
rainzm
94409c25cc fix(compute): return InputParameterError while ValidateCreateData 2020-09-03 15:24:56 +08:00
Qiu Jian
6ea402b576 fix: compatiblity fixes with lenovo RD620 and huawei 2288 2020-09-03 11:53:27 +08:00
yunion-ci-robot
7b7b3a9416 Merge pull request #7727 from tb365/automated-cherry-pick-of-#7725-upstream-release-3.3
Automated cherry pick of #7725: create classic vpc fix
2020-09-03 10:32:41 +08:00
TangBin
142b1bee29 create classic vpc fix 2020-09-02 18:25:49 +08:00
yunion-ci-robot
c0dc06d15d Merge pull request #7720 from wanyaoqi/automated-cherry-pick-of-#7718-upstream-release-3.3
Automated cherry pick of #7718: vmware disk support deploy lvm partition
2020-09-02 16:31:44 +08:00
yunion-ci-robot
1100892f10 Merge pull request #7724 from wanyaoqi/automated-cherry-pick-of-#7722-upstream-release-3.3
Automated cherry pick of #7722: update host status to unknown on host offline
2020-09-02 16:27:38 +08:00
wanyaoqi
8a3d9e7d0d update host status to unknown on host offline 2020-09-02 13:10:00 +08:00
wanyaoqi
e52415a73a vmware disk support deploy lvm partition 2020-09-02 10:32:00 +08:00
屈轩
32195ed702 fix: add details for account delete (#7704)
Co-authored-by: Qu Xuan <quxuan@yunionyun.com>
2020-09-01 20:09:48 +08:00
wanyaoqi
d5251af976 hostinfo: try create network add is_on_premise (#7708) 2020-09-01 20:01:41 +08:00
屈轩
3c7c7c1721 fix: avoid delete aws iam user failed (#7666)
Co-authored-by: Qu Xuan <quxuan@yunionyun.com>
2020-09-01 11:38:35 +08:00
Jian Qiu
f15d7d8f3e fix: vmware esxi host detects vnic portgroup info (#7659)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
2020-09-01 10:51:40 +08:00
Rain Zheng
938c9a6817 Automated cherry pick of #7661: fix(host-deployer): Exit correctly after mounting (#7673)
* fix(esxi): Fetch full templates of datastoreImageCache

Datastore 和 DatastoreImageCache 是一对一的关系。
每一个 Datastore 可能有多个对应的 Host,所以 GetIIMages 里面获取
Templates 的逻辑应该尝试去获取所有 Host 的 Templates。

* fix(host-deployer): Exit correctly after mounting

MountRootfs的返回值为nil时,还是需要Umount的操作来正确退出(比如VDDK)。
VDDK的Mount分为两步,第一步会挂在remote
disk到fuse下,然后挂载fuse/xxx/flat
到块设备上。第一步成功,第二部失败也应该正确退出。

* fix(host-deployer): Kill process

* opt(host-deployer): Increase timeout of waiting mount

* opt(host-deployer): Add debug log print command to mount

* fix(esxi): Support multi agent in different zone
2020-09-01 10:47:39 +08:00
Jian Qiu
589d7d48a0 fix: server purge may fail (#7697)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
2020-09-01 10:21:39 +08:00
屈轩
9424de9cf7 fix: 不限制openstack系统盘类型 (#7676)
Co-authored-by: Qu Xuan <quxuan@yunionyun.com>
2020-09-01 01:22:35 +08:00
wanyaoqi
9272b43991 fix host get guests (#7684) 2020-09-01 01:11:36 +08:00
wanyaoqi
cc051942d7 fix get storage capacity on init' (#7688) 2020-09-01 01:02:36 +08:00
Yousong Zhou
3268e59d20 vpcagent: respect guest src check settings (#7679)
mac   ip    dhcp    ping    xipping    xmacping
  on    on    y       y       n          n
  on    off   y       y       y          n
  off   off   y       y       y          y

external access depends on source routing, changing ip address will
fail that

note dst mac address of reply packet when changing only mac address
with vpc ip remains the same
2020-08-31 16:31:37 +08:00
Jian Qiu
f142206652 fix: cleanup logic for nics of pending_deleted guests (#7670)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
2020-08-31 09:33:36 +08:00
wanyaoqi
d8275fa79a remove backup metadata on delete backup (#7655) 2020-08-28 12:04:05 +08:00
tb365
9ec851df2a eip & vpc manager match fix (#7651)
Co-authored-by: TangBin <tangbin@yunion.cn>
2020-08-28 11:59:40 +08:00
屈轩
c5e616b196 fix: aovid truncated data (#7645)
Co-authored-by: Qu Xuan <quxuan@yunionyun.com>
2020-08-26 21:39:44 +08:00
Jian Qiu
23d01a1e3c fix: turn off some default project policies (#7638)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
2020-08-26 18:42:36 +08:00
屈轩
ac18702727 fix: avoid openstack image-list failed (#7642)
Co-authored-by: Qu Xuan <quxuan@yunionyun.com>
2020-08-26 18:33:33 +08:00
Yousong Zhou
3a966df659 vpcagent: ignore network without wire ids (#7630) 2020-08-26 10:02:33 +08:00
Zexi Li
cf313dd2cc Merge pull request #7624 from wanyaoqi/automated-cherry-pick-of-#7623-upstream-release-3.3
Automated cherry pick of #7623: fix gpfs check mountpoint
2020-08-25 17:41:18 +08:00
wanyaoqi
a04ee820f6 fix gpfs check mountpoint 2020-08-25 15:51:38 +08:00
屈轩
64d0b4f8c8 fix: ignore invalid zone sku for rds sku sync (#7618)
Co-authored-by: Qu Xuan <quxuan@yunionyun.com>
2020-08-25 10:28:30 +08:00
屈轩
9f3b937e6a fix: avoid storage=nil, dis can not delete (#7609)
Co-authored-by: Qu Xuan <quxuan@yunionyun.com>
2020-08-22 12:33:36 +08:00
Jian Qiu
99818a7c0f fix: opslog filter by owner_project_ids and owner_domain_ids (#7601)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
2020-08-21 10:57:24 +08:00
屈轩
6cab61ecb8 fix: member user only can get user & domain resource (#7598)
Co-authored-by: Qu Xuan <quxuan@yunionyun.com>
2020-08-20 20:54:21 +08:00
Jian Qiu
01a8384071 fix: dns record create ignore is_public field (#7590)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
2020-08-18 10:51:56 +08:00
Zexi Li
b5875e00d1 Merge pull request #7582 from swordqiu/automated-cherry-pick-of-#7580-upstream-release-3.3
Automated cherry pick of #7580: fix: allow delete shared role and policy
2020-08-16 23:43:31 +08:00
Yousong Zhou
d91f5fa87e Automated cherry pick of #7585: apis: vpcs_ovn: alloc for interconnects (#7586)
* apis: vpcs_ovn: alloc for interconnects

* vpcagent: names: add vpc ext names

* vpcagent: use var hasXxxgw

* vpcagent: add switch and router for ext access

Link: https://github.com/yunionio/onecloud/issues/7583
2020-08-16 23:41:53 +08:00
Zexi Li
a346fd47fe Merge pull request #7576 from rainzm/automated-cherry-pick-of-#7575-upstream-release-3.3
Automated cherry pick of #7575: fix: GetIImages correctly without 'image_cache' dir
2020-08-16 23:41:50 +08:00
Qiu Jian
cedd4ccdfa fix: allow delete shared role and policy 2020-08-15 21:05:16 +08:00
rainzm
f5d1adcbd0 fix: GetIImages correctly without 'image_cache' dir
After creating vms, there is no dir named 'image_cache' exists in
storage of esxi. So handle this case to not affecte the synchronization of the
VMware Template.
2020-08-14 20:36:26 +08:00
屈轩
66a5410e7d fix: aovid duplicate sku name (#7573)
Co-authored-by: Qu Xuan <quxuan@yunionyun.com>
2020-08-14 20:35:49 +08:00
Zexi Li
3637b671ed Merge pull request #7570 from zexi/hotfix/jsontag-syntax-v33
fix: json TAG_PREFIX invalid syntax
2020-08-14 17:41:42 +08:00
Jian Qiu
7a58d9f197 fix: init wire domain_id for local vpc (#7567)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
2020-08-14 17:29:49 +08:00
Zexi Li
5c8a7769e3 fix: json TAG_PREFIX invalid syntax 2020-08-14 16:54:44 +08:00
屈轩
ebe1eb603b fix: avoid virtual resource project id is empty when cloudaccount with no project (#7561)
Co-authored-by: Qu Xuan <quxuan@yunionyun.com>
2020-08-14 10:37:49 +08:00
Rain Zheng
eb67c681d3 fix: Merge the host network correctly when preparenet (#7558) 2020-08-14 10:36:51 +08:00
Jian Qiu
e099f006fa fix: network port count stat recode (#7555)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
2020-08-14 10:33:48 +08:00
190 changed files with 2994 additions and 1015 deletions

View File

@@ -19,6 +19,7 @@ import (
"yunion.io/x/jsonutils"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
"yunion.io/x/onecloud/pkg/mcclient/modules"
@@ -360,15 +361,18 @@ func init() {
type NetworkAddressOptions struct {
NETWORK string `help:"id or name of network to query"`
api.GetNetworkAddressesInput
}
R(&NetworkAddressOptions{}, "network-addresses", "Query used addresses of network", func(s *mcclient.ClientSession, args *NetworkAddressOptions) error {
result, err := modules.Networks.GetSpecific(s, args.NETWORK, "addresses", nil)
result, err := modules.Networks.GetSpecific(s, args.NETWORK, "addresses", jsonutils.Marshal(args.GetNetworkAddressesInput))
if err != nil {
return err
}
addrList, err := result.GetArray("addresses")
if err != nil {
return err
addrList, _ := result.GetArray("addresses")
if addrList == nil {
fmt.Println("no result")
return nil
}
listResult := modulebase.ListResult{Data: addrList}
printList(&listResult, nil)

View File

@@ -35,7 +35,10 @@ type BaseEventListOptions struct {
Action []string `help:"Log action"`
User string `help:"filter by operator user"`
Project string `help:"filter by owner project"`
Project string `help:"filter by operator user's project"`
OwnerProjectIds []string `help:"filter by owner project ids"`
OwnerDomainIds []string `help:"filter by owner domain ids"`
PagingMarker string `help:"marker for pagination"`
}
@@ -107,6 +110,12 @@ func doEventList(man modulebase.ResourceManager, s *mcclient.ClientSession, args
if len(args.Scope) > 0 {
params.Add(jsonutils.NewString(args.Scope), "scope")
}
if len(args.OwnerProjectIds) > 0 {
params.Add(jsonutils.NewStringArray(args.OwnerProjectIds), "owner_project_ids")
}
if len(args.OwnerDomainIds) > 0 {
params.Add(jsonutils.NewStringArray(args.OwnerDomainIds), "owner_domain_ids")
}
if len(args.PagingMarker) > 0 {
params.Add(jsonutils.NewString(args.PagingMarker), "paging_marker")
}

167
cmd/raidcli/main.go Normal file
View File

@@ -0,0 +1,167 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"fmt"
"os"
"yunion.io/x/structarg"
_ "yunion.io/x/onecloud/cmd/raidcli/shell"
"yunion.io/x/onecloud/pkg/baremetal/utils/raid"
"yunion.io/x/onecloud/pkg/baremetal/utils/raid/drivers"
"yunion.io/x/onecloud/pkg/util/shellutils"
"yunion.io/x/onecloud/pkg/util/ssh"
)
type BaseOptions struct {
Debug bool `help:"debug mode"`
Help bool `help:"Show help"`
Host string `help:"SSH Host IP" default:"$RAID_HOST" metavar:"RAID_HOST"`
Username string `help:"Username, usually root" default:"$RAID_USERNAME" metavar:"RAID_USERNAME"`
Password string `help:"Password" default:"$RAID_PASSWORD" metavar:"RAID_PASSWORD"`
Driver string `help:"Password" default:"$RAID_DRIVER" metavar:"RAID_DRIVER" choices:"MegaRaid|HPSARaid|Mpt2SAS|MarvelRaid"`
SUBCOMMAND string `help:"s3cli subcommand" subcommand:"true"`
}
var (
options = &BaseOptions{}
)
func getSubcommandParser() (*structarg.ArgumentParser, error) {
parse, e := structarg.NewArgumentParser(options,
"raidcli",
"Command-line interface to test RAID drivers.",
`See "raidcli help COMMAND" for help on a specific command.`)
if e != nil {
return nil, e
}
subcmd := parse.GetSubcommand()
if subcmd == nil {
return nil, fmt.Errorf("No subcommand argument.")
}
type HelpOptions struct {
SUBCOMMAND string `help:"sub-command name"`
}
shellutils.R(&HelpOptions{}, "help", "Show help of a subcommand", func(args *HelpOptions) error {
helpstr, e := subcmd.SubHelpString(args.SUBCOMMAND)
if e != nil {
return e
} else {
fmt.Print(helpstr)
return nil
}
})
for _, v := range shellutils.CommandTable {
_, e := subcmd.AddSubParser(v.Options, v.Command, v.Desc, v.Callback)
if e != nil {
return nil, e
}
}
return parse, nil
}
func showErrorAndExit(e error) {
fmt.Fprintf(os.Stderr, "%s", e)
fmt.Fprintln(os.Stderr)
os.Exit(1)
}
func newClient() (raid.IRaidDriver, error) {
if len(options.Host) == 0 {
return nil, fmt.Errorf("Missing host")
}
if len(options.Username) == 0 {
return nil, fmt.Errorf("Missing username")
}
if len(options.Password) == 0 {
return nil, fmt.Errorf("Missing password")
}
if len(options.Driver) == 0 {
return nil, fmt.Errorf("Missing driver")
}
if options.Debug {
raid.Debug = true
}
sshClient, err := ssh.NewClient(
options.Host,
22,
options.Username,
options.Password,
"",
)
if err != nil {
return nil, fmt.Errorf("ssh client init fail: %s", err)
}
drv := drivers.GetDriver(options.Driver, sshClient)
if drv == nil {
return nil, fmt.Errorf("not supported driver %s", options.Driver)
}
err = drv.ParsePhyDevs()
if err != nil {
return nil, fmt.Errorf("parse phyical devices error %s", err)
}
return drv, nil
}
func main() {
parser, e := getSubcommandParser()
if e != nil {
showErrorAndExit(e)
}
e = parser.ParseArgs(os.Args[1:], false)
// options := parser.Options().(*BaseOptions)
if options.Help {
fmt.Print(parser.HelpString())
} else {
subcmd := parser.GetSubcommand()
subparser := subcmd.GetSubParser()
if e != nil {
if subparser != nil {
fmt.Print(subparser.Usage())
} else {
fmt.Print(parser.Usage())
}
showErrorAndExit(e)
} else {
suboptions := subparser.Options()
if options.SUBCOMMAND == "help" {
e = subcmd.Invoke(suboptions)
} else {
var client raid.IRaidDriver
client, e = newClient()
if e != nil {
showErrorAndExit(e)
}
e = subcmd.Invoke(client, suboptions)
}
if e != nil {
showErrorAndExit(e)
}
}
}
}

37
cmd/raidcli/shell/raid.go Normal file
View File

@@ -0,0 +1,37 @@
// 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 shell
import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/baremetal/utils/raid"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type ShowOptions struct {
}
shellutils.R(&ShowOptions{}, "show", "show raid info", func(drv raid.IRaidDriver, args *ShowOptions) error {
adpts := drv.GetAdapters()
for i := range adpts {
fmt.Println("Index:", i)
fmt.Println(jsonutils.Marshal(adpts[i].GetDevices()).PrettyString())
}
return nil
})
}

View File

@@ -17,12 +17,16 @@ package main
import (
"context"
"fmt"
"net/url"
"os"
"strings"
"yunion.io/x/structarg"
_ "yunion.io/x/onecloud/cmd/redfishcli/shell"
"yunion.io/x/onecloud/pkg/util/fileutils2"
"yunion.io/x/onecloud/pkg/util/redfish"
"yunion.io/x/onecloud/pkg/util/redfish/bmconsole"
_ "yunion.io/x/onecloud/pkg/util/redfish/loader"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
@@ -36,8 +40,12 @@ type BaseOptions struct {
SUBCOMMAND string `help:"s3cli subcommand" subcommand:"true"`
}
var (
options = &BaseOptions{}
)
func getSubcommandParser() (*structarg.ArgumentParser, error) {
parse, e := structarg.NewArgumentParser(&BaseOptions{},
parse, e := structarg.NewArgumentParser(options,
"redfishcli",
"Command-line interface to redfish API.",
`See "redfishcli help COMMAND" for help on a specific command.`)
@@ -62,6 +70,7 @@ func getSubcommandParser() (*structarg.ArgumentParser, error) {
return nil
}
})
bmcJnlp()
for _, v := range shellutils.CommandTable {
_, e := subcmd.AddSubParser(v.Options, v.Command, v.Desc, v.Callback)
if e != nil {
@@ -71,13 +80,49 @@ func getSubcommandParser() (*structarg.ArgumentParser, error) {
return parse, nil
}
func bmcJnlp() {
type BmcGetOptions struct {
BRAND string `help:"brand of baremetal" choices:"Lenovo|Huawei|HPE|Dell|Supermicro"`
Save string `help:"save to file"`
Debug bool `help:"turn on debug mode"`
}
shellutils.R(&BmcGetOptions{}, "bmc-jnlp", "Get Java Console JNLP file", func(args *BmcGetOptions) error {
ctx := context.Background()
parts, err := url.Parse(options.Endpoint)
if err != nil {
return err
}
bmc := bmconsole.NewBMCConsole(parts.Hostname(), options.Username, options.Password, args.Debug)
var jnlp string
switch strings.ToLower(args.BRAND) {
case "hp", "hpe":
jnlp, err = bmc.GetIloConsoleJNLP(ctx)
case "dell", "dell inc.":
jnlp, err = bmc.GetIdracConsoleJNLP(ctx, "", "")
case "supermicro":
jnlp, err = bmc.GetSupermicroConsoleJNLP(ctx)
case "lenovo":
jnlp, err = bmc.GetLenovoConsoleJNLP(ctx)
}
if err != nil {
return err
}
if len(args.Save) > 0 {
return fileutils2.FilePutContents(args.Save, jnlp, false)
} else {
fmt.Println(jnlp)
return nil
}
})
}
func showErrorAndExit(e error) {
fmt.Fprintf(os.Stderr, "%s", e)
fmt.Fprintln(os.Stderr)
os.Exit(1)
}
func newClient(options *BaseOptions) (redfish.IRedfishDriver, error) {
func newClient() (redfish.IRedfishDriver, error) {
if len(options.Endpoint) == 0 {
return nil, fmt.Errorf("Missing endpoint")
}
@@ -104,7 +149,7 @@ func main() {
showErrorAndExit(e)
}
e = parser.ParseArgs(os.Args[1:], false)
options := parser.Options().(*BaseOptions)
// options := parser.Options().(*BaseOptions)
if options.Help {
fmt.Print(parser.HelpString())
@@ -122,9 +167,11 @@ func main() {
suboptions := subparser.Options()
if options.SUBCOMMAND == "help" {
e = subcmd.Invoke(suboptions)
} else if options.SUBCOMMAND == "bmc-jnlp" {
e = subcmd.Invoke(suboptions)
} else {
var client redfish.IRedfishDriver
client, e = newClient(options)
client, e = newClient()
if e != nil {
showErrorAndExit(e)
}

8
go.mod
View File

@@ -131,13 +131,13 @@ require (
k8s.io/cluster-bootstrap v0.17.3
k8s.io/kubernetes v1.16.0
yunion.io/x/executor v0.0.0-20200227030256-a18417815e74
yunion.io/x/jsonutils v0.0.0-20200710080709-7ca71cdb9383
yunion.io/x/jsonutils v0.0.0-20200814075449-927b118adbd8
yunion.io/x/log v0.0.0-20200313080802-57a4ce5966b3
yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7
yunion.io/x/pkg v0.0.0-20200713121502-18154120c49b
yunion.io/x/pkg v0.0.0-20200814072949-4f1b541857d6
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e
yunion.io/x/sqlchemy v0.0.0-20200702064124-195445bc4b11
yunion.io/x/structarg v0.0.0-20200708124353-ea9a441ecaf8
yunion.io/x/sqlchemy v0.0.0-20200814052348-164f1f20f8a6
yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce
)
replace (

18
go.sum
View File

@@ -1126,8 +1126,8 @@ vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj
yunion.io/x/executor v0.0.0-20200227030256-a18417815e74 h1:A15C6VdVRWvmQ9pAJHrUs9yan5qKlYH7uaRxHg1kRbk=
yunion.io/x/executor v0.0.0-20200227030256-a18417815e74/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
yunion.io/x/jsonutils v0.0.0-20200710080709-7ca71cdb9383 h1:XEhTD+FGjBjEIWwcY0Ez1lY3oTTzjUOcRgH/i4eFM5A=
yunion.io/x/jsonutils v0.0.0-20200710080709-7ca71cdb9383/go.mod h1:3U5hspYn9apQHaXKY+fJ4Qgwjey32Kc+Mq+mUe9NamQ=
yunion.io/x/jsonutils v0.0.0-20200814075449-927b118adbd8 h1:KQVw5EmohJCqBDMdZ3fAcOQNNMIYgVuNCNWNwg4EM3A=
yunion.io/x/jsonutils v0.0.0-20200814075449-927b118adbd8/go.mod h1:p0nyMqGA/apTxxyLIU/o1k4V7Vujl2O6ey30L594sYE=
yunion.io/x/log v0.0.0-20190514041436-04ce53b17c6b/go.mod h1:+gauLs73omeJAPlsXcevLsJLKixV+sR/E7WSYTSx1fE=
yunion.io/x/log v0.0.0-20190629062853-9f6483a7103d/go.mod h1:LC6f/4FozL0iaAbnFt2eDX9jlsyo3WiOUPm03d7+U4U=
yunion.io/x/log v0.0.0-20200313080802-57a4ce5966b3 h1:5Wc5hkB8PtMudmHuzCyok960RuOa9I55imIGrigSdjs=
@@ -1136,13 +1136,11 @@ yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7 h1:gjqNa2uQzIEXyySsbvVz0Ult
yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7/go.mod h1:0vLkNEhlmA64HViPBAnSTUMrx5QP1CLsxXmxDKQ80tc=
yunion.io/x/pkg v0.0.0-20190620104149-945c25821dbf/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
yunion.io/x/pkg v0.0.0-20190628082551-f4033ba2ea30/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
yunion.io/x/pkg v0.0.0-20200708071451-a663dc94e16b h1:wwPzH8iMRYjtaSM2pBN7nOqeZxR4XW5wdz2VE1KH/Ug=
yunion.io/x/pkg v0.0.0-20200708071451-a663dc94e16b/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
yunion.io/x/pkg v0.0.0-20200713121502-18154120c49b h1:Ov/eKwwNeQje7SggkopExzcCW/GfaUouvXkcY6RUEcM=
yunion.io/x/pkg v0.0.0-20200713121502-18154120c49b/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
yunion.io/x/pkg v0.0.0-20200814072949-4f1b541857d6 h1:UarEDTBGkgcgc+nc+PZ75uo9M9+jiOGd5P2B90TxDNw=
yunion.io/x/pkg v0.0.0-20200814072949-4f1b541857d6/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e h1:v+EzIadodSwkdZ/7bremd7J8J50Cise/HCylsOJngmo=
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo=
yunion.io/x/sqlchemy v0.0.0-20200702064124-195445bc4b11 h1:srrssomGJLh4OaDaY/1so+2FUBjZxdwQx/1pZ6403YU=
yunion.io/x/sqlchemy v0.0.0-20200702064124-195445bc4b11/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI=
yunion.io/x/structarg v0.0.0-20200708124353-ea9a441ecaf8 h1:35Q2ce/gI2cuVhsuLS7WsL2K9SxwMEtWTopt/99iYsk=
yunion.io/x/structarg v0.0.0-20200708124353-ea9a441ecaf8/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng=
yunion.io/x/sqlchemy v0.0.0-20200814052348-164f1f20f8a6 h1:k7E8Zjwzyk/lo1dDO0jtLbODwYRNv+w/zsUJrKWCXvo=
yunion.io/x/sqlchemy v0.0.0-20200814052348-164f1f20f8a6/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI=
yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce h1:kU8xE7O5uZ1GSJVMZHoJ+jrNL7csUQHYGyAPW9QfNpE=
yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng=

View File

@@ -53,6 +53,7 @@ const (
HOST_IPMI_USERNAME_OPTIONAL = "IPMI用户名"
HOST_IPMI_PASSWORD_OPTIONAL = "IPMI密码"
HOST_MNG_IP_ADDR_OPTIONAL = "管理口IP地址"
HOST_MNG_MAC_ADDR_OPTIONAL = "管理口MAC地址"
)
const (
@@ -63,7 +64,7 @@ const (
var (
BatchHostRegisterTemplate = []string{HOST_MAC, HOST_NAME, HOST_IPMI_ADDR_OPTIONAL, HOST_IPMI_USERNAME_OPTIONAL, HOST_IPMI_PASSWORD_OPTIONAL}
BatchHostISORegisterTemplate = []string{HOST_NAME, HOST_IPMI_ADDR, HOST_IPMI_USERNAME, HOST_IPMI_PASSWORD, HOST_MNG_IP_ADDR}
BatchHostPXERegisterTemplate = []string{HOST_NAME, HOST_IPMI_ADDR, HOST_IPMI_USERNAME, HOST_IPMI_PASSWORD, HOST_MNG_IP_ADDR_OPTIONAL}
BatchHostPXERegisterTemplate = []string{HOST_NAME, HOST_IPMI_ADDR, HOST_IPMI_USERNAME, HOST_IPMI_PASSWORD, HOST_MNG_MAC_ADDR_OPTIONAL, HOST_MNG_IP_ADDR_OPTIONAL}
)
func FetchSession(ctx context.Context, r *http.Request, apiVersion string) *mcclient.ClientSession {
@@ -207,7 +208,7 @@ func (mh *MiscHandler) DoBatchHostRegister(ctx context.Context, w http.ResponseW
i2 := -1
for i, title := range rows[0] {
switch title {
case HOST_MAC:
case HOST_MAC, HOST_MNG_MAC_ADDR_OPTIONAL:
paramKeys = append(paramKeys, "access_mac")
case HOST_NAME:
paramKeys = append(paramKeys, "name")

View File

@@ -57,7 +57,7 @@ type ProxySettingResourceInput struct {
// swagger:ignore
// Deprecated
ProxySettingId string `json:"proxy_setting_id" "yunion:deprecated-by":"proxy_setting"`
ProxySettingId string `json:"proxy_setting_id" yunion-deprecated-by:"proxy_setting"`
}
type ProxySettingTestInput struct {

View File

@@ -22,7 +22,7 @@ type CloudaccountResourceListInput struct {
Provider []string `json:"provider"`
// swagger:ignore
CloudaccountId string `json:"cloudaccount_id" "yunion:deprecated-by":"cloudaccount"`
CloudaccountId string `json:"cloudaccount_id" yunion-deprecated-by:"cloudaccount"`
}
type CloudproviderResourceListInput struct {
@@ -30,7 +30,7 @@ type CloudproviderResourceListInput struct {
Cloudprovider string `json:"cloudprovider"`
// swagger:ignore
CloudproviderId string `json:"cloudprovider_id" "yunion:deprecated-by":"cloudprovider"`
CloudproviderId string `json:"cloudprovider_id" yunion-deprecated-by:"cloudprovider"`
}
type CloudaccountResourceDetails struct {

View File

@@ -37,7 +37,7 @@ type CloudgroupJointsListInput struct {
// 根据公有云用户组过滤资源
Cloudgroup string `json:"cloudgroup"`
// swagger:ignore
CloudgroupId string `json:"cloudgroup_id" "yunion:deprecated-by":"cloudgroup"`
CloudgroupId string `json:"cloudgroup_id" yunion-deprecated-by:"cloudgroup"`
}
type CloudgroupJointBaseUpdateInput struct {

View File

@@ -56,7 +56,7 @@ type CloudpolicyResourceListInput struct {
Cloudpolicy string `json:"cloudpolicy"`
// swagger:ignore
CloudpolicyId string `json:"cloudpolicy_id" "yunion:deprecated-by":"cloudpolicy"`
CloudpolicyId string `json:"cloudpolicy_id" yunion-deprecated-by:"cloudpolicy"`
}
type CloudpolicyResourceDetails struct {

View File

@@ -162,7 +162,7 @@ type ClouduserResourceListInput struct {
Clouduser string `json:"clouduser"`
// swagger:ignore
ClouduserId string `json:"clouduser_id" "yunion:deprecated-by":"clouduser"`
ClouduserId string `json:"clouduser_id" yunion-deprecated-by:"clouduser"`
}
type ClouduserResourceDetails struct {

View File

@@ -285,7 +285,7 @@ type ServerConfigs struct {
// swagger:ignore
// Deprecated
// alias for InstanceType
Sku string `json:"sku" "yunion:deprecated-by":"instance_type"`
Sku string `json:"sku" yunion-deprecated-by:"instance_type"`
// 虚拟机高可用(创建备机)
// default: false
@@ -359,7 +359,7 @@ type ServerCreateInput struct {
// swagger:ignore
// Deprecated
KeypairId string `json:"keypair_id" "yunion:deprecated-by":"keypair"`
KeypairId string `json:"keypair_id" yunion-deprecated-by:"keypair"`
// 秘钥对Id
// required: false

View File

@@ -27,7 +27,7 @@ type CachedImageUncacheImageInput struct {
}
type CachedimageDetails struct {
apis.StandaloneResourceDetails
apis.SharableVirtualResourceDetails
SCachedimage

View File

@@ -18,7 +18,7 @@ const (
CACHED_IMAGE_STATUS_INIT = "init"
CACHED_IMAGE_STATUS_SAVING = "saving"
CACHED_IMAGE_STATUS_CACHING = "caching"
CACHED_IMAGE_STATUS_READY = "ready"
CACHED_IMAGE_STATUS_ACTIVE = "active"
CACHED_IMAGE_STATUS_DELETING = "deleting"
CACHED_IMAGE_STATUS_CACHE_FAILED = "cache_fail"

View File

@@ -66,7 +66,7 @@ type CloudenvResourceListInput struct {
Providers []string `json:"providers"`
// swagger:ignore
// Deprecated
Provider []string `json:"provider" "yunion:deprecated-by":"providers"`
Provider []string `json:"provider" yunion-deprecated-by:"providers"`
// 列出指定云平台品牌的资源一般来说brand和provider相同除了以上支持的provider之外还支持以下band
//
@@ -77,7 +77,7 @@ type CloudenvResourceListInput struct {
Brands []string `json:"brands"`
// swagger:ignore
// Deprecated
Brand []string `json:"brand" "yunion:deprecated-by":"brands"`
Brand []string `json:"brand" yunion-deprecated-by:"brands"`
// 列出指定云环境的资源,支持云环境如下:
//
@@ -227,7 +227,7 @@ type CloudaccountListInput struct {
// 代理
ProxySetting string `json:"proxy_setting"`
// swagger:ignore
ProxySettingId string `json:"proxy_setting_id" "yunion:deprecated-by":"proxy_setting"`
ProxySettingId string `json:"proxy_setting_id" yunion-deprecated-by:"proxy_setting"`
}
type ProviderProject struct {

View File

@@ -147,15 +147,15 @@ type CloudproviderResourceInput struct {
// swagger:ignore
// Deprecated
// description: this param will be deprecate at 3.0
Manager string `json:"manager" "yunion:deprecated-by":"cloudprovider"`
Manager string `json:"manager" yunion-deprecated-by:"cloudprovider"`
// swagger:ignore
// Deprecated
// description: this param will be deprecate at 3.0
ManagerId string `json:"manager_id" "yunion:deprecated-by":"cloudprovider"`
ManagerId string `json:"manager_id" yunion-deprecated-by:"cloudprovider"`
// swagger:ignore
// Deprecated
// description: this param will be deprecate at 3.0
CloudproviderId string `json:"cloudprovider_id" "yunion:deprecated-by":"cloudprovider"`
CloudproviderId string `json:"cloudprovider_id" yunion-deprecated-by:"cloudprovider"`
}
type ManagedResourceListInput struct {
@@ -169,15 +169,15 @@ type ManagedResourceListInput struct {
// swagger:ignore
// Deprecated
// description: this param will be deprecate at 3.0
CloudaccountId string `json:"cloudaccount_id" "yunion:deprecated-by":"cloudaccount"`
CloudaccountId string `json:"cloudaccount_id" yunion-deprecated-by:"cloudaccount"`
// swagger:ignore
// Deprecated
// description: this param will be deprecate at 3.0
Account string `json:"account" "yunion:deprecated-by":"cloudaccount"`
Account string `json:"account" yunion-deprecated-by:"cloudaccount"`
// swagger:ignore
// Deprecated
// description: this param will be deprecate at 3.0
AccountId string `json:"account_id" "yunion:deprecated-by":"cloudaccount"`
AccountId string `json:"account_id" yunion-deprecated-by:"cloudaccount"`
// 过滤资源是否为非OneCloud内置私有云管理的资源
// default: false

View File

@@ -57,6 +57,7 @@ const (
CITY_FO_SHAN = "Foshan" //佛山
CITY_QUAN_ZHOU = "Quanzhou" //泉州
CITY_NEI_MENG_GU = "Neimenggu" //内蒙古
CITY_WU_LAN_CHA_BU = "Wulanchabu" //乌兰察布
// 日本
CITY_TOKYO = "Tokyo" //东京

View File

@@ -180,7 +180,7 @@ type SDBInstanceRecoveryConfigInput struct {
apis.Meta
// swagger:ignore
DBInstancebackup string `json:"dbinstancebackup" "yunion:deprecated-by":"dbinstancebackup_id"`
DBInstancebackup string `json:"dbinstancebackup" yunion-deprecated-by:"dbinstancebackup_id"`
// 备份Id
//
@@ -335,7 +335,7 @@ type DBInstanceResourceInput struct {
// swagger:ignore
// Deprecated
DBInstanceId string `json:"dbinstance_id" "yunion:deprecated-by":"dbinstance"`
DBInstanceId string `json:"dbinstance_id" yunion-deprecated-by:"dbinstance"`
}
type DBInstanceFilterListInputBase struct {

View File

@@ -88,7 +88,7 @@ type SnapshotPolicyResourceInput struct {
// swagger:ignore
// Deprecated
// filter disk by snapshotpolicy_id
SnapshotpolicyId string `json:"snapshotpolicy_id" "yunion:deprecated-by":"snapshotpolicy"`
SnapshotpolicyId string `json:"snapshotpolicy_id" yunion-deprecated-by:"snapshotpolicy"`
}
type SnapshotPolicyFilterListInput struct {
@@ -113,7 +113,7 @@ type DiskListInput struct {
// swagger:ignore
// Deprecated
// filter by disk type
Type string `json:"type" "yunion:deprecated-by":"disk_type"`
Type string `json:"type" yunion-deprecated-by:"disk_type"`
// 过滤指定disk_type的磁盘列表可能的值为sys, data, swap. volume
//
// | disk_type值 | 说明 |
@@ -137,13 +137,13 @@ type DiskListInput struct {
Template string `json:"template"`
// swagger:ignore
// Deprecated
TemplateId string `json:"template_id" "yunion:deprecated-by":"template"`
TemplateId string `json:"template_id" yunion-deprecated-by:"template"`
// 快照
Snapshot string `json:"snapshot"`
// swagger:ignore
// Deprecated
SnapshotId string `json:"snapshot_id" "yunion:deprecated-by":"snapshot"`
SnapshotId string `json:"snapshot_id" yunion-deprecated-by:"snapshot"`
}
type DiskResourceInput struct {
@@ -152,7 +152,7 @@ type DiskResourceInput struct {
// swagger:ignore
// Deprecated
// filter by disk_id
DiskId string `json:"disk_id" "yunion:deprecated-by":"disk"`
DiskId string `json:"disk_id" yunion-deprecated-by:"disk"`
}
type DiskFilterListInputBase struct {

View File

@@ -14,5 +14,11 @@
package compute
import "yunion.io/x/onecloud/pkg/apis"
type DnsRecordCreateInput struct {
apis.AdminSharableVirtualResourceBaseCreateInput
}
type DnsRecordUpdateInput struct {
}

View File

@@ -53,7 +53,7 @@ type ELasticcacheResourceInput struct {
// swagger:ignore
// Deprecated
ElasticcacheId string `json:"elasticcache_id" "yunion:deprecated-by":"elasticcache"`
ElasticcacheId string `json:"elasticcache_id" yunion-deprecated-by:"elasticcache"`
}
type ElasticcacheFilterListInput struct {

View File

@@ -24,15 +24,15 @@ type CloudregionResourceInput struct {
// swagger:ignore
// Deprecated
// description: this param will be deprecate at 3.0
CloudregionId string `json:"cloudregion_id" "yunion:deprecated-by":"cloudregion"`
CloudregionId string `json:"cloudregion_id" yunion-deprecated-by:"cloudregion"`
// swagger:ignore
// Deprecated
// description: this param will be deprecate at 3.0
Region string `json:"region" "yunion:deprecated-by":"cloudregion"`
Region string `json:"region" yunion-deprecated-by:"cloudregion"`
// swagger:ignore
// Deprecated
// description: this param will be deprecate at 3.0
RegionId string `json:"region_id" "yunion:deprecated-by":"cloudregion"`
RegionId string `json:"region_id" yunion-deprecated-by:"cloudregion"`
}
type RegionalFilterListInput struct {
@@ -134,5 +134,5 @@ type ZoneResourceInput struct {
// swagger:ignore
// Deprecated
ZoneId string `json:"zone_id" "yunion:deprecated-by":"zone"`
ZoneId string `json:"zone_id" yunion-deprecated-by:"zone"`
}

View File

@@ -42,7 +42,7 @@ type GlobalVpcResourceInput struct {
// swagger:ignore
// Deprecated
GlobalvpcId string `json:"globalvpc_id" "yunion:deprecated-by":"globalvpc"`
GlobalvpcId string `json:"globalvpc_id" yunion-deprecated-by:"globalvpc"`
}
type GlobalVpcResourceListInput struct {

View File

@@ -28,13 +28,13 @@ type ServerListInput struct {
HostFilterListInput
NetworkFilterListInput `"yunion:ambiguous-prefix":"vpc_"`
NetworkFilterListInput `yunion-ambiguous-prefix:"vpc_"`
billing.BillingResourceListInput
GroupFilterListInput
SecgroupFilterListInput
//DiskFilterListInput `"yunion:ambiguous-prefix":"storage_"`
//DiskFilterListInput `yunion-ambiguous-prefix:"storage_"`
ScalingGroupFilterListInput
// 只列出裸金属主机
@@ -64,7 +64,7 @@ type ServerListInput struct {
// 列出可以挂载磁盘的主机
AttachableServersForDisk string `json:"attachable_servers_for_disk"`
// Deprecated:列出可以挂载磁盘的主机
Disk string `json:"disk" "yunion:deprecated-by":"attachable_servers_for_disk"`
Disk string `json:"disk" yunion-deprecated-by:"attachable_servers_for_disk"`
// 按主机资源类型进行排序
// enum: shared,prepaid,dedicated
@@ -285,15 +285,15 @@ type ServerResourceInput struct {
// swagger:ignore
// Deprecated
// Filter by guest Id
ServerId string `json:"server_id" "yunion:deprecated-by":"server"`
ServerId string `json:"server_id" yunion-deprecated-by:"server"`
// swagger:ignore
// Deprecated
// Filter by guest Id
Guest string `json:"guest" "yunion:deprecated-by":"server"`
Guest string `json:"guest" yunion-deprecated-by:"server"`
// swagger:ignore
// Deprecated
// Filter by guest Id
GuestId string `json:"guest_id" "yunion:deprecated-by":"server"`
GuestId string `json:"guest_id" yunion-deprecated-by:"server"`
}
type ServerFilterListInput struct {

View File

@@ -232,7 +232,7 @@ type HostResourceInput struct {
// swagger:ignore
// Deprecated
// filter by host_id
HostId string `json:"host_id" "yunion:deprecated-by":"host"`
HostId string `json:"host_id" yunion-deprecated-by:"host"`
}
type HostRegisterMetadata struct {

View File

@@ -21,7 +21,7 @@ type HostJointResourceDetailsBase struct {
Host string `json:"host"`
// 裸金属服务器名称
// Deprecated
Baremetal string `json:"baremetal" "yunion:deprecated-by":"host"`
Baremetal string `json:"baremetal" yunion-deprecated-by:"host"`
}
type HostJointResourceDetails struct {

View File

@@ -49,7 +49,7 @@ type KeypairListInput struct {
}
type CachedimageListInput struct {
apis.StandaloneResourceListInput
apis.SharableVirtualResourceListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
@@ -144,7 +144,7 @@ type GuestTemplateFilterListInput struct {
GuestTemplate string `json:"guest_template"`
// swagger:ignore
// Deprecated
GuestTemplateId string `json:"guest_template_id" "yunion:deprecated-by":"guest_template"`
GuestTemplateId string `json:"guest_template_id" yunion-deprecated-by:"guest_template"`
}
type ServiceCatalogListInput struct {

View File

@@ -50,7 +50,7 @@ type GroupResourceInput struct {
// swagger:ignore
// Deprecated
// Filter by instance group Id
GroupId string `json:"group_id" "yunion:deprecated-by":"group"`
GroupId string `json:"group_id" yunion-deprecated-by:"group"`
}
type GroupFilterListInput struct {

View File

@@ -210,7 +210,7 @@ type LoadbalancerResourceInput struct {
// swagger:ignore
// Deprecated
LoadbalancerId string `json:"loadbalancer_id" "yunion:deprecated-by":"loadbalancer"`
LoadbalancerId string `json:"loadbalancer_id" yunion-deprecated-by:"loadbalancer"`
}
type LoadbalancerFilterListInput struct {

View File

@@ -35,7 +35,7 @@ type LoadbalancerAclResourceInput struct {
// swagger:ignore
// Deprecated
Acl string `json:"acl" "yunion:deprecated-by":"acl_id"`
Acl string `json:"acl" yunion-deprecated-by:"acl_id"`
}
type LoadbalancerAclFilterListInput struct {

View File

@@ -39,7 +39,7 @@ type LoadbalancerBackendGroupResourceInput struct {
// swagger:ignore
// Deprecated
BackendGroupId string `json:"backend_group_id" "yunion:deprecated-by":"backend_group"`
BackendGroupId string `json:"backend_group_id" yunion-deprecated-by:"backend_group"`
}
type LoadbalancerBackendGroupFilterListInput struct {

View File

@@ -32,7 +32,7 @@ type LoadbalancerCertificateResourceInput struct {
// swagger:ignore
// Deprecated
CertificateId string `json:"certificate_id" "yunion:deprecated-by":"certificate"`
CertificateId string `json:"certificate_id" yunion-deprecated-by:"certificate"`
}
type LoadbalancerCertificateFilterListInput struct {

View File

@@ -45,7 +45,7 @@ type LoadbalancerClusterResourceInput struct {
// swagger:ignore
// Deprecated
ClusterId string `json:"cluster_id" "yunion:deprecated-by":"cluster"`
ClusterId string `json:"cluster_id" yunion-deprecated-by:"cluster"`
}
type LoadbalancerClusterFilterListInput struct {

View File

@@ -46,7 +46,7 @@ type LoadbalancerListenerResourceInput struct {
// 负载均衡监听器ID
// swagger:ignore
// Deprecated
ListenerId string `json:"listener_id" "yunion:deprecated-by":"listener"`
ListenerId string `json:"listener_id" yunion-deprecated-by:"listener"`
}
type LoadbalancerListenerFilterListInput struct {

View File

@@ -89,7 +89,7 @@ type NatGatewayResourceInput struct {
// swagger:ignore
// Deprecated
NatgatewayId string `json:"natgateway_id" "yunion:deprecated-by":"natgateway"`
NatgatewayId string `json:"natgateway_id" yunion-deprecated-by:"natgateway"`
}
type NatGatewayFilterListInput struct {

View File

@@ -24,7 +24,7 @@ type WireResourceInput struct {
// swagger:ignore
// Deprecated
// fitler by wire id
WireId string `json:"wire_id" "yunion:deprecated-by":"wire"`
WireId string `json:"wire_id" yunion-deprecated-by:"wire"`
}
type WireFilterListBase struct {
@@ -47,7 +47,7 @@ type NetworkResourceInput struct {
// swagger:ignore
// Deprecated
// filter by networkId
NetworkId string `json:"network_id" "yunion:deprecated-by":"network"`
NetworkId string `json:"network_id" yunion-deprecated-by:"network"`
}
type NetworkFilterListBase struct {
@@ -300,3 +300,13 @@ type NetworkUpdateInput struct {
// 分配策略
AllocPolicy string `json:"alloc_policy"`
}
type GetNetworkAddressesInput struct {
// 获取资源的范围,例如 project|domain|system
Scope string `json:"scope"`
}
type GetNetworkAddressesOutput struct {
// IP子网地址记录
Addresses []SNetworkAddress `json:"addresses"`
}

View File

@@ -45,7 +45,7 @@ type SchedtagResourceInput struct {
// swagger:ignore
// Deprecated
// filter by schedtag_id
SchedtagId string `json:"schedtag_id" "yunion:deprecated-by":"schedtag"`
SchedtagId string `json:"schedtag_id" yunion-deprecated-by:"schedtag"`
}
type SchedtagFilterListInput struct {
@@ -69,7 +69,7 @@ type SchedtagListInput struct {
// swagger:ignore
// Deprecated
// filter by type, alias for resource_type
Type string `json:"type" "yunion:deprecated-by":"resource_type"`
Type string `json:"type" yunion-deprecated-by:"resource_type"`
DefaultStrategy []string `json:"default_strategy"`
}

View File

@@ -194,7 +194,7 @@ type SecgroupResourceInput struct {
// swagger:ignore
// Deprecated
// filter by secgroup_id
SecgroupId string `json:"secgroup_id" "yunion:deprecated-by":"secgroup"`
SecgroupId string `json:"secgroup_id" yunion-deprecated-by:"secgroup"`
// 模糊匹配安全组规则名称
SecgroupName string `json:"secgroup_name"`
@@ -248,3 +248,6 @@ type GuestsecgroupDetails struct {
// 安全组名称
Secgroup string `json:"secgroup"`
}
type SecurityGroupPurgeInput struct {
}

View File

@@ -144,7 +144,7 @@ type StorageResourceInput struct {
// swagger:ignore
// Deprecated
// filter by storage_id
StorageId string `json:"storage_id" "yunion:deprecated-by":"storage"`
StorageId string `json:"storage_id" yunion-deprecated-by:"storage"`
}
type StorageFilterListInputBase struct {

View File

@@ -48,13 +48,13 @@ type StoragecachedimageListInput struct {
Storagecache string `json:"storagecache"`
// Deprecated
// swagger:ignore
StoragecacheId string `json:"storagecache_id" "yunion:deprecated-by":"storagecache"`
StoragecacheId string `json:"storagecache_id" yunion-deprecated-by:"storagecache"`
// 以镜像缓存过滤
Cachedimage string `json:"cachedimage"`
// Deprecated
// swagger:ignore
CachedimageId string `json:"cachedimage_id" "yunion:deprecated-by":"cachedimage"`
CachedimageId string `json:"cachedimage_id" yunion-deprecated-by:"cachedimage"`
// 镜像状态
Status []string `json:"status"`

View File

@@ -90,7 +90,7 @@ type VpcResourceInput struct {
// swagger:ignore
// Deprecated
// filter by vpc Id
VpcId string `json:"vpc_id" "yunion:deprecated-by":"vpc"`
VpcId string `json:"vpc_id" yunion-deprecated-by:"vpc"`
// Vpc外网访问模式
ExternalAccessMode string `json:"external_access_mode"`

View File

@@ -32,6 +32,34 @@ var (
}
)
const (
sVpcInterCidr = "100.65.0.0/17"
sVpcInterExtCidr = "100.65.0.0/30"
VpcInterExtMask = 30
sVpcInterExtIP1 = "100.65.0.1"
sVpcInterExtIP2 = "100.65.0.2"
VpcInterExtMac1 = "ee:ee:ee:ee:ee:f0"
VpcInterExtMac2 = "ee:ee:ee:ee:ee:f1"
)
var (
vpcInterCidr netutils.IPV4Prefix
vpcInterExtIP1 netutils.IPV4Addr
vpcInterExtIP2 netutils.IPV4Addr
)
func VpcInterCidr() netutils.IPV4Prefix {
return vpcInterCidr
}
func VpcInterExtIP1() netutils.IPV4Addr {
return vpcInterExtIP1
}
func VpcInterExtIP2() netutils.IPV4Addr {
return vpcInterExtIP2
}
const (
sVpcMappedCidr = "100.64.0.0/17"
VpcMappedIPMask = 17
@@ -92,6 +120,10 @@ func init() {
return v
}
vpcInterCidr = mp(netutils.NewIPV4Prefix(sVpcInterCidr))
vpcInterExtIP1 = mi(netutils.NewIPV4Addr(sVpcInterExtIP1))
vpcInterExtIP2 = mi(netutils.NewIPV4Addr(sVpcInterExtIP2))
vpcMappedCidr = mp(netutils.NewIPV4Prefix(sVpcMappedCidr))
vpcMappedGatewayIP = mi(netutils.NewIPV4Addr(sVpcMappedGatewayIP))

View File

@@ -73,7 +73,7 @@ type IdentityProviderCreateInput struct {
TargetDomain string `json:"target_domain"`
// swagger:ignore
// Deprecated
TargetDomainId string `json:"target_domain_id" "yunion:deprecated-by":"target_domain"`
TargetDomainId string `json:"target_domain_id" yunion-deprecated-by:"target_domain"`
// 新建域的时候是否自动新建第一个项目
AutoCreateProject *bool `json:"auto_create_project"`

View File

@@ -49,22 +49,22 @@ type ProjectFilterListInput struct {
ProjectDomain string `json:"project_domain"`
// swagger:ignore
// Deprecated
ProjectDomainId string `json:"project_domain_id" "yunion:deprecated-by":"project-domain"`
ProjectDomainId string `json:"project_domain_id" yunion-deprecated-by:"project-domain"`
// 以项目ID或Name过滤列表结果
Project string `json:"project"`
// swagger:ignore
// Deprecated
// filter by project_id
ProjectId string `json:"project_id" "yunion:deprecated-by":"project"`
ProjectId string `json:"project_id" yunion-deprecated-by:"project"`
// swagger:ignore
// Deprecated
// filter by tenant
Tenant string `json:"tenant" "yunion:deprecated-by":"project"`
Tenant string `json:"tenant" yunion-deprecated-by:"project"`
// swagger:ignore
// Deprecated
// filter by tenant_id
TenantId string `json:"tenant_id" "yunion:deprecated-by":"project"`
TenantId string `json:"tenant_id" yunion-deprecated-by:"project"`
}
type UserFilterListInput struct {
@@ -79,7 +79,7 @@ type UserFilterListInput struct {
// swagger:ignore
// Deprecated
// filter by user_id
UserId string `json:"user_id" "yunion:deprecated-by":"user"`
UserId string `json:"user_id" yunion-deprecated-by:"user"`
}
type GroupFilterListInput struct {
@@ -94,7 +94,7 @@ type GroupFilterListInput struct {
// swagger:ignore
// Deprecated
// filter by group_id
GroupId string `json:"group_id" "yunion:deprecated-by":"group"`
GroupId string `json:"group_id" yunion-deprecated-by:"group"`
}
type RoleFilterListInput struct {
@@ -109,7 +109,7 @@ type RoleFilterListInput struct {
// swagger:ignore
// Deprecated
// filter by role_id
RoleId string `json:"role_id" "yunion:deprecated-by":"role"`
RoleId string `json:"role_id" yunion-deprecated-by:"role"`
}
type ServiceFilterListInput struct {
@@ -121,7 +121,7 @@ type ServiceFilterListInput struct {
// swagger:ignore
// Deprecated
// filter by service_id
ServiceId string `json:"service_id" "yunion:deprecated-by":"service"`
ServiceId string `json:"service_id" yunion-deprecated-by:"service"`
// 以服务名称排序
OrderByService string `json:"order_by_service"`
@@ -325,7 +325,7 @@ type RegionFilterListInput struct {
Region string `json:"region"`
// swagger:ignore
// Deprecated
RegionId string `json:"region_id" "yunion:deprecated-by":"region"`
RegionId string `json:"region_id" yunion-deprecated-by:"region"`
}
type RegionListInput struct {

View File

@@ -21,15 +21,15 @@ type DomainizedResourceInput struct {
// swagger:ignore
// Deprecated
Domain string `json:"domain" "yunion:deprecated-by":"project_domain"`
Domain string `json:"domain" yunion-deprecated-by:"project_domain"`
// swagger:ignore
// Deprecated
// Project domain Id filter, alias for project_domain
ProjectDomainId string `json:"project_domain_id" "yunion:deprecated-by":"project_domain"`
ProjectDomainId string `json:"project_domain_id" yunion-deprecated-by:"project_domain"`
// swagger:ignore
// Deprecated
// Domain Id filter, alias for project_domain
DomainId string `json:"domain_id" "yunion:deprecated-by":"project_domain"`
DomainId string `json:"domain_id" yunion-deprecated-by:"project_domain"`
}
type ProjectizedResourceInput struct {
@@ -39,15 +39,15 @@ type ProjectizedResourceInput struct {
// swagger:ignore
// Deprecated
// Filter by project_id, alias for project
ProjectId string `json:"project_id" "yunion:deprecated-by":"project"`
ProjectId string `json:"project_id" yunion-deprecated-by:"project"`
// swagger:ignore
// Deprecated
// Filter by tenant ID or Name, alias for project
Tenant string `json:"tenant" "yunion:deprecated-by":"project"`
Tenant string `json:"tenant" yunion-deprecated-by:"project"`
// swagger:ignore
// Deprecated
// Filter by tenant_id, alias for project
TenantId string `json:"tenant_id" "yunion:deprecated-by":"project"`
TenantId string `json:"tenant_id" yunion-deprecated-by:"project"`
}
type DomainizedResourceCreateInput struct {
@@ -75,6 +75,13 @@ type SharableVirtualResourceCreateInput struct {
SharableResourceBaseCreateInput
}
type AdminSharableVirtualResourceBaseCreateInput struct {
SharableVirtualResourceCreateInput
// 记录
Records string `json:"records"`
}
type StatusDomainLevelUserResourceCreateInput struct {
StatusDomainLevelResourceCreateInput

View File

@@ -50,7 +50,7 @@ type ProjectizedResourceListInput struct {
OrderByProject string `json:"order_by_project"`
// swagger:ignore
// Deprecated
OrderByTenant string `json:"order_by_tenant" "yunion:deprecated-by":"order_by_project"`
OrderByTenant string `json:"order_by_tenant" yunion-deprecated-by:"order_by_project"`
}
type StatusDomainLevelUserResourceListInput struct {
@@ -61,7 +61,7 @@ type StatusDomainLevelUserResourceListInput struct {
// swagger:ignore
// Deprecated
// Filter by userId
UserId string `json:"user_id" "yunion:deprecated-by":"user"`
UserId string `json:"user_id" yunion-deprecated-by:"user"`
}
type UserResourceListInput struct {
@@ -78,7 +78,7 @@ type UserResourceListInput struct {
// swagger:ignore
// Deprecated
// Filter by userId
UserId string `json:"user_id" "yunion:deprecated-by":"user"`
UserId string `json:"user_id" yunion-deprecated-by:"user"`
}
type ModelBaseListInput struct {

View File

@@ -155,11 +155,11 @@ type ProjectizedResourceInfo struct {
// 资源归属项目的ID(向后兼容别名)
// Deprecated
TenantId string `json:"project_id" "yunion:deprecated-by":"tenant_id"`
TenantId string `json:"project_id" yunion-deprecated-by:"tenant_id"`
// 资源归属项目的名称(向后兼容别名)
// Deprecated
Tenant string `json:"project" "yunion:deprecated-by":"tenant"`
Tenant string `json:"project" yunion-deprecated-by:"tenant"`
}
type ScopedResourceBaseInfo struct {

View File

@@ -28,14 +28,14 @@ type ParameterListInput struct {
// Deprecated
// swagger:ignore
ServiceId string `json:"service_id" "yunion:deprecated-by":"service"`
ServiceId string `json:"service_id" yunion-deprecated-by:"service"`
// 用户名称或ID
User string `json:"user"`
// Deprecated
// swagger:ignore
UserId string `json:"user_id" "yunion:deprecated-by":"user"`
UserId string `json:"user_id" yunion-deprecated-by:"user"`
// filter by name
Name []string `json:"name"`

View File

@@ -61,6 +61,7 @@ import (
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/util/dhcp"
"yunion.io/x/onecloud/pkg/util/fileutils2"
"yunion.io/x/onecloud/pkg/util/httputils"
"yunion.io/x/onecloud/pkg/util/influxdb"
"yunion.io/x/onecloud/pkg/util/procutils"
"yunion.io/x/onecloud/pkg/util/redfish"
@@ -1398,7 +1399,15 @@ func (b *SBaremetalInstance) DoRedfishPowerOn() error {
b.ClearSSHConfig()
redfishApi := b.GetRedfishCli(ctx)
if redfishApi != nil {
return redfishApi.Reset(ctx, "On")
err := redfishApi.Reset(ctx, "On")
if err != nil {
if httputils.ErrorCode(err) == 409 {
log.Warningf("redfishApi.Reset On fail %s", err)
} else {
return errors.Wrap(err, "redfishApi.Reset On")
}
}
return nil
}
return fmt.Errorf("Baremetal %s redfishApi is nil", b.GetId())
}
@@ -1953,6 +1962,8 @@ func (b *SBaremetalInstance) GetConsoleJNLP(ctx context.Context) (string, error)
return bmc.GetIdracConsoleJNLP(ctx, "", "")
case "supermicro":
return bmc.GetSupermicroConsoleJNLP(ctx)
case "lenovo":
return bmc.GetLenovoConsoleJNLP(ctx)
}
return "", httperrors.NewNotImplementedError("Unsupported manufacture %s", manufacture)
}

View File

@@ -20,9 +20,8 @@ import (
"strconv"
"strings"
"github.com/pkg/errors"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/tristate"
"yunion.io/x/pkg/util/stringutils"
"yunion.io/x/pkg/utils"
@@ -75,7 +74,7 @@ func (dev *MegaRaidPhyDev) ToBaremetalStorage(index int) *baremetal.BaremetalSto
}
func (dev *MegaRaidPhyDev) GetSize() int64 {
return dev.sector * int64(dev.block) / 1024 / 1024 // MB
return dev.sector * dev.block / 1024 / 1024 // MB
}
func (dev *MegaRaidPhyDev) parseLine(line string) bool {
@@ -124,7 +123,7 @@ func (dev *MegaRaidPhyDev) parseLine(line string) bool {
if err != nil {
log.Errorf("parse logical sector size error: %v", err)
dev.block = 512
} else {
} else if block > 0 {
dev.block = int64(block)
}
default:
@@ -189,6 +188,7 @@ type MegaRaidAdaptor struct {
raid *MegaRaid
devs []*MegaRaidPhyDev
sn string
name string
busNumber string
deviceNumber string
funcNumber string
@@ -209,6 +209,10 @@ func NewMegaRaidAdaptor(index int, raid *MegaRaid) (*MegaRaidAdaptor, error) {
return adapter, nil
}
func (adapter MegaRaidAdaptor) key() string {
return adapter.name + adapter.sn
}
func (adapter *MegaRaidAdaptor) fillInfo() error {
cmd := GetCommand("-AdpAllInfo", fmt.Sprintf("-a%d", adapter.index))
ret, err := adapter.remoteRun(cmd)
@@ -223,10 +227,12 @@ func (adapter *MegaRaidAdaptor) fillInfo() error {
switch key {
case "Serial No":
adapter.sn = val
case "Product Name":
adapter.name = val
}
}
if len(adapter.sn) == 0 {
return errors.New("Not found Serial No")
if len(adapter.key()) == 0 {
return errors.Error("Not found Serial No and Product Name")
}
return adapter.fillPCIInfo()
}
@@ -267,7 +273,7 @@ func (adapter *MegaRaidAdaptor) fillPCIInfo() error {
}
}
if len(adapter.busNumber) == 0 || len(adapter.deviceNumber) == 0 || len(adapter.funcNumber) == 0 {
return errors.New("Not found bus number")
return errors.Error("Not found bus number")
}
pciDir := fmt.Sprintf("/sys/bus/pci/devices/0000:%s:%s.%s/", adapter.busNumber, adapter.deviceNumber, adapter.funcNumber)
cmd = raiddrivers.GetCommand("ls", pciDir, "|", "grep", "host")
@@ -601,18 +607,24 @@ func (adapter *MegaRaidAdaptor) BuildNoneRaid(devs []*baremetal.BaremetalStorage
type StorcliAdaptor struct {
Controller int
SN string
sn string
name string
}
func newStorcliAdaptor() *StorcliAdaptor {
return &StorcliAdaptor{
Controller: -1,
SN: "",
sn: "",
name: "",
}
}
func (a StorcliAdaptor) key() string {
return a.name + a.sn
}
func (a *StorcliAdaptor) isComplete() bool {
return a.Controller >= 0 && a.SN != ""
return a.Controller >= 0 && a.key() != ""
}
func (a *StorcliAdaptor) parseLine(l string) {
@@ -626,13 +638,15 @@ func (a *StorcliAdaptor) parseLine(l string) {
case "Controller":
a.Controller, _ = strconv.Atoi(val)
case "Serial Number":
a.SN = val
a.sn = val
case "Product Name":
a.name = val
}
}
func (raid *MegaRaid) GetStorcliAdaptor() (map[string]*StorcliAdaptor, error) {
ret := make(map[string]*StorcliAdaptor)
cmd := GetCommand2("/call", "show", "|", "grep", "-iE", `'^(Controller|Serial Number)\s='`)
cmd := GetCommand2("/call", "show", "|", "grep", "-iE", `'^(Controller|Product Name|Serial Number)\s='`)
lines, err := raid.term.Run(cmd)
if err != nil {
return nil, errors.Wrap(err, "Get storcli adapter")
@@ -641,7 +655,7 @@ func (raid *MegaRaid) GetStorcliAdaptor() (map[string]*StorcliAdaptor, error) {
for _, l := range lines {
adapter.parseLine(l)
if adapter.isComplete() {
ret[adapter.SN] = adapter
ret[adapter.key()] = adapter
adapter = newStorcliAdaptor()
}
}
@@ -656,9 +670,9 @@ func (adapter *MegaRaidAdaptor) storcliCtrlIndex() (int, error) {
if err != nil {
return -1, errors.Wrap(err, "Get all Storcli adaptor")
}
storAdap, ok := storcliAdaps[adapter.sn]
storAdap, ok := storcliAdaps[adapter.key()]
if !ok {
return -1, errors.Errorf("Not found storcli adaptor by SN %q", adapter.sn)
return -1, errors.Errorf("Not found storcli adaptor by SN %q", adapter.key())
}
return storAdap.Controller, nil
}
@@ -914,6 +928,9 @@ func (raid *MegaRaid) ParsePhyDevs() error {
if err != nil {
return fmt.Errorf("List raid disk error: %v", err)
}
if raiddrivers.Debug {
log.Debugf("-PDList -aALL: %s", ret)
}
err = raid.parsePhyDevs(ret)
if err != nil {
return fmt.Errorf("parse physical disk device error: %v", err)

View File

@@ -28,6 +28,10 @@ import (
"yunion.io/x/onecloud/pkg/util/sysutils"
)
var (
Debug bool
)
const (
MODULE_MEGARAID = "megaraid_sas"
MODULE_HPSA = "hpsa"

View File

@@ -239,6 +239,7 @@ func (agent *SBaseAgent) createOrUpdateBaremetalAgent(session *mcclient.ClientSe
if agent.IAgent().GetAgentType() != string(api.AgentTypeEsxi) {
params.Add(jsonutils.NewString(naccessIP.String()), "access_ip")
}
params.Add(jsonutils.NewString(agent.IAgent().GetZoneName()), "zone_id")
params.Add(jsonutils.NewString(agent.IAgent().GetAgentType()), "agent_type")
ret, err := modules.Baremetalagents.List(session, params)
if err != nil {

View File

@@ -51,7 +51,22 @@ func (manager *SAdminSharableVirtualResourceBaseManager) GetIAdminSharableVirtua
return manager.GetVirtualObject().(IAdminSharableVirtualModelManager)
}
func (manager *SAdminSharableVirtualResourceBaseManager) ValidateCreateData(man IAdminSharableVirtualModelManager, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
func (manager *SAdminSharableVirtualResourceBaseManager) ValidateCreateData(
ctx context.Context,
userCred mcclient.TokenCredential,
ownerId mcclient.IIdentityProvider,
query jsonutils.JSONObject,
input apis.AdminSharableVirtualResourceBaseCreateInput,
) (apis.AdminSharableVirtualResourceBaseCreateInput, error) {
var err error
input.SharableVirtualResourceCreateInput, err = manager.SSharableVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.SharableVirtualResourceCreateInput)
if err != nil {
return input, errors.Wrap(err, "SSharableVirtualResourceBaseManager.ValidateCreateData")
}
return input, nil
}
func (manager *SAdminSharableVirtualResourceBaseManager) ValidateRecordsData(man IAdminSharableVirtualModelManager, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
records, err := man.ParseInputInfo(data)
if err != nil {
return nil, err

View File

@@ -106,9 +106,16 @@ func (manager *SDomainizedResourceBaseManager) ListItemFilter(
query apis.DomainizedResourceListInput,
) (*sqlchemy.SQuery, error) {
if len(query.ProjectDomains) > 0 {
// make sure ids are not utf8 string
idList := make([]string, 0)
for _, pid := range query.ProjectDomains {
if !stringutils2.IsUtf8(pid) {
idList = append(idList, pid)
}
}
tenants := TenantCacheManager.GetDomainQuery().SubQuery()
subq := tenants.Query(tenants.Field("id")).Filter(sqlchemy.OR(
sqlchemy.In(tenants.Field("id"), query.ProjectDomains),
sqlchemy.In(tenants.Field("id"), idList),
sqlchemy.In(tenants.Field("name"), query.ProjectDomains),
)).SubQuery()
q = q.In("domain_id", subq)

View File

@@ -16,6 +16,7 @@ package db
import (
"context"
"database/sql"
"fmt"
"strconv"
"strings"
@@ -464,28 +465,7 @@ func (manager *SOpsLogManager) ListItemFilter(
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
) (*sqlchemy.SQuery, error) {
/*userStrs := jsonutils.GetQueryStringArray(query, "user")
if len(userStrs) > 0 {
for i := range userStrs {
usrObj, err := DefaultUserFetcher(ctx, userStrs[i])
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("user", userStrs[i])
} else if err == sqlchemy.ErrDuplicateEntry {
return nil, httperrors.NewDuplicateNameError("user", userStrs[i])
} else {
return nil, httperrors.NewGeneralError(err)
}
}
userStrs[i] = usrObj.GetId()
}
if len(userStrs) == 1 {
q = q.Filter(sqlchemy.Equals(q.Field("user_id"), userStrs[0]))
} else {
q = q.Filter(sqlchemy.In(q.Field("user_id"), userStrs))
}
}
projStrs := jsonutils.GetQueryStringArray(query, "project")
projStrs := jsonutils.GetQueryStringArray(query, "owner_project_ids")
if len(projStrs) > 0 {
for i := range projStrs {
projObj, err := DefaultProjectFetcher(ctx, projStrs[i])
@@ -498,12 +478,23 @@ func (manager *SOpsLogManager) ListItemFilter(
}
projStrs[i] = projObj.GetId()
}
if len(projStrs) == 1 {
q = q.Filter(sqlchemy.Equals(q.Field("owner_tenant_id"), projStrs[0]))
} else {
q = q.Filter(sqlchemy.In(q.Field("owner_tenant_id"), projStrs))
q = q.Filter(sqlchemy.In(q.Field("owner_tenant_id"), projStrs))
}
domainStrs := jsonutils.GetQueryStringArray(query, "owner_domain_ids")
if len(domainStrs) > 0 {
for i := range domainStrs {
domainObj, err := DefaultDomainFetcher(ctx, domainStrs[i])
if err != nil {
if err == sql.ErrNoRows {
return nil, httperrors.NewResourceNotFoundError2("domain", domainStrs[i])
} else {
return nil, httperrors.NewGeneralError(err)
}
}
domainStrs[i] = domainObj.GetId()
}
}*/
q = q.Filter(sqlchemy.In(q.Field("owner_domain_id"), domainStrs))
}
objTypes := jsonutils.GetQueryStringArray(query, "obj_type")
if len(objTypes) > 0 {
if len(objTypes) == 1 {

View File

@@ -101,9 +101,16 @@ func (manager *SProjectizedResourceBaseManager) ListItemFilter(
return nil, errors.Wrap(err, "SDomainizedResourceBaseManager.ListItemFilter")
}
if len(query.Projects) > 0 {
// make sure ids are not utf8 string
idList := make([]string, 0)
for _, pid := range query.Projects {
if !stringutils2.IsUtf8(pid) {
idList = append(idList, pid)
}
}
tenants := TenantCacheManager.GetTenantQuery().SubQuery()
subq := tenants.Query(tenants.Field("id")).Filter(sqlchemy.OR(
sqlchemy.In(tenants.Field("id"), query.Projects),
sqlchemy.In(tenants.Field("id"), idList),
sqlchemy.In(tenants.Field("name"), query.Projects),
)).SubQuery()
q = q.In("tenant_id", subq)

View File

@@ -43,7 +43,7 @@ func isObjectRbacAllowed(model IModel, userCred mcclient.TokenCredential, action
case rbacutils.ScopeSystem:
requireScope = rbacutils.ScopeSystem
case rbacutils.ScopeDomain:
if ownerId != nil && objOwnerId != nil && (ownerId.GetUserId() == objOwnerId.GetUserId()) {
if ownerId != nil && objOwnerId != nil && (ownerId.GetUserId() == objOwnerId.GetUserId() && action == policy.PolicyActionGet) {
requireScope = rbacutils.ScopeUser
} else if ownerId != nil && objOwnerId != nil && (ownerId.GetProjectDomainId() == objOwnerId.GetProjectDomainId() || objOwnerId.GetProjectDomainId() == "" || (model.IsSharable(ownerId) && action == policy.PolicyActionGet)) {
requireScope = rbacutils.ScopeDomain

View File

@@ -46,7 +46,7 @@ type SSubTask struct {
Stage string `width:"64" charset:"ascii" nullable:"false" primary:"true"` // Column(VARCHAR(64, charset='ascii'), nullable=False, primary_key=True)
SubtaskId string `width:"36" charset:"ascii" nullable:"false" primary:"true"` // Column(VARCHAR(36, charset='ascii'), nullable=False, primary_key=True)
Status string `width:"36" charset:"ascii" nullable:"false" default:"init"` // Column(VARCHAR(36, charset='ascii'), nullable=False, default=SUBTASK_INIT)
Result string `length:"medium" charset:"ascii" nullable:"true"` // Column(MEDIUMTEXT(charset='ascii'), nullable=True)
Result string `length:"medium" charset:"utf8" nullable:"true"` // Column(MEDIUMTEXT(charset='ascii'), nullable=True)
}
func (manager *SSubTaskmanager) GetSubTask(ptaskId string, subtaskId string) *SSubTask {

View File

@@ -126,7 +126,7 @@ func RawNotify(recipientId []string, isGroup bool, channel notify.TNotifyChannel
msg.Topic = topic
body, _ := getContent(event, "content", channel, data)
if len(body) == 0 {
body = data.String()
body, _ = data.GetString()
}
msg.Msg = body
// log.Debugf("send notification %s %s", topic, body)

View File

@@ -156,7 +156,7 @@ type ICloudZone interface {
}
type ICloudImage interface {
ICloudResource
IVirtualResource
Delete(ctx context.Context) error
GetIStoragecache() ICloudStoragecache
@@ -173,6 +173,7 @@ type ICloudImage interface {
GetImageFormat() string
GetCreatedAt() time.Time
UEFI() bool
GetPublicScope() rbacutils.TRbacScope
}
type ICloudStoragecache interface {
@@ -487,6 +488,7 @@ type ICloudHostNetInterface interface {
GetIpAddr() string
GetMtu() int32
GetNicType() string
GetBridge() string
}
type ICloudLoadbalancer interface {

View File

@@ -314,6 +314,10 @@ func (self *SBaseGuestDriver) IsWindowsUserDataTypeNeedEncode() bool {
return false
}
func (self *SBaseGuestDriver) IsSupportdDcryptPasswordFromSecretKey() bool {
return true
}
func (self *SBaseGuestDriver) GetUserDataType() string {
return cloudprovider.CLOUD_CONFIG
}

View File

@@ -172,7 +172,7 @@ func (self *SESXiGuestDriver) GetJsonDescAtHost(ctx context.Context, userCred mc
if img.ImageType != cloudprovider.CachedImageTypeSystem {
return desc
}
sciSubQ := models.StoragecachedimageManager.Query("storagecache_id").Equals("cachedimage_id", templateId).Equals("status", api.CACHED_IMAGE_STATUS_READY).SubQuery()
sciSubQ := models.StoragecachedimageManager.Query("storagecache_id").Equals("cachedimage_id", templateId).Equals("status", api.CACHED_IMAGE_STATUS_ACTIVE).SubQuery()
scQ := models.StoragecacheManager.Query().In("id", sciSubQ)
storageCaches := make([]models.SStoragecache, 0, 1)
err = db.FetchModelObjects(models.StoragecacheManager, scQ, &storageCaches)
@@ -368,3 +368,42 @@ func (self *SESXiGuestDriver) RequestAssociateEip(ctx context.Context, userCred
func (self *SESXiGuestDriver) IsSupportCdrom(guest *models.SGuest) (bool, error) {
return false, nil
}
func (self *SESXiGuestDriver) RequestSyncstatusOnHost(ctx context.Context, guest *models.SGuest, host *models.SHost, userCred mcclient.TokenCredential) (jsonutils.JSONObject, error) {
ihost, err := host.GetIHost()
if err != nil {
return nil, err
}
ivm, err := ihost.GetIVMById(guest.GetExternalId())
if err != nil && errors.Cause(err) != errors.ErrNotFound {
return nil, err
}
// VM may be migrated by Vcenter, try to find VM from whole datacenter.
if err != nil {
ehost := ihost.(*esxi.SHost)
dc, err := ehost.GetDatacenter()
if err != nil {
return nil, errors.Wrapf(err, "ehost.GetDatacenter")
}
vm, err := dc.FetchVMById(guest.GetExternalId())
if err != nil {
log.Errorf("fail to find ivm by id %q in dc %q: %v", guest.GetExternalId(), dc.GetName(), err)
return nil, err
}
ihost = vm.GetIHost()
host = models.HostManager.FetchHostByExtId(ihost.GetGlobalId())
if host == nil {
return nil, errors.Wrapf(errors.ErrNotFound, "find ivm %q in ihost %q which is not existed here", guest.GetExternalId(), ihost.GetGlobalId())
}
ivm = vm
}
err = guest.SyncAllWithCloudVM(ctx, userCred, host, ivm)
if err != nil {
return nil, err
}
status := GetCloudVMStatus(ivm)
body := jsonutils.NewDict()
body.Add(jsonutils.NewString(status), "status")
return body, nil
}

View File

@@ -226,6 +226,10 @@ func (self *SQcloudGuestDriver) GetGuestInitialStateAfterRebuild() string {
return api.VM_RUNNING
}
func (self *SQcloudGuestDriver) IsSupportdDcryptPasswordFromSecretKey() bool {
return false
}
func (self *SQcloudGuestDriver) GetUserDataType() string {
return cloudprovider.CLOUD_SHELL
}

View File

@@ -182,7 +182,7 @@ func (self *SManagedVirtualizationHostDriver) RequestSaveUploadImageOnHost(ctx c
osType, _ := params.GetString("properties", "os_type")
scimg := models.StoragecachedimageManager.Register(ctx, task.GetUserCred(), iStoragecache.GetId(), imageId, "")
if scimg.Status != api.CACHED_IMAGE_STATUS_READY {
if scimg.Status != api.CACHED_IMAGE_STATUS_ACTIVE {
scimg.SetStatus(task.GetUserCred(), api.CACHED_IMAGE_STATUS_CACHING, "request_prepare_save_disk_on_host")
}
iImage, err := iStoragecache.CreateIImage(snapshot.GetId(), fmt.Sprintf("Image-%s", imageId), osType, "")
@@ -208,7 +208,7 @@ func (self *SManagedVirtualizationHostDriver) RequestSaveUploadImageOnHost(ctx c
if err := snapshot.Delete(); err != nil {
log.Errorf("Delete snapshot %s failed: %v", snapshot.GetId(), err)
}
scimg.SetStatus(task.GetUserCred(), api.CACHED_IMAGE_STATUS_READY, "")
scimg.SetStatus(task.GetUserCred(), api.CACHED_IMAGE_STATUS_ACTIVE, "")
return result, nil
})
return nil

View File

@@ -37,11 +37,12 @@ import (
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/util/rbacutils"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SCachedimageManager struct {
db.SStandaloneResourceBaseManager
db.SSharableVirtualResourceBaseManager
db.SExternalizedResourceBaseManager
}
@@ -49,7 +50,7 @@ var CachedimageManager *SCachedimageManager
func init() {
CachedimageManager = &SCachedimageManager{
SStandaloneResourceBaseManager: db.NewStandaloneResourceBaseManager(
SSharableVirtualResourceBaseManager: db.NewSharableVirtualResourceBaseManager(
SCachedimage{},
"cachedimages_tbl",
"cachedimage",
@@ -60,7 +61,7 @@ func init() {
}
type SCachedimage struct {
db.SStandaloneResourceBase
db.SSharableVirtualResourceBase
db.SExternalizedResourceBase
// 镜像大小单位: Byte
@@ -100,10 +101,10 @@ func (self *SCachedimage) ValidateDeleteCondition(ctx context.Context) error {
if cnt > 0 {
return httperrors.NewNotEmptyError("The image has been cached on storages")
}
if self.GetStatus() == "active" && !self.isReferenceSessionExpire() {
if self.GetStatus() == api.CACHED_IMAGE_STATUS_ACTIVE && !self.isReferenceSessionExpire() {
return httperrors.NewConflictError("the image reference session has not been expired!")
}
return self.SStandaloneResourceBase.ValidateDeleteCondition(ctx)
return self.SSharableVirtualResourceBase.ValidateDeleteCondition(ctx)
}
func (self *SCachedimage) isReferenceSessionExpire() bool {
@@ -194,32 +195,44 @@ func (manager *SCachedimageManager) cacheGlanceImageInfo(ctx context.Context, us
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
imgId, _ := info.GetString("id")
if len(imgId) == 0 {
img := struct {
Id string
Size int64
Name string
Status string
IsPublic bool
ProjectId string `json:"tenant_id"`
PublicScope string
}{}
err := info.Unmarshal(&img)
if err != nil {
return nil, errors.Wrapf(err, "Unmarshal %s", info.String())
}
if len(img.Id) == 0 {
return nil, fmt.Errorf("invalid image info")
}
if len(img.Name) == 0 {
img.Name = img.Id
}
imageCache := SCachedimage{}
imageCache.SetModelManager(manager, &imageCache)
size, _ := info.Int("size")
name, _ := info.GetString("name")
if len(name) == 0 {
name = imgId
}
name, err := db.GenerateName(manager, nil, name)
img.Name, err = db.GenerateName(manager, nil, img.Name)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "db.GenerateName(%s)", img.Name)
}
err = manager.RawQuery().Equals("id", imgId).First(&imageCache)
err = manager.RawQuery().Equals("id", img.Id).First(&imageCache)
if err != nil {
if err == sql.ErrNoRows { // insert
imageCache.Id = imgId
imageCache.Name = name
imageCache.Size = size
imageCache.Id = img.Id
imageCache.Name = img.Name
imageCache.Size = img.Size
imageCache.Info = info
imageCache.Status = img.Status
imageCache.IsPublic = img.IsPublic
imageCache.PublicScope = img.PublicScope
imageCache.LastSync = timeutils.UtcNow()
err = manager.TableSpec().Insert(ctx, &imageCache)
@@ -230,13 +243,16 @@ func (manager *SCachedimageManager) cacheGlanceImageInfo(ctx context.Context, us
return &imageCache, nil
} else {
log.Errorf("fetching image cache (%s) failed: %s", imgId, err)
log.Errorf("fetching image cache (%s) failed: %s", img.Id, err)
return nil, err
}
} else { // update
diff, err := db.Update(&imageCache, func() error {
imageCache.Size = size
imageCache.Size = img.Size
imageCache.Info = info
imageCache.Status = img.Status
imageCache.IsPublic = img.IsPublic
imageCache.PublicScope = img.PublicScope
imageCache.LastSync = timeutils.UtcNow()
if imageCache.Deleted == true {
imageCache.Deleted = false
@@ -323,16 +339,15 @@ func (manager *SCachedimageManager) FetchCustomizeColumns(
isList bool,
) []api.CachedimageDetails {
rows := make([]api.CachedimageDetails, len(objs))
stdRows := manager.SStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
virtRows := manager.SSharableVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
ci := objs[i].(*SCachedimage)
rows[i] = api.CachedimageDetails{
StandaloneResourceDetails: stdRows[i],
Status: ci.GetStatus(),
OsType: ci.GetOSType(),
OsDistribution: ci.GetOSDistribution(),
OsVersion: ci.GetOSVersion(),
Hypervisor: ci.GetHypervisor(),
SharableVirtualResourceDetails: virtRows[i],
OsType: ci.GetOSType(),
OsDistribution: ci.GetOSDistribution(),
OsVersion: ci.GetOSVersion(),
Hypervisor: ci.GetHypervisor(),
}
rows[i].CachedCount, _ = ci.getStoragecacheCount()
}
@@ -372,7 +387,7 @@ func (self *SCachedimage) PerformUncacheImage(ctx context.Context, userCred mccl
}
func (self *SCachedimage) addRefCount() {
if self.GetStatus() != "active" {
if self.GetStatus() != api.CACHED_IMAGE_STATUS_ACTIVE {
return
}
_, err := db.Update(self, func() error {
@@ -397,7 +412,7 @@ func (self *SCachedimage) ChooseSourceStoragecacheInRange(hostType string, exclu
Join(hostStorage, sqlchemy.Equals(hostStorage.Field("storage_id"), storage.Field("id"))).
Join(host, sqlchemy.Equals(hostStorage.Field("host_id"), host.Field("id"))).
Filter(sqlchemy.Equals(storageCachedImage.Field("cachedimage_id"), self.Id)).
Filter(sqlchemy.Equals(storageCachedImage.Field("status"), api.CACHED_IMAGE_STATUS_READY)).
Filter(sqlchemy.Equals(storageCachedImage.Field("status"), api.CACHED_IMAGE_STATUS_ACTIVE)).
Filter(sqlchemy.Equals(host.Field("status"), api.HOST_STATUS_RUNNING)).
Filter(sqlchemy.IsTrue(host.Field("enabled"))).
Filter(sqlchemy.Equals(host.Field("host_status"), api.HOST_ONLINE)).
@@ -455,12 +470,17 @@ func (self *SCachedimage) canDeleteLastCache() bool {
return false
}
func (self *SCachedimage) syncWithCloudImage(ctx context.Context, userCred mcclient.TokenCredential, image cloudprovider.ICloudImage) error {
func (self *SCachedimage) syncWithCloudImage(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, image cloudprovider.ICloudImage, managerId string) error {
diff, err := db.UpdateWithLock(ctx, self, func() error {
self.Name = image.GetName()
self.Size = image.GetSizeByte()
self.ExternalId = image.GetGlobalId()
self.ImageType = image.GetImageType()
self.PublicScope = string(image.GetPublicScope())
self.Status = image.GetStatus()
if image.GetPublicScope() == rbacutils.ScopeSystem {
self.IsPublic = true
}
self.UEFI = tristate.NewFromBool(image.UEFI())
sImage := cloudprovider.CloudImage2Image(image)
self.Info = jsonutils.Marshal(&sImage)
@@ -468,10 +488,12 @@ func (self *SCachedimage) syncWithCloudImage(ctx context.Context, userCred mccli
return nil
})
db.OpsLog.LogSyncUpdate(self, diff, userCred)
SyncCloudProject(userCred, self, ownerId, image, managerId)
return err
}
func (manager *SCachedimageManager) newFromCloudImage(ctx context.Context, userCred mcclient.TokenCredential, image cloudprovider.ICloudImage) (*SCachedimage, error) {
func (manager *SCachedimageManager) newFromCloudImage(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, image cloudprovider.ICloudImage, managerId string) (*SCachedimage, error) {
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
@@ -491,12 +513,21 @@ func (manager *SCachedimageManager) newFromCloudImage(ctx context.Context, userC
cachedImage.LastSync = time.Now().UTC()
cachedImage.ImageType = image.GetImageType()
cachedImage.ExternalId = image.GetGlobalId()
cachedImage.Status = image.GetStatus()
cachedImage.PublicScope = string(image.GetPublicScope())
switch image.GetPublicScope() {
case rbacutils.ScopeNone:
default:
cachedImage.IsPublic = true
}
err = manager.TableSpec().Insert(ctx, &cachedImage)
if err != nil {
return nil, err
}
SyncCloudProject(userCred, &cachedImage, ownerId, image, managerId)
return &cachedImage, nil
}
@@ -529,7 +560,7 @@ func (image *SCachedimage) requestRefreshExternalImage(ctx context.Context, user
log.Errorf("iCache.GetIImageById fail %s", err)
return nil, err
}
err = image.syncWithCloudImage(ctx, userCred, iImage)
err = image.syncWithCloudImage(ctx, userCred, nil, iImage, "")
if err != nil {
log.Errorf("image.syncWithCloudImage fail %s", err)
return nil, err
@@ -549,7 +580,7 @@ func (image *SCachedimage) getValidStoragecache() []SStoragecache {
q = q.Filter(sqlchemy.In(providers.Field("status"), api.CLOUD_PROVIDER_VALID_STATUS))
q = q.Filter(sqlchemy.In(providers.Field("health_status"), api.CLOUD_PROVIDER_VALID_HEALTH_STATUS))
q = q.Filter(sqlchemy.Equals(storagecacheimages.Field("cachedimage_id"), image.Id))
q = q.Filter(sqlchemy.Equals(storagecacheimages.Field("status"), api.CACHED_IMAGE_STATUS_READY))
q = q.Filter(sqlchemy.Equals(storagecacheimages.Field("status"), api.CACHED_IMAGE_STATUS_ACTIVE))
caches := make([]SStoragecache, 0)
err := db.FetchModelObjects(StoragecacheManager, q, &caches)
@@ -589,7 +620,7 @@ func (image *SCachedimage) GetUsableZoneIds() ([]string, error) {
q = q.Filter(sqlchemy.In(providers.Field("status"), api.CLOUD_PROVIDER_VALID_STATUS))
q = q.Filter(sqlchemy.In(providers.Field("health_status"), api.CLOUD_PROVIDER_VALID_HEALTH_STATUS))
q = q.Filter(sqlchemy.Equals(storagecacheimages.Field("cachedimage_id"), image.Id))
q = q.Filter(sqlchemy.Equals(storagecacheimages.Field("status"), api.CACHED_IMAGE_STATUS_READY))
q = q.Filter(sqlchemy.Equals(storagecacheimages.Field("status"), api.CACHED_IMAGE_STATUS_ACTIVE))
q = q.Filter(sqlchemy.Equals(q.Field("status"), api.ZONE_ENABLE))
result := []string{}
@@ -632,6 +663,10 @@ func (manager *SCachedimageManager) ListItemFilter(
query api.CachedimageListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SSharableBaseResourceManager.ListItemFilter(ctx, q, userCred, query.SharableResourceBaseListInput)
if err != nil {
return nil, errors.Wrapf(err, "SSharableBaseResourceManager.ListItemFilter")
}
q, err = managedResourceFilterByAccount(q, query.ManagedResourceListInput, "id", func() *sqlchemy.SQuery {
cachedImages := CachedimageManager.Query().SubQuery()
@@ -647,9 +682,9 @@ func (manager *SCachedimageManager) ListItemFilter(
return nil, errors.Wrap(err, "managedResourceFilterByAccount")
}
q, err = manager.SStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StandaloneResourceListInput)
q, err = manager.SSharableVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query.SharableVirtualResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStandaloneResourceBaseManager.ListItemFilter")
return nil, errors.Wrap(err, "SSharableVirtualResourceBaseManager.ListItemFilter")
}
q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
@@ -667,7 +702,7 @@ func (manager *SCachedimageManager) ListItemFilter(
subq = subq.Join(storageCaches, sqlchemy.Equals(storagecachedImages.Field("storagecache_id"), storageCaches.Field("id")))
subq = subq.Join(storages, sqlchemy.Equals(storageCaches.Field("id"), storages.Field("storagecache_id")))
subq = subq.Join(zones, sqlchemy.Equals(storages.Field("zone_id"), zones.Field("id")))
subq = subq.Filter(sqlchemy.Equals(storagecachedImages.Field("status"), api.CACHED_IMAGE_STATUS_READY))
subq = subq.Filter(sqlchemy.Equals(storagecachedImages.Field("status"), api.CACHED_IMAGE_STATUS_ACTIVE))
return subq
})
if err != nil {
@@ -682,7 +717,7 @@ func (manager *SCachedimageManager) ListItemFilter(
subq := storagecachedImages.Query(storagecachedImages.Field("cachedimage_id"))
subq = subq.Join(storageCaches, sqlchemy.Equals(storagecachedImages.Field("storagecache_id"), storageCaches.Field("id")))
subq = subq.Join(storages, sqlchemy.Equals(storageCaches.Field("id"), storages.Field("storagecache_id")))
subq = subq.Filter(sqlchemy.Equals(storagecachedImages.Field("status"), api.CACHED_IMAGE_STATUS_READY))
subq = subq.Filter(sqlchemy.Equals(storagecachedImages.Field("status"), api.CACHED_IMAGE_STATUS_ACTIVE))
return subq
})
if err != nil {
@@ -704,9 +739,9 @@ func (manager *SCachedimageManager) OrderByExtraFields(
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StandaloneResourceListInput)
q, err = manager.SSharableVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.SharableVirtualResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStandaloneResourceBaseManager.OrderByExtraFields")
return nil, errors.Wrap(err, "SSharableVirtualResourceBaseManager.OrderByExtraFields")
}
return q, nil
@@ -715,10 +750,44 @@ func (manager *SCachedimageManager) OrderByExtraFields(
func (manager *SCachedimageManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
q, err = manager.SSharableVirtualResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SCachedimageManager) ListItemExportKeys(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, keys stringutils2.SSortedStrings) (*sqlchemy.SQuery, error) {
q, err := manager.SSharableVirtualResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrapf(err, "SSharableVirtualResourceBaseManager.L.ListItemExportKeys")
}
return q, nil
}
func (manager *SCachedimageManager) InitializeData() error {
images := []SCachedimage{}
q := manager.Query().IsNullOrEmpty("tenant_id")
err := db.FetchModelObjects(manager, q, &images)
if err != nil {
return errors.Wrapf(err, "db.FetchModelObjects")
}
for i := range images {
_, err := db.Update(&images[i], func() error {
images[i].IsPublic = true
images[i].PublicScope = string(rbacutils.ScopeSystem)
images[i].ProjectId = "system"
if len(images[i].ExternalId) > 0 {
images[i].Status = api.CACHED_IMAGE_STATUS_ACTIVE
} else {
images[i].Status = images[i].GetStatus()
}
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update(%s)", images[i].Id)
}
}
return nil
}

View File

@@ -48,6 +48,7 @@ import (
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/multicloud/esxi"
"yunion.io/x/onecloud/pkg/multicloud/esxi/vcenter"
"yunion.io/x/onecloud/pkg/util/choices"
"yunion.io/x/onecloud/pkg/util/httputils"
@@ -417,9 +418,11 @@ func (scm *SCloudaccountManager) PerformPrepareNets(ctx context.Context, userCre
if err != nil {
return output, errors.Wrap(err, "provider.GetOnPremiseIRegion")
}
hosts, err := iregion.GetIHosts()
// hack
client := iregion.(*esxi.SESXiClient)
hostIps, simpleVms, err := client.HostVmIPs(ctx)
if err != nil {
return output, errors.Wrap(err, "unable to get hosts")
return output, errors.Wrap(err, "unable to fetch ips of hosts and vms")
}
// fetch networks
networks := make([][]SNetwork, len(wires))
@@ -430,20 +433,15 @@ func (scm *SCloudaccountManager) PerformPrepareNets(ctx context.Context, userCre
}
networks[i] = nets
}
// fetch host ips
// key of ipHosts is host's ip
ipHosts := make(map[netutils.IPV4Addr]cloudprovider.ICloudHost, len(hosts))
for i := range hosts {
ip := hosts[i].GetAccessIp()
if len(ip) == 0 {
log.Errorf("unable to get accessip of host %q", hosts[i].GetName())
continue
}
ipHosts := make(map[netutils.IPV4Addr]string, len(hostIps))
for name, ip := range hostIps {
addr, err := netutils.NewIPV4Addr(ip)
if err != nil {
return output, err
}
ipHosts[addr] = hosts[i]
ipHosts[addr] = name
}
// Find suitable wire and the network containing the Host IP in suitable wire.
var (
@@ -490,15 +488,15 @@ func (scm *SCloudaccountManager) PerformPrepareNets(ctx context.Context, userCre
// Give the suggested network configuration for the Host IP that does not have a corresponding suitable network.
noNetHostIP := make([]netutils.IPV4Addr, 0, len(ipHosts))
for hip, host := range ipHosts {
for ip, name := range ipHosts {
rnet := api.CAHostNet{
Name: host.GetName(),
IP: host.GetAccessIp(),
Name: name,
IP: ip.String(),
}
if net, ok := suitableNetworks[hip]; ok {
if net, ok := suitableNetworks[ip]; ok {
rnet.SuitableNetwork = net.GetId()
} else {
noNetHostIP = append(noNetHostIP, hip)
noNetHostIP = append(noNetHostIP, ip)
}
output.Hosts = append(output.Hosts, rnet)
}
@@ -515,7 +513,7 @@ func (scm *SCloudaccountManager) PerformPrepareNets(ctx context.Context, userCre
// Find the suitable network containing the VM IP in Project 'input.Project', and if not, give the corresponding suggested network configuration in this project.
project := input.Project
nets := []*SNetwork{}
excludeNets := []*SNetwork{}
var allNets []SNetwork
if suitableWire != nil {
allNets, err = suitableWire.getNetworks(userCred, rbacutils.ScopeSystem)
@@ -524,85 +522,161 @@ func (scm *SCloudaccountManager) PerformPrepareNets(ctx context.Context, userCre
}
for i := range allNets {
if allNets[i].ProjectId == project {
nets = append(nets, &allNets[i])
excludeNets = append(excludeNets, &allNets[i])
}
}
}
// find suitable network
vms := make([]cloudprovider.ICloudVM, 0, len(hosts))
for _, host := range hosts {
vs, err := host.GetIVMs()
if err != nil {
return output, errors.Wrapf(err, "unable to get VMs of host %q", host.GetName())
}
vms = append(vms, vs...)
type vm struct {
FakeID int
IP netutils.IPV4Addr
Name string
}
ipVMs := make(map[netutils.IPV4Addr]int, len(vms))
for i, vm := range vms {
nics, err := vm.GetINics()
if err != nil {
return output, errors.Wrapf(err, "unable get nics of vm %q", vm.GetName())
}
for _, nic := range nics {
ipStr := nic.GetIP()
if len(ipStr) == 0 {
continue
}
ip, err := netutils.NewIPV4Addr(ipStr)
if err != nil {
return output, errors.Wrapf(err, "unable to new IPV4Addr for ip %q", nic.GetIP())
}
ipVMs[ip] = i
}
output.Guests = append(output.Guests, api.CAGuestNet{
Name: vm.GetName(),
IPNets: make([]api.CAIPNet, 0, 1),
})
}
suitableNetworks = make(map[netutils.IPV4Addr]*SNetwork)
if len(nets) != 0 {
for vip := range ipVMs {
for i := range nets {
ipRange := nets[i].GetIPRange()
if !ipRange.Contains(vip) {
continue
vms := make([]vm, 0, len(simpleVms))
var nip netutils.IPV4Addr
guestMap := make(map[int]*api.CAGuestNet)
for i := range simpleVms {
id := i
if len(simpleVms[i].IPs) == 0 {
if _, ok := guestMap[id]; !ok {
guestMap[id] = &api.CAGuestNet{
Name: simpleVms[i].Name,
IPNets: []api.CAIPNet{},
}
suitableNetworks[vip] = nets[i]
break
}
}
}
noNetVMIPs := make([]netutils.IPV4Addr, 0, len(ipVMs))
for vip, i := range ipVMs {
ipnet := api.CAIPNet{
IP: vip.String(),
for _, ip := range simpleVms[i].IPs {
nip, err = netutils.NewIPV4Addr(ip)
if err != nil {
return output, err
}
vms = append(vms, vm{
FakeID: i,
IP: nip,
Name: simpleVms[i].Name,
})
}
if net, ok := suitableNetworks[vip]; ok {
ipnet.SuitableNetwork = net.GetId()
} else {
noNetVMIPs = append(noNetVMIPs, vip)
}
output.Guests[i].IPNets = append(output.Guests[ipVMs[vip]].IPNets, ipnet)
}
// sort vms via vm's ip
sort.Slice(vms, func(i, j int) bool {
return vms[i].IP < vms[j].IP
})
// excludedIRs is to prevent network conflicts
excludedIRs := make([]netutils.IPV4AddrRange, len(allNets))
for i := range excludedIRs {
excludedIRs[i] = allNets[i].GetIPRange()
excludeNets = make([]*SNetwork, 0, len(allNets)+len(output.HostSuggestedNetworks))
for i := range allNets {
excludeNets = append(excludeNets, &allNets[i])
}
for i := range output.HostSuggestedNetworks {
startIPStr := output.HostSuggestedNetworks[i].GuestIpStart
endIPStr := output.HostSuggestedNetworks[i].GuestIpEnd
startIP, _ := netutils.NewIPV4Addr(startIPStr)
endIP, _ := netutils.NewIPV4Addr(endIPStr)
excludedIRs = append(excludedIRs, netutils.NewIPV4AddrRange(startIP, endIP))
startipStr := output.HostSuggestedNetworks[i].GuestIpStart
endipStr := output.HostSuggestedNetworks[i].GuestIpEnd
excludeNets = append(excludeNets, &SNetwork{GuestIpEnd: endipStr, GuestIpStart: startipStr})
}
if len(noNetVMIPs) > 0 {
sConfs := scm.suggestVMNetwors(noNetVMIPs, excludedIRs)
confs := make([]api.CANetConf, len(sConfs))
// sort excludeNets via their GuestIpStart
sort.Slice(excludeNets, func(i, j int) bool {
return excludeNets[i].GuestIpStart < excludeNets[j].GuestIpStart
})
svNets := make([]netutils.IPV4AddrRange, 0, 5)
var vmi, neti int
lastEndIp := netutils.IPV4Addr(0)
Loop:
for neti = 0; neti < len(excludeNets); {
startIp, _ := netutils.NewIPV4Addr(excludeNets[neti].GuestIpStart)
endIp, _ := netutils.NewIPV4Addr(excludeNets[neti].GuestIpEnd)
switch {
case vms[vmi].IP > endIp:
lastEndIp = endIp
neti++
case vms[vmi].IP >= startIp:
for vms[vmi].IP <= endIp {
id := vms[vmi].FakeID
if _, ok := guestMap[id]; !ok {
guestMap[id] = &api.CAGuestNet{
Name: vms[vmi].Name,
IPNets: []api.CAIPNet{},
}
}
guestMap[id].IPNets = append(guestMap[id].IPNets, api.CAIPNet{
IP: vms[vmi].IP.String(),
SuitableNetwork: excludeNets[neti].Id,
})
vmi += 1
if vmi == len(vms) {
break Loop
}
}
lastEndIp = endIp
neti++
default:
for vms[vmi].IP < startIp {
suggestStartIp := vms[vmi].IP.NetAddr(24) + 1
if suggestStartIp <= lastEndIp {
suggestStartIp = lastEndIp + 1
}
if suggestStartIp >= startIp {
break
}
suggestEndIp := suggestStartIp.NetAddr(24) + 255
if suggestEndIp >= startIp {
suggestEndIp = startIp - 1
}
svNets = append(svNets, netutils.NewIPV4AddrRange(suggestStartIp, suggestEndIp))
for vmi < len(vms) && vms[vmi].IP <= suggestEndIp {
id := vms[vmi].FakeID
if _, ok := guestMap[id]; !ok {
guestMap[id] = &api.CAGuestNet{
Name: vms[vmi].Name,
IPNets: []api.CAIPNet{},
}
}
guestMap[id].IPNets = append(guestMap[id].IPNets, api.CAIPNet{
IP: vms[vmi].IP.String(),
})
vmi++
}
if vmi == len(vms) {
break Loop
}
}
}
}
for vmi < len(vms) {
suggestStartIp := vms[vmi].IP.NetAddr(24) + 1
if suggestStartIp <= lastEndIp {
suggestStartIp = lastEndIp + 1
}
suggestEndIp := suggestStartIp.NetAddr(24) + 255
svNets = append(svNets, netutils.NewIPV4AddrRange(suggestStartIp, suggestEndIp))
for vmi < len(vms) && vms[vmi].IP <= suggestEndIp {
id := vms[vmi].FakeID
if _, ok := guestMap[id]; !ok {
guestMap[id] = &api.CAGuestNet{
Name: vms[vmi].Name,
IPNets: []api.CAIPNet{},
}
}
guestMap[id].IPNets = append(guestMap[id].IPNets, api.CAIPNet{
IP: vms[vmi].IP.String(),
})
vmi++
}
}
for _, guest := range guestMap {
output.Guests = append(output.Guests, *guest)
}
if len(svNets) > 0 {
confs := make([]api.CANetConf, len(svNets))
for i := range confs {
confs[i].CASimpleNetConf = sConfs[i]
confs[i].CASimpleNetConf = api.CASimpleNetConf{
GuestIpStart: svNets[i].StartIp().String(),
GuestIpEnd: svNets[i].EndIp().String(),
GuestIpMask: 24,
GuestGateway: (svNets[i].StartIp().NetAddr(24) + 1).String(),
}
confs[i].Name = fmt.Sprintf("%s-guest-network-%d", input.Name, i+1)
}
output.GuestSuggestedNetworks = confs
@@ -650,15 +724,19 @@ func (manager *SCloudaccountManager) fetchEsxiZoneIds() ([]string, error) {
// The suggested network mask is 24 and the gateway is x.x.x.1.
// The suggests network is the smallest network segment that meets the above conditions.
func (manager *SCloudaccountManager) suggestHostNetworks(ips []netutils.IPV4Addr) []api.CASimpleNetConf {
if len(ips) == 0 {
return nil
}
sort.Slice(ips, func(i, j int) bool {
return ips[i] < ips[j]
})
var (
mask int8 = 24
consequent []netutils.IPV4Addr
ret []api.CASimpleNetConf
mask int8 = 24
lastnetAddr netutils.IPV4Addr
consequent []netutils.IPV4Addr
ret []api.CASimpleNetConf
)
lastnetAddr, _ := netutils.NewIPV4Addr("0.0.0.0")
lastnetAddr = ips[0].NetAddr(mask)
consequent = []netutils.IPV4Addr{ips[0]}
for i := 1; i < len(ips); i++ {
ip := ips[i]

View File

@@ -71,6 +71,21 @@ func TestSCloudaccount_suggestHostNetworks(t *testing.T) {
},
},
},
{
[]string{
"10.155.50.103",
"10.155.50.101",
"10.155.50.102",
},
[]api.CASimpleNetConf{
{
GuestIpStart: "10.155.50.101",
GuestIpEnd: "10.155.50.103",
GuestIpMask: 24,
GuestGateway: "10.155.50.1",
},
},
},
}
for _, c := range cases {
ins := make([]netutils.IPV4Addr, len(c.in))

View File

@@ -1394,8 +1394,7 @@ func (self *SCloudprovider) StartCloudproviderDeleteTask(ctx context.Context, us
params := jsonutils.NewDict()
task, err := taskman.TaskManager.NewTask(ctx, "CloudProviderDeleteTask", self, userCred, params, parentTaskId, "", nil)
if err != nil {
log.Errorf("%s", err)
return err
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.CLOUD_PROVIDER_START_DELETE, "StartCloudproviderDeleteTask")
task.ScheduleRun(nil)

View File

@@ -1229,7 +1229,7 @@ func SyncCloudProject(userCred mcclient.TokenCredential, model db.IVirtualModel,
extProject, err := ExternalProjectManager.GetProject(extProjectId, managerId)
if err != nil {
log.Errorf("sync project for %s %s error: %v", model.Keyword(), model.GetName(), err)
} else {
} else if len(extProject.ProjectId) > 0 {
newOwnerId = extProject.GetOwnerId()
}
}

View File

@@ -1299,6 +1299,13 @@ func (manager *SDBInstanceManager) SyncDBInstances(ctx context.Context, userCred
return nil, nil, syncResult
}
for i := range dbInstances {
if taskman.TaskManager.IsInTask(&dbInstances[i]) {
syncResult.Error(fmt.Errorf("dbInstance %s(%s)in task", dbInstances[i].Name, dbInstances[i].Id))
return nil, nil, syncResult
}
}
removed := make([]SDBInstance, 0)
commondb := make([]SDBInstance, 0)
commonext := make([]cloudprovider.ICloudDBInstance, 0)

View File

@@ -1079,15 +1079,15 @@ func (self *SDisk) validateDeleteCondition(ctx context.Context, isPurge bool) er
}
host := storage.GetMasterHost()
if host == nil {
return httperrors.NewBadRequestError("storage of disk no valid host")
return httperrors.NewBadRequestError("storage of disk %s no valid host", self.Id)
}
}
cnt, err := self.GetGuestDiskCount()
if err != nil {
return httperrors.NewInternalServerError("GetGuestDiskCount fail %s", err)
return httperrors.NewInternalServerError("GetGuestDiskCount for disk %s fail %s", self.Id, err)
}
if cnt > 0 {
return httperrors.NewNotEmptyError("Virtual disk used by virtual servers")
return httperrors.NewNotEmptyError("Virtual disk %s(%s) used by virtual servers", self.Name, self.Id)
}
if !isPurge && self.IsValidPrePaid() {
return httperrors.NewForbiddenError("not allow to delete prepaid disk in valid status")

View File

@@ -337,11 +337,26 @@ func (man *SDnsRecordManager) ValidateCreateData(
query jsonutils.JSONObject,
data *jsonutils.JSONDict,
) (*jsonutils.JSONDict, error) {
_, err := man.validateModelData(ctx, data, true)
var err error
input := apis.AdminSharableVirtualResourceBaseCreateInput{}
err = data.Unmarshal(&input)
if err != nil {
return nil, errors.Wrap(err, "Unmarshal AdminSharableVirtualResourceBaseCreateInput")
}
input, err = man.SAdminSharableVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input)
if err != nil {
return nil, errors.Wrap(err, "SAdminSharableVirtualResourceBaseManager.ValidateCreateData")
}
data.Update(jsonutils.Marshal(input))
_, err = man.validateModelData(ctx, data, true)
if err != nil {
return nil, err
}
return man.SAdminSharableVirtualResourceBaseManager.ValidateCreateData(man, data)
return man.SAdminSharableVirtualResourceBaseManager.ValidateRecordsData(man, data)
}
func (man *SDnsRecordManager) QueryDns(projectId, name string) *SDnsRecord {

View File

@@ -452,6 +452,13 @@ func (manager *SElasticcacheManager) SyncElasticcaches(ctx context.Context, user
return nil, nil, syncResult
}
for i := range dbInstances {
if taskman.TaskManager.IsInTask(&dbInstances[i]) {
syncResult.Error(fmt.Errorf("ElasticCacheInstance %s(%s)in task", dbInstances[i].Name, dbInstances[i].Id))
return nil, nil, syncResult
}
}
removed := make([]SElasticcache, 0)
commondb := make([]SElasticcache, 0)
commonext := make([]cloudprovider.ICloudElasticcache, 0)

View File

@@ -426,8 +426,11 @@ func (self *SElasticip) SyncInstanceWithCloudEip(ctx context.Context, userCred m
case api.EIP_ASSOCIATE_TYPE_SERVER:
sq := HostManager.Query().SubQuery()
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("host_id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), self.ManagerId))
case api.EIP_ASSOCIATE_TYPE_NAT_GATEWAY, api.EIP_ASSOCIATE_TYPE_LOADBALANCER:
case api.EIP_ASSOCIATE_TYPE_LOADBALANCER:
return q.Equals("manager_id", self.ManagerId)
case api.EIP_ASSOCIATE_TYPE_NAT_GATEWAY:
sq := VpcManager.Query("id").Equals("manager_id", self.ManagerId)
return q.In("vpc_id", sq.SubQuery())
}
return q
})
@@ -1266,6 +1269,7 @@ func (manager *SElasticipManager) NewEipForVMOnHost(ctx context.Context, userCre
wireq := WireManager.Query().SubQuery()
hostwireq := HostwireManager.Query().SubQuery()
q := NetworkManager.Query()
q = NetworkManager.FilterByOwner(q, userCred, NetworkManager.NamespaceScope())
q = q.Join(wireq, sqlchemy.Equals(wireq.Field("id"), q.Field("wire_id")))
q = q.Join(hostwireq, sqlchemy.Equals(hostwireq.Field("wire_id"), wireq.Field("id")))
q = q.Join(hostq, sqlchemy.Equals(hostq.Field("id"), host.Id))

View File

@@ -89,7 +89,7 @@ func (self *SGuest) PreCheckPerformAction(
) error {
if self.Hypervisor == api.HYPERVISOR_KVM {
host := self.GetHost()
if (host.HostStatus == api.HOST_OFFLINE || !host.Enabled.Bool()) &&
if host != nil && (host.HostStatus == api.HOST_OFFLINE || !host.Enabled.Bool()) &&
utils.IsInStringArray(action,
[]string{
"start", "restart", "stop", "reset", "rebuild-root",
@@ -3635,9 +3635,11 @@ func (self *SGuest) SaveRenewInfo(
guestdisks := self.GetDisks()
for i := 0; i < len(guestdisks); i += 1 {
disk := guestdisks[i].GetDisk()
err = disk.SaveRenewInfo(ctx, userCred, bc, expireAt, billingType)
if err != nil {
return err
if disk.AutoDelete {
err = disk.SaveRenewInfo(ctx, userCred, bc, expireAt, billingType)
if err != nil {
return err
}
}
}
return nil

View File

@@ -142,6 +142,8 @@ type IGuestDriver interface {
IsRebuildRootSupportChangeImage() bool
IsRebuildRootSupportChangeUEFI() bool
IsSupportdDcryptPasswordFromSecretKey() bool
RequestDeleteDetachedDisk(ctx context.Context, disk *SDisk, task taskman.ITask, isPurge bool) error
StartGuestDetachdiskTask(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, params *jsonutils.JSONDict, parentTaskId string) error
StartGuestAttachDiskTask(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, params *jsonutils.JSONDict, parentTaskId string) error

View File

@@ -644,6 +644,8 @@ func totalGuestNicCount(
q = q.Join(guests, sqlchemy.Equals(guests.Field("id"), guestnics.Field("guest_id")))
q = q.Join(hosts, sqlchemy.Equals(guests.Field("host_id"), hosts.Field("id")))
q = q.Filter(sqlchemy.IsFalse(guests.Field("pending_deleted")))
q = CloudProviderFilter(q, hosts.Field("manager_id"), providers, brands, cloudEnv)
q = RangeObjectsFilter(q, rangeObjs, nil, hosts.Field("zone_id"), hosts.Field("manager_id"), hosts.Field("id"), nil)

View File

@@ -2773,7 +2773,7 @@ func getCloudNicNetwork(ctx context.Context, vnic cloudprovider.ICloudNic, host
if vnet == nil {
if vnic.InClassicNetwork() {
region := host.GetRegion()
cloudprovider := region.GetCloudprovider()
cloudprovider := host.GetCloudprovider()
vpc, err := VpcManager.GetOrCreateVpcForClassicNetwork(ctx, cloudprovider, region)
if err != nil {
return nil, errors.Wrap(err, "NewVpcForClassicNetwork")
@@ -3631,7 +3631,7 @@ func (self *SGuest) DeleteAllDisksInDB(ctx context.Context, userCred mcclient.To
disk := guestdisk.GetDisk()
err := guestdisk.Detach(ctx, userCred)
if err != nil {
return err
return errors.Wrapf(err, "guestdisk.Detach guest_id: %s disk_id: %s", guestdisk.GuestId, guestdisk.DiskId)
}
if disk != nil {
@@ -4234,6 +4234,14 @@ func (self *SGuest) GetShortDesc(ctx context.Context) *jsonutils.JSONDict {
billingInfo.SCloudProviderInfo = host.getCloudProviderInfo()
}
if len(self.BackupHostId) > 0 {
backupHost := HostManager.FetchHostById(self.BackupHostId)
if backupHost != nil {
desc.Set("backup_host", jsonutils.NewString(backupHost.Name))
desc.Set("backup_host_id", jsonutils.NewString(backupHost.Id))
}
}
if priceKey := self.GetMetadata("ext:price_key", nil); len(priceKey) > 0 {
billingInfo.PriceKey = priceKey
}
@@ -4257,40 +4265,49 @@ func (self *SGuest) saveOsType(userCred mcclient.TokenCredential, osType string)
return err
}
type sDeployInfo struct {
Os string
Account string
Key string
Distro string
Version string
Arch string
Language string
}
func (self *SGuest) SaveDeployInfo(ctx context.Context, userCred mcclient.TokenCredential, data jsonutils.JSONObject) {
deployInfo := sDeployInfo{}
data.Unmarshal(&deployInfo)
info := make(map[string]interface{})
if data.Contains("os") {
osName, _ := data.GetString("os")
self.saveOsType(userCred, osName)
info["os_name"] = osName
if len(deployInfo.Os) > 0 {
self.saveOsType(userCred, deployInfo.Os)
info["os_name"] = deployInfo.Os
}
if data.Contains("account") {
account, _ := data.GetString("account")
info["login_account"] = account
if data.Contains("key") {
key, _ := data.GetString("key")
info["login_key"] = key
driver := self.GetDriver()
if len(deployInfo.Account) > 0 {
info["login_account"] = deployInfo.Account
if len(deployInfo.Key) > 0 {
info["login_key"] = deployInfo.Key
if len(self.KeypairId) > 0 && !driver.IsSupportdDcryptPasswordFromSecretKey() { // Tencent Cloud does not support simultaneous setting of secret keys and passwords
info["login_key"], _ = seclib2.EncryptBase64(self.GetKeypairPublicKey(), "")
}
info["login_key_timestamp"] = timeutils.UtcNow()
} else {
info["login_key"] = "none"
info["login_key_timestamp"] = "none"
}
}
if data.Contains("distro") {
dist, _ := data.GetString("distro")
info["os_distribution"] = dist
if len(deployInfo.Distro) > 0 {
info["os_distribution"] = deployInfo.Distro
}
if data.Contains("version") {
ver, _ := data.GetString("version")
info["os_version"] = ver
if len(deployInfo.Version) > 0 {
info["os_version"] = deployInfo.Version
}
if data.Contains("arch") {
arch, _ := data.GetString("arch")
info["os_arch"] = arch
if len(deployInfo.Arch) > 0 {
info["os_arch"] = deployInfo.Arch
}
if data.Contains("language") {
lang, _ := data.GetString("language")
info["os_language"] = lang
if len(deployInfo.Language) > 0 {
info["os_language"] = deployInfo.Language
}
self.SetAllMetadata(ctx, info, userCred)
self.saveOldPassword(ctx, userCred)

View File

@@ -674,7 +674,7 @@ func (self *SHost) RealDelete(ctx context.Context, userCred mcclient.TokenCreden
if storage != nil && storage.IsLocal() {
cnt, err := storage.GetDiskCount()
if err != nil {
return err
return errors.Wrapf(err, "GetDiskCount")
}
if cnt > 0 {
return httperrors.NewNotEmptyError("Inconsistent: local storage is not empty???")
@@ -1418,6 +1418,17 @@ func (self *SHost) GetGuests() []SGuest {
return guests
}
func (self *SHost) GetKvmGuests() []SGuest {
q := GuestManager.Query().Equals("host_id", self.Id).Equals("hypervisor", api.HYPERVISOR_KVM)
guests := make([]SGuest, 0)
err := db.FetchModelObjects(GuestManager, q, &guests)
if err != nil {
log.Errorf("GetGuests %s", err)
return nil
}
return guests
}
func (self *SHost) GetGuestsMasterOnThisHost() []SGuest {
q := self.GetGuestsQuery().IsNotEmpty("backup_host_id")
guests := make([]SGuest, 0)
@@ -3519,6 +3530,9 @@ func (self *SHost) PerformOffline(ctx context.Context, userCred mcclient.TokenCr
if jsonutils.QueryBoolean(data, "update_health_status", false) {
self.EnableHealthCheck = false
}
// Note: update host status to unknown on host offline
// we did not have host status after host offline
self.Status = api.BAREMETAL_UNKNOWN
return nil
})
if err != nil {
@@ -4612,7 +4626,15 @@ func (host *SHost) SyncHostExternalNics(ctx context.Context, userCred mcclient.T
enables = append(enables, extNics[i])
}
} else {
// do nothing, in sync
// in sync, sync interface and bridge
hw := host.getHostwireOfIdAndMac(netIfs[i].WireId, netIfs[i].Mac)
if hw != nil && (hw.Bridge != extNics[i].GetBridge() || hw.Interface != extNics[i].GetDevice()) {
db.Update(hw, func() error {
hw.Interface = extNics[i].GetDevice()
hw.Bridge = extNics[i].GetBridge()
return nil
})
}
}
} else {
reserveIp := false
@@ -4663,7 +4685,7 @@ func (host *SHost) SyncHostExternalNics(ctx context.Context, userCred mcclient.T
// always try reserved pool
extNic := adds[i].netif
err = host.addNetif(ctx, userCred, extNic.GetMac(), "", extNic.GetIpAddr(), 0, extNic.GetNicType(), extNic.GetIndex(),
extNic.IsLinkUp(), int16(extNic.GetMtu()), false, "", "", true, true)
extNic.IsLinkUp(), int16(extNic.GetMtu()), false, extNic.GetDevice(), extNic.GetBridge(), true, true)
if err != nil {
result.AddError(err)
} else {
@@ -4896,7 +4918,7 @@ func (host *SHost) PerformHostMaintenance(ctx context.Context, userCred mcclient
preferHostId = host.Id
}
guests := host.GetGuests()
guests := host.GetKvmGuests()
for i := 0; i < len(guests); i++ {
lockman.LockObject(ctx, &guests[i])
defer lockman.ReleaseObject(ctx, &guests[i])
@@ -5428,3 +5450,15 @@ func (manager *SHostManager) ListItemExportKeys(ctx context.Context,
}
return q, nil
}
func (manager *SHostManager) FetchHostByExtId(extid string) *SHost {
host := SHost{}
host.SetModelManager(manager, &host)
err := manager.Query().Equals("external_id", extid).First(&host)
if err != nil {
log.Errorf("fetchHostByExtId fail %s", err)
return nil
} else {
return &host
}
}

View File

@@ -60,6 +60,8 @@ func InitDB() error {
ScheduledTaskActivityManager,
ExternalProjectManager,
CachedimageManager,
StoragecachedimageManager,
} {
err := manager.InitializeData()
if err != nil {

View File

@@ -285,6 +285,8 @@ func totalLBNicCount(
lbnics := LoadbalancernetworkManager.Query().SubQuery()
q := lbnics.Query()
q = q.Join(lbs, sqlchemy.Equals(lbs.Field("id"), lbnics.Field("loadbalancer_id")))
q = q.Filter(sqlchemy.IsFalse(lbs.Field("pending_deleted")))
switch scope {
case rbacutils.ScopeSystem:
// do nothing

View File

@@ -732,6 +732,13 @@ func (man *SLoadbalancerManager) SyncLoadbalancers(ctx context.Context, userCred
return nil, nil, syncResult
}
for i := range dbLbs {
if taskman.TaskManager.IsInTask(&dbLbs[i]) {
syncResult.Error(fmt.Errorf("loadbalancer %s(%s)in task", dbLbs[i].Name, dbLbs[i].Id))
return nil, nil, syncResult
}
}
removed := []SLoadbalancer{}
commondb := []SLoadbalancer{}
commonext := []cloudprovider.ICloudLoadbalancer{}

View File

@@ -1,4 +1,3 @@
// 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.
@@ -354,7 +353,7 @@ func (manager *SNetworkManager) GetOrCreateClassicNetwork(ctx context.Context, w
func (self *SNetwork) GetUsedAddresses() map[string]bool {
used := make(map[string]bool)
q := self.getUsedAddressQuery(true)
q := self.getUsedAddressQuery(nil, rbacutils.ScopeSystem, true)
results, err := q.AllStringMap()
if err != nil {
log.Errorf("GetUsedAddresses fail %s", err)
@@ -780,7 +779,7 @@ func (self *SNetwork) IsAddressInRange(address netutils.IPV4Addr) bool {
}
func (self *SNetwork) isAddressUsed(address string) (bool, error) {
q := self.getUsedAddressQuery(true)
q := self.getUsedAddressQuery(nil, rbacutils.ScopeSystem, true)
q = q.Equals("ip_addr", address)
count, err := q.CountWithError()
if err != nil && errors.Cause(err) != sql.ErrNoRows {
@@ -829,16 +828,17 @@ func (manager *SNetworkManager) GetOnPremiseNetworkOfIP(ipAddr string, serverTyp
func (manager *SNetworkManager) allNetworksQ(providers []string, brands []string, cloudEnv string, rangeObjs []db.IStandaloneModel) *sqlchemy.SQuery {
networks := manager.Query().SubQuery()
hostwires := HostwireManager.Query().SubQuery()
hosts := HostManager.Query().SubQuery()
wires := WireManager.Query().SubQuery()
vpcs := VpcManager.Query().SubQuery()
q := networks.Query(networks.Field("id"))
q = q.Join(hostwires, sqlchemy.Equals(hostwires.Field("wire_id"), networks.Field("wire_id")))
q = q.Join(hosts, sqlchemy.Equals(hosts.Field("id"), hostwires.Field("host_id")))
q = q.Filter(sqlchemy.IsTrue(hosts.Field("enabled")))
q = q.Filter(sqlchemy.OR(
sqlchemy.Equals(hosts.Field("host_type"), api.HOST_TYPE_BAREMETAL),
sqlchemy.Equals(hosts.Field("host_status"), api.HOST_ONLINE)))
return AttachUsageQuery(q, hosts, nil, nil, providers, brands, cloudEnv, rangeObjs)
q = q.Join(wires, sqlchemy.Equals(q.Field("wire_id"), wires.Field("id")))
q = q.Join(vpcs, sqlchemy.Equals(wires.Field("vpc_id"), vpcs.Field("id")))
q = CloudProviderFilter(q, vpcs.Field("manager_id"), providers, brands, cloudEnv)
q = RangeObjectsFilter(q, rangeObjs, vpcs.Field("cloudregion_id"), wires.Field("zone_id"), vpcs.Field("manager_id"), nil, nil)
return q
}
func (manager *SNetworkManager) totalPortCountQ(
@@ -2425,7 +2425,7 @@ func (network *SNetwork) AllowGetDetailsAddresses(ctx context.Context, userCred
return network.IsOwner(userCred) || db.IsAdminAllowGetSpec(userCred, network, "addresses")
}
func (network *SNetwork) getUsedAddressQuery(addrOnly bool) *sqlchemy.SQuery {
func (network *SNetwork) getUsedAddressQuery(owner mcclient.IIdentityProvider, scope rbacutils.TRbacScope, addrOnly bool) *sqlchemy.SQuery {
guestnetworks := GuestnetworkManager.Query().Equals("network_id", network.Id).SubQuery()
var guestNetQ *sqlchemy.SQuery
if addrOnly {
@@ -2433,17 +2433,17 @@ func (network *SNetwork) getUsedAddressQuery(addrOnly bool) *sqlchemy.SQuery {
guestnetworks.Field("ip_addr"),
)
} else {
guests := GuestManager.Query().SubQuery()
guests := GuestManager.FilterByOwner(GuestManager.Query(), owner, scope).SubQuery()
guestNetQ = guestnetworks.Query(
guestnetworks.Field("ip_addr"),
guestnetworks.Field("mac_addr"),
sqlchemy.NewStringField(GuestManager.KeywordPlural()).Label("owner_type"),
guestnetworks.Field("guest_id").Label("owner_id"),
guests.Field("id").Label("owner_id"),
guests.Field("name").Label("owner"),
sqlchemy.NewStringField("").Label("associate_id"),
sqlchemy.NewStringField("").Label("associate_type"),
guestnetworks.Field("created_at"),
).Join(
).LeftJoin(
guests,
sqlchemy.Equals(
guests.Field("id"),
@@ -2459,17 +2459,17 @@ func (network *SNetwork) getUsedAddressQuery(addrOnly bool) *sqlchemy.SQuery {
groupnetworks.Field("ip_addr"),
)
} else {
groups := GroupManager.Query().SubQuery()
groups := GroupManager.FilterByOwner(GroupManager.Query(), owner, scope).SubQuery()
groupNetQ = groupnetworks.Query(
groupnetworks.Field("ip_addr"),
sqlchemy.NewStringField("").Label("mac_addr"),
sqlchemy.NewStringField(GroupManager.KeywordPlural()).Label("owner_type"),
groupnetworks.Field("group_id").Label("owner_id"),
groups.Field("id").Label("owner_id"),
groups.Field("name").Label("owner"),
sqlchemy.NewStringField("").Label("associate_id"),
sqlchemy.NewStringField("").Label("associate_type"),
groupnetworks.Field("created_at"),
).Join(
).LeftJoin(
groups,
sqlchemy.Equals(
groups.Field("id"),
@@ -2485,17 +2485,17 @@ func (network *SNetwork) getUsedAddressQuery(addrOnly bool) *sqlchemy.SQuery {
hostnetworks.Field("ip_addr"),
)
} else {
hosts := HostManager.Query().SubQuery()
hosts := HostManager.FilterByOwner(HostManager.Query(), owner, scope).SubQuery()
hostNetQ = hostnetworks.Query(
hostnetworks.Field("ip_addr"),
hostnetworks.Field("mac_addr"),
sqlchemy.NewStringField(HostManager.KeywordPlural()).Label("owner_type"),
hostnetworks.Field("baremetal_id").Label("owner_id"),
hosts.Field("id").Label("owner_id"),
hosts.Field("name").Label("owner"),
sqlchemy.NewStringField("").Label("associate_id"),
sqlchemy.NewStringField("").Label("associate_type"),
hostnetworks.Field("created_at"),
).Join(
).LeftJoin(
hosts,
sqlchemy.Equals(
hosts.Field("id"),
@@ -2534,17 +2534,17 @@ func (network *SNetwork) getUsedAddressQuery(addrOnly bool) *sqlchemy.SQuery {
lbnetworks.Field("ip_addr"),
)
} else {
loadbalancers := LoadbalancerManager.Query().SubQuery()
loadbalancers := LoadbalancerManager.FilterByOwner(LoadbalancerManager.Query(), owner, scope).SubQuery()
lbNetQ = lbnetworks.Query(
lbnetworks.Field("ip_addr"),
sqlchemy.NewStringField("").Label("mac_addr"),
sqlchemy.NewStringField(LoadbalancerManager.KeywordPlural()).Label("owner_type"),
lbnetworks.Field("loadbalancer_id").Label("owner_id"),
loadbalancers.Field("id").Label("owner_id"),
loadbalancers.Field("name").Label("owner"),
sqlchemy.NewStringField("").Label("associate_id"),
sqlchemy.NewStringField("").Label("associate_type"),
lbnetworks.Field("created_at"),
).Join(
).LeftJoin(
loadbalancers,
sqlchemy.Equals(
loadbalancers.Field("id"),
@@ -2554,6 +2554,7 @@ func (network *SNetwork) getUsedAddressQuery(addrOnly bool) *sqlchemy.SQuery {
}
elasticips := ElasticipManager.Query().Equals("network_id", network.Id).SubQuery()
ownerEips := ElasticipManager.FilterByOwner(ElasticipManager.Query().Equals("network_id", network.Id), owner, scope).SubQuery()
var eipQ *sqlchemy.SQuery
if addrOnly {
eipQ = elasticips.Query(
@@ -2564,11 +2565,17 @@ func (network *SNetwork) getUsedAddressQuery(addrOnly bool) *sqlchemy.SQuery {
elasticips.Field("ip_addr"),
sqlchemy.NewStringField("").Label("mac_addr"),
sqlchemy.NewStringField(ElasticipManager.KeywordPlural()).Label("owner_type"),
elasticips.Field("id").Label("owner_id"),
elasticips.Field("name").Label("owner"),
elasticips.Field("associate_id"),
elasticips.Field("associate_type"),
ownerEips.Field("id").Label("owner_id"),
ownerEips.Field("name").Label("owner"),
ownerEips.Field("associate_id"),
ownerEips.Field("associate_type"),
elasticips.Field("created_at"),
).LeftJoin(
ownerEips,
sqlchemy.Equals(
elasticips.Field("id"),
ownerEips.Field("id"),
),
)
}
@@ -2579,17 +2586,17 @@ func (network *SNetwork) getUsedAddressQuery(addrOnly bool) *sqlchemy.SQuery {
netifnetworks.Field("ip_addr"),
)
} else {
netifs := NetworkInterfaceManager.Query().SubQuery()
netifs := NetworkInterfaceManager.FilterByOwner(NetworkInterfaceManager.Query(), owner, scope).SubQuery()
netifsQ = netifnetworks.Query(
netifnetworks.Field("ip_addr"),
netifs.Field("mac").Label("mac_addr"),
sqlchemy.NewStringField(NetworkInterfaceManager.KeywordPlural()).Label("owner_type"),
netifnetworks.Field("networkinterface_id").Label("owner_id"),
netifs.Field("id").Label("owner_id"),
netifs.Field("name").Label("owner"),
netifs.Field("associate_id"),
netifs.Field("associate_type"),
netifnetworks.Field("created_at"),
).Join(
).LeftJoin(
netifs,
sqlchemy.Equals(
netifnetworks.Field("networkinterface_id"),
@@ -2598,7 +2605,33 @@ func (network *SNetwork) getUsedAddressQuery(addrOnly bool) *sqlchemy.SQuery {
)
}
return sqlchemy.Union(guestNetQ, groupNetQ, hostNetQ, reservedQ, lbNetQ, eipQ, netifsQ).Query()
dbnetworks := DBInstanceNetworkManager.Query().Equals("network_id", network.Id).SubQuery()
var dbNetQ *sqlchemy.SQuery
if addrOnly {
dbNetQ = dbnetworks.Query(
dbnetworks.Field("ip_addr"),
)
} else {
dbinstances := DBInstanceManager.FilterByOwner(DBInstanceManager.Query(), owner, scope).SubQuery()
dbNetQ = dbnetworks.Query(
dbnetworks.Field("ip_addr"),
sqlchemy.NewStringField("").Label("mac_addr"),
sqlchemy.NewStringField(DBInstanceManager.KeywordPlural()).Label("owner_type"),
dbinstances.Field("id").Label("owner_id"),
dbinstances.Field("name").Label("owner"),
sqlchemy.NewStringField("").Label("associate_id"),
sqlchemy.NewStringField("").Label("associate_type"),
dbnetworks.Field("created_at"),
).LeftJoin(
dbinstances,
sqlchemy.Equals(
dbinstances.Field("id"),
dbnetworks.Field("dbinstance_id"),
),
)
}
return sqlchemy.Union(guestNetQ, groupNetQ, hostNetQ, reservedQ, lbNetQ, eipQ, netifsQ, dbNetQ).Query()
}
type SNetworkAddressList []api.SNetworkAddress
@@ -2611,20 +2644,26 @@ func (a SNetworkAddressList) Less(i, j int) bool {
return ipI < ipJ
}
func (network *SNetwork) GetDetailsAddresses(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
func (network *SNetwork) GetDetailsAddresses(ctx context.Context, userCred mcclient.TokenCredential, input api.GetNetworkAddressesInput) (api.GetNetworkAddressesOutput, error) {
output := api.GetNetworkAddressesOutput{}
allowScope := policy.PolicyManager.AllowScope(userCred, api.SERVICE_TYPE, network.KeywordPlural(), policy.PolicyActionGet, "addresses")
scope := rbacutils.String2ScopeDefault(input.Scope, allowScope)
if scope.HigherThan(allowScope) {
return output, errors.Wrapf(httperrors.ErrNotSufficientPrivilege, "require %s allow %s", scope, allowScope)
}
netAddrs := make([]api.SNetworkAddress, 0)
q := network.getUsedAddressQuery(false)
q := network.getUsedAddressQuery(userCred, scope, false)
err := q.All(&netAddrs)
if err != nil {
return nil, httperrors.NewGeneralError(err)
return output, httperrors.NewGeneralError(err)
}
sort.Sort(SNetworkAddressList(netAddrs))
result := jsonutils.NewDict()
result.Add(jsonutils.Marshal(netAddrs), "addresses")
return result, nil
output.Addresses = netAddrs
return output, nil
}
func (net *SNetwork) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {

View File

@@ -82,14 +82,14 @@ func (host *SHost) purge(ctx context.Context, userCred mcclient.TokenCredential)
_, err := host.PerformDisable(ctx, userCred, nil, apis.PerformDisableInput{})
if err != nil {
return err
return errors.Wrapf(err, "PerformDisable")
}
guests := host.GetGuests()
for i := range guests {
err := guests[i].purge(ctx, userCred)
if err != nil {
return err
return errors.Wrapf(err, "purge guest %s", guests[i].Id)
}
}
@@ -98,7 +98,7 @@ func (host *SHost) purge(ctx context.Context, userCred mcclient.TokenCredential)
for i := range storages {
err := storages[i].purgeDisks(ctx, userCred)
if err != nil {
return err
return errors.Wrapf(err, "purgeDisks for storage %s", storages[i].Name)
}
}
@@ -139,7 +139,7 @@ func (storage *SStorage) purgeDisks(ctx context.Context, userCred mcclient.Token
for i := range disks {
err := disks[i].purge(ctx, userCred)
if err != nil {
return err
return errors.Wrapf(err, "purge disk %s", disks[i].Id)
}
}
return nil

View File

@@ -171,10 +171,13 @@ func (st *SScalingTimer) ValidateCreateData(input api.ScalingPolicyCreateInput)
var err error
if input.TriggerType == api.TRIGGER_TIMING {
input.Timer, err = checkTimerCreateInput(input.Timer)
return input, err
} else {
input.CycleTimer, err = checkCycleTimerCreateInput(input.CycleTimer)
}
input.CycleTimer, err = checkCycleTimerCreateInput(input.CycleTimer)
return input, err
if err != nil {
return input, httperrors.NewInputParameterError(err.Error())
}
return input, nil
}
func (st *SScalingTimer) Register(ctx context.Context, userCred mcclient.TokenCredential) error {

View File

@@ -178,7 +178,10 @@ func (stm *SScheduledTaskManager) ValidateCreateData(ctx context.Context, userCr
} else {
input.CycleTimer, err = checkCycleTimerCreateInput(input.CycleTimer)
}
return input, err
if err != nil {
return input, httperrors.NewInputParameterError(err.Error())
}
return input, nil
}
var wdsCN = []string{"", "一", "二", "三", "四", "五", "六", "日"}

View File

@@ -355,6 +355,39 @@ func (self *SSecurityGroupCache) GetSecgroup() (*SSecurityGroup, error) {
return model.(*SSecurityGroup), nil
}
func (self *SSecurityGroupCache) syncWithCloudSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudSecurityGroup) error {
_, err := db.Update(self, func() error {
self.Status = api.SECGROUP_CACHE_STATUS_READY
self.Name = ext.GetName()
self.Description = ext.GetDescription()
self.ExternalProjectId = ext.GetProjectId()
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update")
}
secgroup, err := self.GetSecgroup()
if err != nil {
return errors.Wrapf(err, "GetSecurity")
}
cacheCount, err := secgroup.GetSecgroupCacheCount()
if err != nil {
return errors.Wrapf(err, "GetSecgroupCacheCount")
}
if cacheCount > 1 {
return nil
}
info, err := SecurityGroupManager.getRuleInfo(provider, ext)
if err != nil {
return errors.Wrapf(err, "getRuleInfo")
}
err = secgroup.SyncSecurityGroupRules(ctx, userCred, info)
if err != nil {
return errors.Wrapf(err, "SyncSecurityGroupRules")
}
return nil
}
func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, secgroups []cloudprovider.ICloudSecurityGroup, vpc *SVpc) ([]SSecurityGroup, []cloudprovider.ICloudSecurityGroup, compare.SyncResult) {
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
@@ -415,25 +448,18 @@ func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(ctx context.C
}
for i := 0; i < len(commondb); i++ {
_, err = db.Update(&commondb[i], func() error {
commondb[i].Status = api.SECGROUP_CACHE_STATUS_READY
commondb[i].Name = commonext[i].GetName()
commondb[i].Description = commonext[i].GetDescription()
commondb[i].ExternalProjectId = commonext[i].GetProjectId()
return nil
})
err = commondb[i].syncWithCloudSecurityGroup(ctx, userCred, provider, commonext[i])
if err != nil {
syncResult.UpdateError(err)
} else {
syncResult.Update()
syncResult.UpdateError(errors.Wrapf(err, "syncWithCloudSecurityGroup"))
continue
}
syncResult.Update()
}
//相同的不能同步, 原因: 多个平台的安全组可能共用一个本地安全组,下面仅仅是新加的安全组
for i := 0; i < len(added); i++ {
secgroup, err := SecurityGroupManager.newFromCloudSecgroup(ctx, userCred, provider, added[i])
if err != nil {
syncResult.AddError(err)
syncResult.AddError(errors.Wrapf(err, "newFromCloudSecgroup"))
continue
}
if secgroup.ProjectId != provider.ProjectId {
@@ -450,7 +476,7 @@ func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(ctx context.C
}
cache, err := manager.NewCache(ctx, userCred, secgroup.Id, vpcId, vpc.CloudregionId, provider.Id, added[i].GetProjectId())
if err != nil {
syncResult.AddError(fmt.Errorf("failed to create secgroup cache for secgroup %s(%s) provider: %s: %s", secgroup.Name, secgroup.Name, provider.Name, err))
syncResult.AddError(errors.Wrapf(err, "NewCache for secgroup %s provider %s", secgroup.Name, provider.Name))
continue
}
_, err = db.Update(cache, func() error {
@@ -461,7 +487,7 @@ func (manager *SSecurityGroupCacheManager) SyncSecurityGroupCaches(ctx context.C
return nil
})
if err != nil {
syncResult.AddError(err)
syncResult.AddError(errors.Wrapf(err, "db.Update"))
continue
}
localSecgroups = append(localSecgroups, *secgroup)
@@ -560,3 +586,20 @@ func (manager *SSecurityGroupCacheManager) ListItemExportKeys(ctx context.Contex
return q, nil
}
func (self *SSecurityGroupCache) GetISecurityGroup() (cloudprovider.ICloudSecurityGroup, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty externalId")
}
manager := self.GetCloudprovider()
if manager == nil {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "failed to found manager")
}
iRegion, err := self.GetIRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetIRegion")
}
return iRegion.GetISecurityGroupById(self.ExternalId)
}

View File

@@ -22,7 +22,6 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/util/regutils"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/util/stringutils"
@@ -462,8 +461,7 @@ func (manager *SSecurityGroupRuleManager) getRulesBySecurityGroup(secgroup *SSec
return rules, nil
}
func (manager *SSecurityGroupRuleManager) SyncRules(ctx context.Context, userCred mcclient.TokenCredential, secgroup *SSecurityGroup, rules cloudprovider.SecurityRuleSet) compare.SyncResult {
syncResult := compare.SyncResult{}
func (self *SSecurityGroup) SyncRules(ctx context.Context, userCred mcclient.TokenCredential, rules cloudprovider.SecurityRuleSet) error {
priority, prePriority := 10, 0
for i := 0; i < len(rules); i++ {
// 这里避免了Rule规则优先级在 1-100之外的问题,ext.GetRules()不需要进行优先级转换
@@ -472,19 +470,17 @@ func (manager *SSecurityGroupRuleManager) SyncRules(ctx context.Context, userCre
}
prePriority = rules[i].Priority
rules[i].Priority = priority
_, err := manager.newFromCloudSecurityGroup(ctx, userCred, rules[i], secgroup)
_, err := self.newFromCloudSecurityGroupRule(ctx, userCred, rules[i])
if err != nil {
syncResult.AddError(err)
continue
return errors.Wrapf(err, "newFromCloudSecurityGroupRule")
}
syncResult.Add()
}
return syncResult
return nil
}
func (manager *SSecurityGroupRuleManager) newFromCloudSecurityGroup(ctx context.Context, userCred mcclient.TokenCredential, rule cloudprovider.SecurityRule, secgroup *SSecurityGroup) (*SSecurityGroupRule, error) {
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
func (self *SSecurityGroup) newFromCloudSecurityGroupRule(ctx context.Context, userCred mcclient.TokenCredential, rule cloudprovider.SecurityRule) (*SSecurityGroupRule, error) {
lockman.LockObject(ctx, self)
defer lockman.ReleaseObject(ctx, self)
protocol := rule.Protocol
if len(protocol) == 0 {
@@ -505,11 +501,11 @@ func (manager *SSecurityGroupRuleManager) newFromCloudSecurityGroup(ctx context.
Action: string(rule.Action),
Description: rule.Description,
}
secrule.SecgroupId = secgroup.Id
secrule.SecgroupId = self.Id
err := manager.TableSpec().Insert(ctx, secrule)
err := SecurityGroupRuleManager.TableSpec().Insert(ctx, secrule)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "SecurityGroupRuleManager.Insert")
}
return secrule, nil
}

View File

@@ -37,6 +37,7 @@ import (
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/options"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
@@ -539,6 +540,14 @@ func totalSecurityGroupCount(scope rbacutils.TRbacScope, ownerId mcclient.IIdent
return q.CountWithError()
}
func (self *SSecurityGroup) AllowPerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "purge")
}
func (self *SSecurityGroup) PerformPurge(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return nil, self.StartDeleteSecurityGroupTask(ctx, userCred, true, "")
}
func (self *SSecurityGroup) AllowPerformUncacheSecgroup(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "uncache-secgroup")
}
@@ -821,7 +830,57 @@ func (manager *SSecurityGroupManager) getSecurityGroups() ([]SSecurityGroup, err
}
}
func (manager *SSecurityGroupManager) newFromCloudSecgroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, extSec cloudprovider.ICloudSecurityGroup) (*SSecurityGroup, error) {
func (self *SSecurityGroup) cleanRules(ctx context.Context, userCred mcclient.TokenCredential) error {
rules := []SSecurityGroupRule{}
q := SecurityGroupRuleManager.Query().Equals("secgroup_id", self.Id)
err := db.FetchModelObjects(SecurityGroupRuleManager, q, &rules)
if err != nil {
return errors.Wrapf(err, "db.FetchModelObjects")
}
for i := range rules {
err = rules[i].Delete(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "DeleteRule(%s)", rules[i].Id)
}
}
return nil
}
func (self *SSecurityGroup) SyncSecurityGroupRules(ctx context.Context, userCred mcclient.TokenCredential, info *sRuleInfo) error {
inRules := cloudprovider.AddDefaultRule(info.inRules, info.defaultInRule, "in:deny any", info.order, info.minPriority, info.maxPriority, info.onlyAllowRules)
cloudprovider.SortSecurityRule(inRules, info.order, info.onlyAllowRules)
outRules := cloudprovider.AddDefaultRule(info.outRules, info.defaultOutRule, "out:allow any", info.order, info.minPriority, info.maxPriority, info.onlyAllowRules)
cloudprovider.SortSecurityRule(outRules, info.order, info.onlyAllowRules)
err := self.cleanRules(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "cleanRules")
}
err = self.SyncRules(ctx, userCred, inRules)
if err != nil {
return errors.Wrapf(err, "SyncInRules")
}
err = self.SyncRules(ctx, userCred, outRules)
if err != nil {
return errors.Wrapf(err, "SyncOutRules")
}
return nil
}
type sRuleInfo struct {
rules []cloudprovider.SecurityRule
inRules []cloudprovider.SecurityRule
outRules []cloudprovider.SecurityRule
defaultInRule cloudprovider.SecurityRule
defaultOutRule cloudprovider.SecurityRule
order cloudprovider.TPriorityOrder
onlyAllowRules bool
maxPriority int
minPriority int
}
func (manager *SSecurityGroupManager) getRuleInfo(provider *SCloudprovider, extSec cloudprovider.ICloudSecurityGroup) (*sRuleInfo, error) {
regionDriver, err := provider.GetRegionDriver()
if err != nil {
return nil, errors.Wrap(err, "provider.GetRegionDriver")
@@ -832,36 +891,48 @@ func (manager *SSecurityGroupManager) newFromCloudSecgroup(ctx context.Context,
return nil, errors.Wrap(err, "extSec.GetRules")
}
inRules := []cloudprovider.SecurityRule{}
outRules := []cloudprovider.SecurityRule{}
info := &sRuleInfo{
rules: rules,
inRules: []cloudprovider.SecurityRule{},
outRules: []cloudprovider.SecurityRule{},
defaultInRule: regionDriver.GetDefaultSecurityGroupInRule(),
defaultOutRule: regionDriver.GetDefaultSecurityGroupOutRule(),
order: regionDriver.GetSecurityGroupRuleOrder(),
onlyAllowRules: regionDriver.IsOnlySupportAllowRules(),
maxPriority: regionDriver.GetSecurityGroupRuleMaxPriority(),
minPriority: regionDriver.GetSecurityGroupRuleMinPriority(),
}
for i := range rules {
if rules[i].Direction == secrules.DIR_IN {
inRules = append(inRules, rules[i])
info.inRules = append(info.inRules, rules[i])
} else {
outRules = append(outRules, rules[i])
info.outRules = append(info.outRules, rules[i])
}
}
return info, nil
}
maxPriority := regionDriver.GetSecurityGroupRuleMaxPriority()
minPriority := regionDriver.GetSecurityGroupRuleMinPriority()
defaultInRule := regionDriver.GetDefaultSecurityGroupInRule()
defaultOutRule := regionDriver.GetDefaultSecurityGroupOutRule()
order := regionDriver.GetSecurityGroupRuleOrder()
onlyAllowRules := regionDriver.IsOnlySupportAllowRules()
// 查询与provider在同域的安全组比对寻找一个与云上安全组规则相同的安全组
secgroups := []SSecurityGroup{}
q := manager.Query().Equals("domain_id", provider.DomainId)
err = db.FetchModelObjects(manager, q, &secgroups)
func (manager *SSecurityGroupManager) newFromCloudSecgroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, extSec cloudprovider.ICloudSecurityGroup) (*SSecurityGroup, error) {
info, err := manager.getRuleInfo(provider, extSec)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
return nil, errors.Wrapf(err, "getRuleInfo")
}
for i := range secgroups {
localRules := secrules.SecurityRuleSet(secgroups[i].GetSecRules(""))
_, inAdds, outAdds, inDels, outDels := cloudprovider.CompareRules(minPriority, maxPriority, order, localRules, rules, defaultInRule, defaultOutRule, onlyAllowRules, false)
if len(inAdds) == 0 && len(outAdds) == 0 && len(inDels) == 0 && len(outDels) == 0 {
return &secgroups[i], nil
if options.Options.EnableAutoMergeSecurityGroup {
// 查询与provider在同域的安全组比对寻找一个与云上安全组规则相同的安全组
secgroups := []SSecurityGroup{}
q := manager.Query().Equals("domain_id", provider.DomainId)
err = db.FetchModelObjects(manager, q, &secgroups)
if err != nil {
return nil, errors.Wrap(err, "db.FetchModelObjects")
}
for i := range secgroups {
localRules := secrules.SecurityRuleSet(secgroups[i].GetSecRules(""))
_, inAdds, outAdds, inDels, outDels := cloudprovider.CompareRules(info.minPriority, info.maxPriority, info.order, localRules, info.rules, info.defaultInRule, info.defaultOutRule, info.onlyAllowRules, false)
if len(inAdds) == 0 && len(outAdds) == 0 && len(inDels) == 0 && len(outDels) == 0 {
return &secgroups[i], nil
}
}
}
@@ -870,31 +941,26 @@ func (manager *SSecurityGroupManager) newFromCloudSecgroup(ctx context.Context,
secgroup := SSecurityGroup{}
secgroup.SetModelManager(manager, &secgroup)
newName, err := db.GenerateName(manager, userCred, extSec.GetName())
secgroup.Name, err = db.GenerateName(manager, userCred, extSec.GetName())
if err != nil {
return nil, err
}
secgroup.Name = newName
secgroup.Description = extSec.GetDescription()
secgroup.ProjectId = provider.ProjectId
secgroup.DomainId = provider.DomainId
if err := manager.TableSpec().Insert(ctx, &secgroup); err != nil {
return nil, err
err = manager.TableSpec().Insert(ctx, &secgroup)
if err != nil {
return nil, errors.Wrapf(err, "Insert")
}
//这里必须先同步下规则,不然下次对比此安全组规则为空
inRules = cloudprovider.AddDefaultRule(inRules, defaultInRule, "in:deny any", order, minPriority, maxPriority, onlyAllowRules)
cloudprovider.SortSecurityRule(inRules, order, onlyAllowRules)
outRules = cloudprovider.AddDefaultRule(outRules, defaultOutRule, "out:allow any", order, minPriority, maxPriority, onlyAllowRules)
cloudprovider.SortSecurityRule(outRules, order, onlyAllowRules)
SecurityGroupRuleManager.SyncRules(ctx, userCred, &secgroup, inRules)
SecurityGroupRuleManager.SyncRules(ctx, userCred, &secgroup, outRules)
err = secgroup.SyncSecurityGroupRules(ctx, userCred, info)
if err != nil {
return nil, errors.Wrapf(err, "SyncSecurityGroupRules")
}
db.OpsLog.LogEvent(&secgroup, db.ACT_CREATE, secgroup.GetShortDesc(ctx), userCred)
return &secgroup, nil
}
@@ -1035,10 +1101,12 @@ func (self *SSecurityGroup) GetSecurityGroupCaches() []SSecurityGroupCache {
}
func (self *SSecurityGroup) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteSecurityGroupTask(ctx, userCred, jsonutils.NewDict(), "")
return self.StartDeleteSecurityGroupTask(ctx, userCred, false, "")
}
func (self *SSecurityGroup) StartDeleteSecurityGroupTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict, parentTaskId string) error {
func (self *SSecurityGroup) StartDeleteSecurityGroupTask(ctx context.Context, userCred mcclient.TokenCredential, isPurge bool, parentTaskId string) error {
params := jsonutils.NewDict()
params.Add(jsonutils.NewBool(isPurge), "purge")
self.SetStatus(userCred, api.SECGROUP_STATUS_DELETING, "")
task, err := taskman.TaskManager.NewTask(ctx, "SecurityGroupDeleteTask", self, userCred, params, parentTaskId, "", nil)
if err != nil {

View File

@@ -97,7 +97,7 @@ type SServerSku struct {
OsName string `width:"32" charset:"ascii" nullable:"true" list:"user" create:"admin_optional" update:"admin" default:"Any"` // Windows|Linux|Any
SysDiskResizable tristate.TriState `default:"true" nullable:"true" list:"user" create:"admin_optional" update:"admin"`
SysDiskType string `width:"32" charset:"ascii" nullable:"true" list:"user" create:"admin_optional" update:"admin"`
SysDiskType string `width:"128" charset:"ascii" nullable:"true" list:"user" create:"admin_optional" update:"admin"`
SysDiskMinSizeGB int `nullable:"true" list:"user" create:"admin_optional" update:"admin"` // not required。 windows比较新的版本都是50G左右。
SysDiskMaxSizeGB int `nullable:"true" list:"user" create:"admin_optional" update:"admin"` // not required
@@ -1142,10 +1142,15 @@ func (manager *SServerSkuManager) newFromCloudSku(ctx context.Context, userCred
sku.Status = api.SkuStatusReady
sku.constructSku(extSku)
sku.Name = extSku.GetName()
var err error
sku.Name, err = db.GenerateName(manager, userCred, extSku.GetName())
if err != nil {
return errors.Wrap(err, "db.GenerateName")
}
sku.CloudregionId = api.DEFAULT_REGION_ID
sku.SetModelManager(manager, sku)
err := manager.TableSpec().Insert(ctx, sku)
err = manager.TableSpec().Insert(ctx, sku)
if err != nil {
return errors.Wrapf(err, "newFromCloudSku.Insert")
}

View File

@@ -72,9 +72,10 @@ func (self *SSkuResourcesMeta) GetDBInstanceSkusByRegionExternalId(regionExterna
return nil, errors.Wrapf(err, "obj.Unmarshal")
}
if len(sku.Zone1) > 0 {
zoneId := self.getZoneIdBySuffix(zoneMaps, sku.Zone1)
zoneId := self.getZoneIdBySuffix(zoneMaps, sku.Zone1) // Huawei rds sku zone1 maybe is cn-north-4f
if len(zoneId) == 0 {
return nil, fmt.Errorf("invalid sku %s %s zone1: %s", sku.Id, sku.CloudregionId, sku.Zone1)
log.Errorf("invalid sku %s(%s) %s zone1: %s", sku.Name, sku.Id, sku.CloudregionId, sku.Zone1)
continue
}
sku.Zone1 = zoneId
}
@@ -82,7 +83,8 @@ func (self *SSkuResourcesMeta) GetDBInstanceSkusByRegionExternalId(regionExterna
if len(sku.Zone2) > 0 {
zoneId := self.getZoneIdBySuffix(zoneMaps, sku.Zone2)
if len(zoneId) == 0 {
return nil, fmt.Errorf("invalid sku %s %s zone2: %s", sku.Id, sku.CloudregionId, sku.Zone2)
log.Errorf("invalid sku %s(%s) %s zone2: %s", sku.Name, sku.Id, sku.CloudregionId, sku.Zone2)
continue
}
sku.Zone2 = zoneId
}
@@ -90,7 +92,8 @@ func (self *SSkuResourcesMeta) GetDBInstanceSkusByRegionExternalId(regionExterna
if len(sku.Zone3) > 0 {
zoneId := self.getZoneIdBySuffix(zoneMaps, sku.Zone3)
if len(zoneId) == 0 {
return nil, fmt.Errorf("invalid sku %s %s zone3: %s", sku.Id, sku.CloudregionId, sku.Zone3)
log.Errorf("invalid sku %s(%s) %s zone3: %s", sku.Name, sku.Id, sku.CloudregionId, sku.Zone3)
continue
}
sku.Zone3 = zoneId
}

View File

@@ -331,7 +331,7 @@ func (self *SStoragecachedimage) markDeleting(ctx context.Context, userCred mccl
}
if !isForce && !utils.IsInStringArray(self.Status,
[]string{api.CACHED_IMAGE_STATUS_READY, api.CACHED_IMAGE_STATUS_DELETING, api.CACHED_IMAGE_STATUS_CACHE_FAILED}) {
[]string{api.CACHED_IMAGE_STATUS_ACTIVE, api.CACHED_IMAGE_STATUS_DELETING, api.CACHED_IMAGE_STATUS_CACHE_FAILED}) {
return httperrors.NewInvalidStatusError("Cannot uncache in status %s", self.Status)
}
_, err = db.Update(self, func() error {
@@ -439,17 +439,17 @@ func (self *SStoragecachedimage) syncRemoveCloudImage(ctx context.Context, userC
return nil
}
func (self *SStoragecachedimage) syncWithCloudImage(ctx context.Context, userCred mcclient.TokenCredential, image cloudprovider.ICloudImage) error {
func (self *SStoragecachedimage) syncWithCloudImage(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, image cloudprovider.ICloudImage, managerId string) error {
cachedImage := self.GetCachedimage()
if len(cachedImage.ExternalId) > 0 {
self.SetStatus(userCred, image.GetStatus(), "")
return cachedImage.syncWithCloudImage(ctx, userCred, image)
return cachedImage.syncWithCloudImage(ctx, userCred, ownerId, image, managerId)
} else {
return nil
}
}
func (manager *SStoragecachedimageManager) newFromCloudImage(ctx context.Context, userCred mcclient.TokenCredential, image cloudprovider.ICloudImage, cache *SStoragecache) error {
func (manager *SStoragecachedimageManager) newFromCloudImage(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, image cloudprovider.ICloudImage, cache *SStoragecache) error {
var cachedImage *SCachedimage
imgObj, err := db.FetchByExternalId(CachedimageManager, image.GetGlobalId())
if err != nil {
@@ -472,7 +472,7 @@ func (manager *SStoragecachedimageManager) newFromCloudImage(ctx context.Context
}
if cachedImage == nil {
// no such image
cachedImage, err = CachedimageManager.newFromCloudImage(ctx, userCred, image)
cachedImage, err = CachedimageManager.newFromCloudImage(ctx, userCred, ownerId, image, cache.ManagerId)
if err != nil {
log.Errorf("CachedimageManager.newFromCloudImage fail %s", err)
return err
@@ -482,7 +482,7 @@ func (manager *SStoragecachedimageManager) newFromCloudImage(ctx context.Context
cachedImage = imgObj.(*SCachedimage)
}
if len(cachedImage.ExternalId) > 0 {
cachedImage.syncWithCloudImage(ctx, userCred, image)
cachedImage.syncWithCloudImage(ctx, userCred, ownerId, image, cache.ManagerId)
}
scimg := manager.Register(ctx, userCred, cache.GetId(), cachedImage.GetId(), image.GetStatus())
if scimg == nil {
@@ -553,3 +553,22 @@ func (manager *SStoragecachedimageManager) OrderByExtraFields(
return q, nil
}
func (manager *SStoragecachedimageManager) InitializeData() error {
images := []SStoragecachedimage{}
q := manager.Query().Equals("status", "ready")
err := db.FetchModelObjects(manager, q, &images)
if err != nil {
return errors.Wrapf(err, "db.FetchModelObjects")
}
for i := range images {
_, err := db.Update(&images[i], func() error {
images[i].Status = api.CACHED_IMAGE_STATUS_ACTIVE
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update(%d)", images[i].RowId)
}
}
return nil
}

View File

@@ -610,6 +610,13 @@ func (cache *SStoragecache) SyncCloudImages(
return syncResult
}
var syncOwnerId mcclient.IIdentityProvider
provider := cache.GetCloudprovider()
if provider != nil {
syncOwnerId = provider.GetOwnerId()
}
removed := make([]SStoragecachedimage, 0)
commondb := make([]SStoragecachedimage, 0)
commonext := make([]cloudprovider.ICloudImage, 0)
@@ -631,7 +638,7 @@ func (cache *SStoragecache) SyncCloudImages(
}
}
for i := 0; i < len(commondb); i += 1 {
err = commondb[i].syncWithCloudImage(ctx, userCred, commonext[i])
err = commondb[i].syncWithCloudImage(ctx, userCred, syncOwnerId, commonext[i], cache.ManagerId)
if err != nil {
syncResult.UpdateError(err)
} else {
@@ -639,7 +646,7 @@ func (cache *SStoragecache) SyncCloudImages(
}
}
for i := 0; i < len(added); i += 1 {
err = StoragecachedimageManager.newFromCloudImage(ctx, userCred, added[i], cache)
err = StoragecachedimageManager.newFromCloudImage(ctx, userCred, syncOwnerId, added[i], cache)
if err != nil {
syncResult.AddError(err)
} else {
@@ -662,7 +669,7 @@ func (self *SStoragecache) IsReachCapacityLimit(imageId string) bool {
log.Debugf("image %s is not a customized image, no need to cache", imageId)
return false
}
cachedImages := self.getCachedImageList(nil, cloudprovider.CachedImageTypeCustomized, []string{api.CACHED_IMAGE_STATUS_READY})
cachedImages := self.getCachedImageList(nil, cloudprovider.CachedImageTypeCustomized, []string{api.CACHED_IMAGE_STATUS_ACTIVE})
for i := range cachedImages {
if cachedImages[i].Id == imageId {
// already cached
@@ -675,7 +682,7 @@ func (self *SStoragecache) IsReachCapacityLimit(imageId string) bool {
}
func (self *SStoragecache) StartRelinquishLeastUsedCachedImageTask(ctx context.Context, userCred mcclient.TokenCredential, imageId string, parentTaskId string) error {
cachedImages := self.getCachedImageList([]string{imageId}, cloudprovider.CachedImageTypeCustomized, []string{api.CACHED_IMAGE_STATUS_READY})
cachedImages := self.getCachedImageList([]string{imageId}, cloudprovider.CachedImageTypeCustomized, []string{api.CACHED_IMAGE_STATUS_ACTIVE})
leastUsedIdx := -1
leastRefCount := -1
for i := range cachedImages {

View File

@@ -194,7 +194,7 @@ func (manager *SVpcManager) getVpcExternalIdForClassicNetwork(regionId, cloudpro
func (manager *SVpcManager) GetOrCreateVpcForClassicNetwork(ctx context.Context, cloudprovider *SCloudprovider, region *SCloudregion) (*SVpc, error) {
externalId := manager.getVpcExternalIdForClassicNetwork(region.Id, cloudprovider.Id)
_vpc, err := db.FetchByExternalIdAndManagerId(manager, externalId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
return q.Equals("manager_id", region.ManagerId)
return q.Equals("manager_id", cloudprovider.Id)
})
if err == nil {
return _vpc.(*SVpc), nil
@@ -211,7 +211,7 @@ func (manager *SVpcManager) GetOrCreateVpcForClassicNetwork(ctx context.Context,
vpc.SetEnabled(false)
vpc.Status = api.VPC_STATUS_UNAVAILABLE
vpc.ExternalId = externalId
vpc.ManagerId = region.ManagerId
vpc.ManagerId = cloudprovider.Id
err = manager.TableSpec().Insert(ctx, vpc)
if err != nil {
return nil, errors.Wrap(err, "Insert vpc for classic network")
@@ -1062,6 +1062,11 @@ func (self *SVpc) initWire(ctx context.Context, zone *SZone) (*SWire, error) {
wire.ZoneId = zone.Id
wire.IsEmulated = true
wire.Name = fmt.Sprintf("vpc-%s", self.Name)
wire.DomainId = self.DomainId
wire.IsPublic = self.IsPublic
wire.PublicScope = self.PublicScope
wire.SetModelManager(WireManager, wire)
err := WireManager.TableSpec().Insert(ctx, wire)
if err != nil {
@@ -1216,7 +1221,7 @@ func (manager *SVpcManager) ListItemExportKeys(ctx context.Context,
}
func (vpc *SVpc) PerformPublic(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input apis.PerformPublicDomainInput) (jsonutils.JSONObject, error) {
if rbacutils.String2ScopeDefault(input.Scope, rbacutils.ScopeSystem) != rbacutils.ScopeSystem {
if vpc.Id == api.DEFAULT_VPC_ID && rbacutils.String2ScopeDefault(input.Scope, rbacutils.ScopeSystem) != rbacutils.ScopeSystem {
return nil, httperrors.NewForbiddenError("For default vpc, only system level sharing can be set")
}
_, err := vpc.SEnabledStatusInfrasResourceBase.PerformPublic(ctx, userCred, query, input)

View File

@@ -451,10 +451,10 @@ func (manager *SWireManager) totalCountQ(
providers []string, brands []string, cloudEnv string,
scope rbacutils.TRbacScope,
ownerId mcclient.IIdentityProvider,
pendingDeleted bool,
) *sqlchemy.SQuery {
guestsQ := filterByScopeOwnerId(GuestManager.Query(), scope, ownerId)
guests := guestsQ.SubQuery()
hostsQ := HostManager.Query()
if len(hostTypes) > 0 {
hostsQ = hostsQ.In("host_type", hostTypes)
@@ -466,7 +466,9 @@ func (manager *SWireManager) totalCountQ(
hostsQ = RangeObjectsFilter(hostsQ, rangeObjs, nil, hostsQ.Field("zone_id"), hostsQ.Field("manager_id"), hostsQ.Field("id"), nil)
}
hosts := hostsQ.SubQuery()
groups := filterByScopeOwnerId(GroupManager.Query(), scope, ownerId).SubQuery()
lbsQ := filterByScopeOwnerId(LoadbalancerManager.Query(), scope, ownerId)
if len(providers) > 0 || len(brands) > 0 || len(cloudEnv) > 0 {
lbsQ = CloudProviderFilter(lbsQ, lbsQ.Field("manager_id"), providers, brands, cloudEnv)
@@ -476,19 +478,24 @@ func (manager *SWireManager) totalCountQ(
}
lbs := lbsQ.SubQuery()
dbsQ := filterByScopeOwnerId(DBInstanceManager.Query(), scope, ownerId)
if len(providers) > 0 || len(brands) > 0 || len(cloudEnv) > 0 {
dbsQ = CloudProviderFilter(dbsQ, dbsQ.Field("manager_id"), providers, brands, cloudEnv)
}
if len(rangeObjs) > 0 {
dbsQ = RangeObjectsFilter(dbsQ, rangeObjs, dbsQ.Field("cloudregion_id"), dbsQ.Field("zone_id"), dbsQ.Field("manager_id"), nil, nil)
}
dbs := dbsQ.SubQuery()
gNics := GuestnetworkManager.Query().SubQuery()
gNicQ := gNics.Query(
gNics.Field("network_id"),
sqlchemy.COUNT("gnic_count"),
sqlchemy.SUM("pending_deleted_gnic_count", guests.Field("pending_deleted")),
)
gNicQ = gNicQ.Join(guests, sqlchemy.Equals(guests.Field("id"), gNics.Field("guest_id")))
gNicQ = gNicQ.Join(hosts, sqlchemy.Equals(guests.Field("host_id"), hosts.Field("id")))
gNicQ = gNicQ.Filter(sqlchemy.IsTrue(hosts.Field("enabled")))
if pendingDeleted {
gNicQ = gNicQ.Filter(sqlchemy.IsTrue(guests.Field("pending_deleted")))
} else {
gNicQ = gNicQ.Filter(sqlchemy.IsFalse(guests.Field("pending_deleted")))
}
hNics := HostnetworkManager.Query().SubQuery()
hNicQ := hNics.Query(
@@ -517,33 +524,75 @@ func (manager *SWireManager) totalCountQ(
sqlchemy.COUNT("lbnic_count"),
)
lbNicQ = lbNicQ.Join(lbs, sqlchemy.Equals(lbs.Field("id"), lbNics.Field("loadbalancer_id")))
if pendingDeleted {
lbNicQ = lbNicQ.Filter(sqlchemy.IsTrue(lbs.Field("pending_deleted")))
} else {
lbNicQ = lbNicQ.Filter(sqlchemy.IsFalse(lbs.Field("pending_deleted")))
lbNicQ = lbNicQ.Filter(sqlchemy.IsFalse(lbs.Field("pending_deleted")))
eipNics := ElasticipManager.Query().IsNotEmpty("network_id").SubQuery()
eipNicQ := eipNics.Query(
eipNics.Field("network_id"),
sqlchemy.COUNT("eipnic_count"),
)
if len(providers) > 0 || len(brands) > 0 || len(cloudEnv) > 0 {
eipNicQ = CloudProviderFilter(eipNicQ, eipNicQ.Field("manager_id"), providers, brands, cloudEnv)
}
if len(rangeObjs) > 0 {
eipNicQ = RangeObjectsFilter(eipNicQ, rangeObjs, eipNicQ.Field("cloudregion_id"), nil, eipNicQ.Field("manager_id"), nil, nil)
}
netifsQ := NetworkInterfaceManager.Query()
if len(providers) > 0 || len(brands) > 0 || len(cloudEnv) > 0 {
netifsQ = CloudProviderFilter(netifsQ, netifsQ.Field("manager_id"), providers, brands, cloudEnv)
}
if len(rangeObjs) > 0 {
netifsQ = RangeObjectsFilter(netifsQ, rangeObjs, netifsQ.Field("cloudregion_id"), nil, netifsQ.Field("manager_id"), nil, nil)
}
netifs := netifsQ.SubQuery()
netifNics := NetworkinterfacenetworkManager.Query().SubQuery()
netifNicQ := netifNics.Query(
netifNics.Field("network_id"),
sqlchemy.COUNT("netifnic_count"),
)
netifNicQ = netifNicQ.Join(netifs, sqlchemy.Equals(netifNics.Field("networkinterface_id"), netifs.Field("id")))
dbNics := DBInstanceNetworkManager.Query().SubQuery()
dbNicQ := dbNics.Query(
dbNics.Field("network_id"),
sqlchemy.COUNT("dbnic_count"),
)
dbNicQ = dbNicQ.Join(dbs, sqlchemy.Equals(dbs.Field("id"), dbNics.Field("dbinstance_id")))
dbNicQ = dbNicQ.Filter(sqlchemy.IsFalse(dbs.Field("pending_deleted")))
gNicSQ := gNicQ.GroupBy(gNics.Field("network_id")).SubQuery()
hNicSQ := hNicQ.GroupBy(hNics.Field("network_id")).SubQuery()
revSQ := revQ.GroupBy(revIps.Field("network_id")).SubQuery()
grpNicSQ := grpNicQ.GroupBy(groupNics.Field("network_id")).SubQuery()
lbNicSQ := lbNicQ.GroupBy(lbNics.Field("network_id")).SubQuery()
eipNicSQ := eipNicQ.GroupBy(eipNics.Field("network_id")).SubQuery()
netifNicSQ := netifNicQ.GroupBy(netifNics.Field("network_id")).SubQuery()
dbNicSQ := dbNicQ.GroupBy(dbNics.Field("network_id")).SubQuery()
networks := NetworkManager.Query().SubQuery()
netQ := networks.Query(
networks.Field("wire_id"),
sqlchemy.COUNT("id").Label("net_count"),
sqlchemy.SUM("gnic_count", gNicQ.Field("gnic_count")),
sqlchemy.SUM("hnic_count", hNicQ.Field("hnic_count")),
sqlchemy.SUM("rev_count", revQ.Field("rnic_count")),
sqlchemy.SUM("gnic_count", gNicSQ.Field("gnic_count")),
sqlchemy.SUM("pending_deleted_gnic_count", gNicSQ.Field("pending_deleted_gnic_count")),
sqlchemy.SUM("hnic_count", hNicSQ.Field("hnic_count")),
sqlchemy.SUM("rev_count", revSQ.Field("rnic_count")),
sqlchemy.SUM("grpnic_count", grpNicSQ.Field("grpnic_count")),
sqlchemy.SUM("lbnic_count", lbNicSQ.Field("lbnic_count")),
sqlchemy.SUM("eipnic_count", eipNicSQ.Field("eipnic_count")),
sqlchemy.SUM("netifnic_count", netifNicSQ.Field("netifnic_count")),
sqlchemy.SUM("dbnic_count", dbNicSQ.Field("dbnic_count")),
)
netQ = netQ.LeftJoin(gNicSQ, sqlchemy.Equals(gNicSQ.Field("network_id"), networks.Field("id")))
netQ = netQ.LeftJoin(hNicSQ, sqlchemy.Equals(hNicSQ.Field("network_id"), networks.Field("id")))
netQ = netQ.LeftJoin(revSQ, sqlchemy.Equals(revSQ.Field("network_id"), networks.Field("id")))
netQ = netQ.LeftJoin(grpNicSQ, sqlchemy.Equals(grpNicSQ.Field("network_id"), networks.Field("id")))
netQ = netQ.LeftJoin(lbNicSQ, sqlchemy.Equals(lbNicSQ.Field("network_id"), networks.Field("id")))
netQ = netQ.LeftJoin(eipNicSQ, sqlchemy.Equals(eipNicSQ.Field("network_id"), networks.Field("id")))
netQ = netQ.LeftJoin(netifNicSQ, sqlchemy.Equals(netifNicSQ.Field("network_id"), networks.Field("id")))
netQ = netQ.LeftJoin(dbNicSQ, sqlchemy.Equals(dbNicSQ.Field("network_id"), networks.Field("id")))
netQ = netQ.GroupBy(networks.Field("wire_id"))
netSQ := netQ.SubQuery()
@@ -553,28 +602,31 @@ func (manager *SWireManager) totalCountQ(
sqlchemy.SUM("emulated_wires_count", wires.Field("is_emulated")),
sqlchemy.SUM("net_count", netSQ.Field("net_count")),
sqlchemy.SUM("guest_nic_count", netSQ.Field("gnic_count")),
sqlchemy.SUM("pending_deleted_guest_nic_count", netSQ.Field("pending_deleted_gnic_count")),
sqlchemy.SUM("host_nic_count", netSQ.Field("hnic_count")),
sqlchemy.SUM("reserved_count", netSQ.Field("rev_count")),
sqlchemy.SUM("group_nic_count", netSQ.Field("grpnic_count")),
sqlchemy.SUM("lb_nic_count", netSQ.Field("lbnic_count")),
sqlchemy.SUM("eip_nic_count", netSQ.Field("eipnic_count")),
sqlchemy.SUM("netif_nic_count", netSQ.Field("netifnic_count")),
sqlchemy.SUM("db_nic_count", netSQ.Field("dbnic_count")),
)
q = q.LeftJoin(netSQ, sqlchemy.Equals(wires.Field("id"), netSQ.Field("wire_id")))
if len(rangeObjs) > 0 || len(hostTypes) > 0 {
if len(hostTypes) > 0 {
hostwires := HostwireManager.Query().SubQuery()
sq := hostwires.Query(hostwires.Field("wire_id"))
sq = sq.Join(hosts, sqlchemy.Equals(hosts.Field("id"), hostwires.Field("host_id")))
sq = sq.Filter(sqlchemy.IsTrue(hosts.Field("enabled")))
sq = AttachUsageQuery(sq, hosts, hostTypes, nil, nil, nil, "", rangeObjs)
q = q.Filter(sqlchemy.In(wires.Field("id"), sq.Distinct()))
hosts := HostManager.Query().SubQuery()
q = q.Join(hostwires, sqlchemy.Equals(q.Field("id"), hostwires.Field("wire_id")))
q = q.Join(hosts, sqlchemy.Equals(hostwires.Field("host_id"), hosts.Field("id")))
q = q.Filter(sqlchemy.In(hosts.Field("host_type"), hostTypes))
}
if len(providers) > 0 || len(brands) > 0 || len(cloudEnv) > 0 {
if len(rangeObjs) > 0 || len(providers) > 0 || len(brands) > 0 || len(cloudEnv) > 0 {
vpcs := VpcManager.Query().SubQuery()
subq := vpcs.Query(vpcs.Field("id"))
subq = CloudProviderFilter(subq, vpcs.Field("manager_id"), providers, brands, cloudEnv)
q = q.Filter(sqlchemy.In(wires.Field("vpc_id"), subq.SubQuery()))
q = q.Join(vpcs, sqlchemy.Equals(q.Field("vpc_id"), vpcs.Field("id")))
q = CloudProviderFilter(q, vpcs.Field("manager_id"), providers, brands, cloudEnv)
q = RangeObjectsFilter(q, rangeObjs, vpcs.Field("cloudregion_id"), q.Field("zone_id"), vpcs.Field("manager_id"), nil, nil)
}
return q
@@ -589,10 +641,15 @@ type WiresCountStat struct {
ReservedCount int
GroupNicCount int
LbNicCount int
EipNicCount int
NetifNicCount int
DbNicCount int
PendingDeletedGuestNicCount int
}
func (wstat WiresCountStat) NicCount() int {
return wstat.GuestNicCount + wstat.HostNicCount + wstat.ReservedCount + wstat.GroupNicCount + wstat.LbNicCount
return wstat.GuestNicCount + wstat.HostNicCount + wstat.ReservedCount + wstat.GroupNicCount + wstat.LbNicCount + wstat.NetifNicCount + wstat.EipNicCount + wstat.DbNicCount
}
func (manager *SWireManager) TotalCount(
@@ -601,7 +658,6 @@ func (manager *SWireManager) TotalCount(
providers []string, brands []string, cloudEnv string,
scope rbacutils.TRbacScope,
ownerId mcclient.IIdentityProvider,
pendingDeleted bool,
) WiresCountStat {
stat := WiresCountStat{}
err := manager.totalCountQ(
@@ -609,7 +665,6 @@ func (manager *SWireManager) TotalCount(
hostTypes,
providers, brands, cloudEnv,
scope, ownerId,
pendingDeleted,
).First(&stat)
if err != nil {
log.Errorf("Wire total count: %v", err)

View File

@@ -144,6 +144,8 @@ type ComputeOptions struct {
SASControllerOptions
common_options.CommonOptions
common_options.DBOptions
EnableAutoMergeSecurityGroup bool `help:"Enable auto merge secgroup when sync security group from cloud, default False" default:"false"`
}
type SCapabilityOptions struct {

View File

@@ -311,7 +311,7 @@ var (
Action: PolicyActionList,
Result: rbacutils.Allow,
},
{
/*{
Service: api.SERVICE_TYPE,
Resource: "networks",
Action: PolicyActionGet,
@@ -323,6 +323,7 @@ var (
Action: PolicyActionList,
Result: rbacutils.Allow,
},
*/
},
},
}

View File

@@ -127,6 +127,10 @@ func (self *SHuaWeiRegionDriver) ValidateCreateLoadbalancerData(ctx context.Cont
return nil, fmt.Errorf("eip external id is empty")
}
if eip.ManagerId != vpc.ManagerId {
return nil, httperrors.NewInputParameterError("eip's manager (%s(%s)) does not match vpc's(%s(%s)) (%s)", eip.GetName(), eip.GetId(), vpc.GetName(), vpc.GetId(), vpc.ManagerId)
}
data.Set("eip_id", jsonutils.NewString(eip.ExternalId))
}

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