Compare commits

...

62 Commits

Author SHA1 Message Date
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
129 changed files with 1754 additions and 524 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

@@ -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

@@ -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

@@ -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"`

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

@@ -1953,6 +1953,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

@@ -487,6 +487,7 @@ type ICloudHostNetInterface interface {
GetIpAddr() string
GetMtu() int32
GetNicType() string
GetBridge() string
}
type ICloudLoadbalancer interface {

View File

@@ -650,15 +650,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

@@ -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

@@ -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",

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 {

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])

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

@@ -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

@@ -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,7 +451,6 @@ 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()
@@ -476,19 +475,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 +521,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,10 +599,14 @@ 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")))
@@ -589,10 +639,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 +656,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 +663,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

@@ -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))
}

View File

@@ -58,7 +58,12 @@ func (self *BaremetalDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneM
}
func (self *BaremetalDeleteTask) OnDeleteBaremetalComplete(ctx context.Context, baremetal *models.SHost, body jsonutils.JSONObject) {
baremetal.RealDelete(ctx, self.UserCred)
err := baremetal.RealDelete(ctx, self.UserCred)
if err != nil {
log.Errorln("RealDelete fail %s", err)
self.OnFailure(ctx, baremetal, jsonutils.Marshal(err))
return
}
self.SetStageComplete(ctx, nil)
}

View File

@@ -101,10 +101,13 @@ func (self *DiskDeleteTask) startDeleteDisk(ctx context.Context, disk *models.SD
)
storage = disk.GetStorage()
if storage != nil {
host = storage.GetMasterHost()
if storage == nil { // dirty data
self.OnGuestDiskDeleteComplete(ctx, disk, nil)
return
}
host = storage.GetMasterHost()
isPurge := false
if (host == nil || !host.GetEnabled()) && jsonutils.QueryBoolean(self.Params, "purge", false) {
isPurge = true
@@ -112,21 +115,25 @@ func (self *DiskDeleteTask) startDeleteDisk(ctx context.Context, disk *models.SD
disk.SetStatus(self.UserCred, api.DISK_DEALLOC, "")
if isPurge {
self.OnGuestDiskDeleteComplete(ctx, disk, nil)
return
}
if isNeed, _ := disk.IsNeedWaitSnapshotsDeleted(); isNeed { // for kvm rbd disk
self.OnGuestDiskDeleteComplete(ctx, disk, nil)
return
}
if len(disk.BackupStorageId) > 0 {
self.SetStage("OnMasterStorageDeleteDiskComplete", nil)
} else {
if isNeed, _ := disk.IsNeedWaitSnapshotsDeleted(); isNeed {
self.OnGuestDiskDeleteComplete(ctx, disk, nil)
return
}
if len(disk.BackupStorageId) > 0 {
self.SetStage("OnMasterStorageDeleteDiskComplete", nil)
} else {
self.SetStage("OnGuestDiskDeleteComplete", nil)
}
if host == nil {
self.OnGuestDiskDeleteCompleteFailed(ctx, disk, jsonutils.NewString("fail to find master host"))
} else if err := host.GetHostDriver().RequestDeallocateDiskOnHost(ctx, host, storage, disk, self); err != nil {
self.OnGuestDiskDeleteCompleteFailed(ctx, disk, jsonutils.NewString(err.Error()))
}
self.SetStage("OnGuestDiskDeleteComplete", nil)
}
if host == nil {
self.OnGuestDiskDeleteCompleteFailed(ctx, disk, jsonutils.NewString("fail to find master host"))
return
}
err := host.GetHostDriver().RequestDeallocateDiskOnHost(ctx, host, storage, disk, self)
if err != nil {
self.OnGuestDiskDeleteCompleteFailed(ctx, disk, jsonutils.NewString(err.Error()))
return
}
}

View File

@@ -127,6 +127,10 @@ func (self *GuestDeleteBackupTask) OnDeleteBackupComplete(ctx context.Context, g
}
func (self *GuestDeleteBackupTask) TaskComplete(ctx context.Context, guest *models.SGuest, data jsonutils.JSONObject) {
guest.RemoveMetadata(ctx, "switch_backup", self.UserCred)
guest.RemoveMetadata(ctx, "switch_backup_count", self.UserCred)
guest.RemoveMetadata(ctx, "create_backup", self.UserCred)
guest.RemoveMetadata(ctx, "create_backup_count", self.UserCred)
self.OnDeleteBackupComplete(ctx, guest, data)
self.SetStageComplete(ctx, nil)
}

View File

@@ -174,8 +174,12 @@ func (self *GuestDeleteTask) doClearSecurityGroupComplete(ctx context.Context, g
models.IsolatedDeviceManager.ReleaseDevicesOfGuest(ctx, guest, self.UserCred)
guest.RevokeAllSecgroups(ctx, self.UserCred)
// sync revoked secgroups to remote cloud
self.SetStage("OnSyncConfigComplete", nil)
guest.StartSyncTaskWithoutSyncstatus(ctx, self.UserCred, false, self.GetTaskId())
if jsonutils.QueryBoolean(self.Params, "purge", false) {
self.OnSyncConfigComplete(ctx, guest, nil)
} else {
self.SetStage("OnSyncConfigComplete", nil)
guest.StartSyncTaskWithoutSyncstatus(ctx, self.UserCred, false, self.GetTaskId())
}
}
func (self *GuestDeleteTask) OnSyncConfigComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {

View File

@@ -371,7 +371,7 @@ func getDomainGeneralUsage(scope rbacutils.TRbacScope, cred mcclient.IIdentityPr
BucketUsage(scope, cred, rangeObjs, providers, brands, cloudEnv),
nicsUsage(rangeObjs, hostTypes, providers, brands, cloudEnv, scope, cred),
nicsUsage("domain", rangeObjs, hostTypes, providers, brands, cloudEnv, scope, cred),
SnapshotUsage(scope, cred, rangeObjs, providers, brands, cloudEnv),
@@ -413,7 +413,7 @@ func getProjectGeneralUsage(scope rbacutils.TRbacScope, cred mcclient.IIdentityP
DisksUsage(getKey(scope, "pending_delete_disks"), rangeObjs, hostTypes, nil, providers, brands, cloudEnv, scope, cred, true, false),
DisksUsage(getKey(scope, "pending_delete_disks.system"), rangeObjs, hostTypes, nil, providers, brands, cloudEnv, scope, cred, true, true),
nicsUsage(rangeObjs, hostTypes, providers, brands, cloudEnv, scope, cred),
nicsUsage("", rangeObjs, hostTypes, providers, brands, cloudEnv, scope, cred),
SnapshotUsage(scope, cred, rangeObjs, providers, brands, cloudEnv),
@@ -601,35 +601,37 @@ func DisksUsage(
func WireUsage(rangeObjs []db.IStandaloneModel, hostTypes []string, providers []string, brands []string, cloudEnv string) Usage {
count := make(map[string]interface{})
result := models.WireManager.TotalCount(rangeObjs, hostTypes, providers, brands, cloudEnv, rbacutils.ScopeSystem, nil, false)
result := models.WireManager.TotalCount(rangeObjs, hostTypes, providers, brands, cloudEnv, rbacutils.ScopeSystem, nil)
count["wires"] = result.WiresCount - result.EmulatedWiresCount
count["networks"] = result.NetCount
// include nics for pending_deleted guests
count["all.nics.guest"] = result.GuestNicCount
// nics for pending_deleted guests
count["all.nics.guest.pending_delete"] = result.PendingDeletedGuestNicCount
count["all.nics.host"] = result.HostNicCount
count["all.nics.reserve"] = result.ReservedCount
count["all.nics.group"] = result.GroupNicCount
count["all.nics.lb"] = result.LbNicCount
count["all.nics.eip"] = result.EipNicCount
count["all.nics.netif"] = result.NetifNicCount
count["all.nics.db"] = result.DbNicCount
count["all.nics"] = result.NicCount()
result = models.WireManager.TotalCount(rangeObjs, hostTypes, providers, brands, cloudEnv, rbacutils.ScopeSystem, nil, true)
count["all.nics.guest.pending_delete"] = result.GuestNicCount
count["all.nics.lb.pending_delete"] = result.LbNicCount
count["all.nics.pending_delete"] = result.GuestNicCount + result.LbNicCount
return count
}
func nicsUsage(rangeObjs []db.IStandaloneModel, hostTypes []string, providers []string, brands []string, cloudEnv string, scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider) Usage {
func nicsUsage(prefix string, rangeObjs []db.IStandaloneModel, hostTypes []string, providers []string, brands []string, cloudEnv string, scope rbacutils.TRbacScope, ownerId mcclient.IIdentityProvider) Usage {
count := make(map[string]interface{})
result := models.WireManager.TotalCount(rangeObjs, hostTypes, providers, brands, cloudEnv, scope, ownerId, false)
count["nics.guest"] = result.GuestNicCount
count["nics.group"] = result.GroupNicCount
count["nics.lb"] = result.LbNicCount
count["nics"] = result.GuestNicCount + result.GroupNicCount + result.LbNicCount
result = models.WireManager.TotalCount(rangeObjs, hostTypes, providers, brands, cloudEnv, scope, ownerId, true)
count["nics.guest.pending_delete"] = result.GuestNicCount
count["nics.lb.pending_delete"] = result.LbNicCount
count["nics.pending_delete"] = result.GuestNicCount + result.LbNicCount
result := models.WireManager.TotalCount(rangeObjs, hostTypes, providers, brands, cloudEnv, scope, ownerId)
// including nics for pending_deleted guests
count[prefixKey(prefix, "nics.guest")] = result.GuestNicCount
// #nics for pending_deleted guests
count[prefixKey(prefix, "nics.guest.pending_delete")] = result.PendingDeletedGuestNicCount
count[prefixKey(prefix, "nics.group")] = result.GroupNicCount
count[prefixKey(prefix, "nics.lb")] = result.LbNicCount
count[prefixKey(prefix, "nics.db")] = result.DbNicCount
count[prefixKey(prefix, "nics.eip")] = result.EipNicCount
count[prefixKey(prefix, "nics")] = result.GuestNicCount + result.GroupNicCount + result.LbNicCount + result.DbNicCount + result.EipNicCount
return count
}

View File

@@ -21,8 +21,8 @@ import (
)
type IDisk interface {
Connect() bool
Disconnect() bool
Connect() error
Disconnect() error
MountRootfs() fsdriver.IRootFsDriver
UmountRootfs(driver fsdriver.IRootFsDriver)
}

View File

@@ -24,6 +24,7 @@ import (
"time"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/hostman/diskutils/nbd"
"yunion.io/x/onecloud/pkg/hostman/guestfs"
@@ -62,15 +63,10 @@ func (d *SKVMGuestDisk) IsLVMPartition() bool {
return len(d.lvms) > 0
}
func (d *SKVMGuestDisk) ConnectWithoutDetectLvm() bool {
return d.connect()
}
func (d *SKVMGuestDisk) connect() bool {
func (d *SKVMGuestDisk) connect() error {
d.nbdDev = nbd.GetNBDManager().AcquireNbddev()
if len(d.nbdDev) == 0 {
log.Errorln("Cannot get nbd device")
return false
return errors.Errorf("Cannot get nbd device")
}
var cmd []string
@@ -80,14 +76,14 @@ func (d *SKVMGuestDisk) connect() bool {
err := procutils.NewRemoteCommandAsFarAsPossible("mkdir", "-p", "/etc/ceph").Run()
if err != nil {
log.Errorf("Failed to mkdir /etc/ceph: %s", err)
return false
return errors.Wrap(err, "Failed to mkdir /etc/ceph: %s")
}
err = procutils.NewRemoteCommandAsFarAsPossible("test", "-f", "/etc/ceph/ceph.conf").Run()
if err != nil {
err = procutils.NewRemoteCommandAsFarAsPossible("touch", "/etc/ceph/ceph.conf").Run()
if err != nil {
log.Errorf("failed to create /etc/ceph/ceph.conf: %s", err)
return false
return errors.Wrap(err, "failed to create /etc/ceph/ceph.conf")
}
}
}
@@ -95,10 +91,10 @@ func (d *SKVMGuestDisk) connect() bool {
} else {
cmd = []string{qemutils.GetQemuNbd(), "-c", d.nbdDev, d.imagePath}
}
_, err := procutils.NewRemoteCommandAsFarAsPossible(cmd[0], cmd[1:]...).Output()
output, err := procutils.NewRemoteCommandAsFarAsPossible(cmd[0], cmd[1:]...).Output()
if err != nil {
log.Errorln(err.Error())
return false
log.Errorf("qemu-nbd connect failed %s %s", output, err.Error())
return errors.Wrapf(err, "qemu-nbd connect failed %s", output)
}
var tried uint = 0
@@ -107,31 +103,37 @@ func (d *SKVMGuestDisk) connect() bool {
err = d.findPartitions()
if err != nil {
log.Errorln(err.Error())
return false
return err
}
tried += 1
}
return true
return nil
}
func (d *SKVMGuestDisk) Connect() bool {
func (d *SKVMGuestDisk) Connect() error {
pathType := d.connectionPrecheck()
if d.connect() == false {
return false
if err := d.connect(); err != nil {
return errors.Wrap(err, "disk.connect")
}
if pathType == LVM_PATH {
d.setupLVMS()
if _, err := d.setupLVMS(); err != nil {
return err
}
} else if pathType == PATH_TYPE_UNKNOWN {
hasLVM, err := d.setupLVMS()
if err != nil {
return err
}
// no lvm partition found and has partitions
if !hasLVM && err == nil && len(d.partitions) > 0 {
if !hasLVM && len(d.partitions) > 0 {
d.cacheNonLVMImagePath()
}
}
return true
return nil
}
func (d *SKVMGuestDisk) getImageFormat() string {
@@ -156,7 +158,7 @@ func (d *SKVMGuestDisk) findPartitions() error {
devpath := filepath.Dir(d.nbdDev)
files, err := ioutil.ReadDir(devpath)
if err != nil {
return err
return errors.Wrapf(err, "read dir %s", devpath)
}
for i := 0; i < len(files); i++ {
if files[i].Name() != dev && strings.HasPrefix(files[i].Name(), dev+"p") {
@@ -264,30 +266,26 @@ func (d *SKVMGuestDisk) PutdownLVMs() {
d.lvms = []*SKVMGuestLVMPartition{}
}
func (d *SKVMGuestDisk) DisconnectWithoutLvm() bool {
return d.disconnect()
}
func (d *SKVMGuestDisk) Disconnect() bool {
func (d *SKVMGuestDisk) Disconnect() error {
if len(d.nbdDev) > 0 {
defer d.LvmDisconnectNotify()
d.PutdownLVMs()
return d.disconnect()
} else {
return false
return nil
}
}
func (d *SKVMGuestDisk) disconnect() bool {
_, err := procutils.NewRemoteCommandAsFarAsPossible(qemutils.GetQemuNbd(), "-d", d.nbdDev).Output()
func (d *SKVMGuestDisk) disconnect() error {
output, err := procutils.NewRemoteCommandAsFarAsPossible(qemutils.GetQemuNbd(), "-d", d.nbdDev).Output()
if err != nil {
log.Errorln(err.Error())
return false
return errors.Wrapf(err, "qemu-nbd disconnect %s", output)
}
nbd.GetNBDManager().ReleaseNbddev(d.nbdDev)
d.nbdDev = ""
d.partitions = d.partitions[len(d.partitions):]
return true
return nil
}
@@ -347,6 +345,9 @@ func (d *SKVMGuestDisk) UmountKvmRootfs(fd fsdriver.IRootFsDriver) {
}
func (d *SKVMGuestDisk) UmountRootfs(fd fsdriver.IRootFsDriver) {
if fd == nil {
return
}
d.UmountKvmRootfs(fd)
}

View File

@@ -60,6 +60,8 @@ type VDDKDisk struct {
PartDirs []string
Proc *Command
Pid int
kvmDisk *SKVMGuestDisk
}
func NewVDDKDisk(vddkInfo *apis.VDDKConInfo, diskPath string) *VDDKDisk {
@@ -132,43 +134,36 @@ func logpath(pid int) string {
return fmt.Sprintf("%s/vixDiskLib-%d.log", TMPDIR, pid)
}
func (vd *VDDKDisk) Connect() bool {
return true
func (vd *VDDKDisk) Connect() error {
flatFile, err := vd.ConnectBlockDevice()
if err != nil {
return err
}
vd.kvmDisk = NewKVMGuestDisk(flatFile)
return vd.kvmDisk.Connect()
}
func (vd *VDDKDisk) Disconnect() bool {
return true
func (vd *VDDKDisk) Disconnect() error {
if vd.kvmDisk != nil {
if err := vd.kvmDisk.Disconnect(); err != nil {
log.Errorf("kvm disk disconnect failed %s", err)
}
}
return vd.DisconnectBlockDevice()
}
func (vd *VDDKDisk) MountRootfs() fsdriver.IRootFsDriver {
var err error
if err = vd.Mount(); err == nil {
for _, mntPath := range vd.PartDirs {
part := newVDDKPartition(mntPath)
if fs := guestfs.DetectRootFs(part); fs != nil {
log.Infof("Use rootfs %s", fs)
return fs
}
}
if vd.kvmDisk == nil {
return nil
}
if err != nil {
log.Errorf("VDDKDisk Mount failed: %s", err)
}
// something is wrong
if vd.Proc != nil {
err := vd.Proc.Kill()
if err != nil {
log.Errorf("unable to kill proc: %s", err.Error())
}
}
return nil
return vd.kvmDisk.MountRootfs()
}
func (vd *VDDKDisk) UmountRootfs(fd fsdriver.IRootFsDriver) {
err := vd.Umount()
if err != nil {
log.Errorf("VDDKDisk Umount failed: %s", err)
if vd.kvmDisk == nil {
return
}
vd.kvmDisk.UmountRootfs(fd)
}
func (vd *VDDKDisk) ParsePartitions(buf string) error {
@@ -275,6 +270,7 @@ func (vd *VDDKDisk) ExecProg() error {
}
cmd := NewCommand(execpath(), "-info", "-host", vd.Host, "-port", strconv.Itoa(vd.Port), "-user", vd.User,
"-password", vd.Passwd, "-mode", "nbd", "-thumb", thumb, "-vm", fmt.Sprintf("moref=%s", vd.VmRef), vd.DiskPath)
log.Debugf("command to mount: %s", cmd)
env := os.Environ()
env = append(env, fmt.Sprintf("LD_LIBRARY_PATH=%s", libdir()))
cmd.Env = env
@@ -321,7 +317,7 @@ func (vd *VDDKDisk) getServerCertThumbSha1(addr string) (string, error) {
func (vd *VDDKDisk) WaitMounted() error {
endStr := []byte("Do you want to procede to unmount the volume")
timeout := 30 * time.Second
timeout := 300 * time.Second
endClock := time.After(timeout)
isEnd := false
@@ -349,13 +345,16 @@ Loop:
}
if vd.Proc.Exited() {
retCode := vd.Proc.ProcessState.ExitCode()
// ignore the error
vd.Proc.Kill()
vd.Proc = nil
err := vd.Proc.Kill()
if err != nil {
log.Errorf("unable to kill process '%d'", vd.Proc.Process.Pid)
}
return errors.Error(fmt.Sprintf("VDDKDisk prog exit error(%d): %s", retCode, backup))
} else if !isEnd {
// timeout
vd.Proc.Kill()
err := vd.Proc.Kill()
if err != nil {
log.Errorf("unable to kill process '%d'", vd.Proc.Process.Pid)
}
return errors.Error(fmt.Sprintf("VDDKDisk read timeout, program blocked"))
}
return nil

View File

@@ -49,6 +49,8 @@ const CENTOS_VGNAME = "centos"
type DeployerServer struct{}
var _ deployapi.DeployAgentServer = &DeployerServer{}
func (*DeployerServer) DeployGuestFs(ctx context.Context, req *deployapi.DeployParams,
) (res *deployapi.DeployGuestFsResponse, err error) {
// There will be some occasional unknown panic, so temporarily capture panic here.
@@ -63,22 +65,22 @@ func (*DeployerServer) DeployGuestFs(ctx context.Context, req *deployapi.DeployP
res, err = nil, errors.Error(msg)
}
}()
log.Infof("Deploy guest fs on %s", req.DiskPath)
log.Infof("********* Deploy guest fs on %s", req.DiskPath)
var disk = diskutils.GetIDisk(req)
if len(req.GuestDesc.Hypervisor) == 0 {
req.GuestDesc.Hypervisor = comapi.HYPERVISOR_KVM
}
defer disk.Disconnect()
if !disk.Connect() {
log.Infof("Failed to connect %s disk", req.GuestDesc.Hypervisor)
if err := disk.Connect(); err != nil {
log.Infof("Failed to connect %s disk: %s", req.GuestDesc.Hypervisor, err)
return new(deployapi.DeployGuestFsResponse), nil
}
root := disk.MountRootfs()
defer disk.UmountRootfs(root)
if root == nil {
log.Infof("Failed mounting rootfs for %s disk", req.GuestDesc.Hypervisor)
return new(deployapi.DeployGuestFsResponse), nil
}
defer disk.UmountRootfs(root)
ret, err := guestfs.DoDeployGuestFs(root, req.GuestDesc, req.DeployInfo)
if err != nil {
@@ -92,11 +94,11 @@ func (*DeployerServer) DeployGuestFs(ctx context.Context, req *deployapi.DeployP
func (*DeployerServer) ResizeFs(ctx context.Context, req *deployapi.ResizeFsParams,
) (*deployapi.Empty, error) {
log.Infof("Resize fs on %s", req.DiskPath)
log.Infof("********* Resize fs on %s", req.DiskPath)
disk := diskutils.NewKVMGuestDisk(req.DiskPath)
defer disk.Disconnect()
if !disk.Connect() {
return new(deployapi.Empty), errors.Error("resize fs disk connect failed")
if err := disk.Connect(); err != nil {
return new(deployapi.Empty), errors.Wrap(err, "disk connect failed")
}
root := disk.MountKvmRootfs()
@@ -116,10 +118,10 @@ func (*DeployerServer) ResizeFs(ctx context.Context, req *deployapi.ResizeFsPara
}
func (*DeployerServer) FormatFs(ctx context.Context, req *deployapi.FormatFsParams) (*deployapi.Empty, error) {
log.Infof("Format fs on %s", req.DiskPath)
log.Infof("********* Format fs on %s", req.DiskPath)
gd := diskutils.NewKVMGuestDisk(req.DiskPath)
defer gd.Disconnect()
if gd.Connect() {
if err := gd.Connect(); err == nil {
if err := gd.MakePartition(req.FsFormat); err == nil {
err = gd.FormatPartition(req.FsFormat, req.Uuid)
if err != nil {
@@ -128,19 +130,23 @@ func (*DeployerServer) FormatFs(ctx context.Context, req *deployapi.FormatFsPara
} else {
return new(deployapi.Empty), err
}
} else {
log.Errorf("failed connect kvm disk %s: %s", req.DiskPath, err)
}
return new(deployapi.Empty), nil
}
func (*DeployerServer) SaveToGlance(ctx context.Context, req *deployapi.SaveToGlanceParams) (*deployapi.SaveToGlanceResponse, error) {
log.Infof("%s save to glance", req.DiskPath)
log.Infof("********* %s save to glance", req.DiskPath)
var (
kvmDisk = diskutils.NewKVMGuestDisk(req.DiskPath)
osInfo string
relInfo *deployapi.ReleaseInfo
)
defer kvmDisk.Disconnect()
if kvmDisk.Connect() {
if err := kvmDisk.Connect(); err != nil {
log.Errorf("failed connect kvm disk %s: %s", req.DiskPath, err)
} else {
var err error
func() {
if root := kvmDisk.MountKvmRootfs(); root != nil {
@@ -182,11 +188,11 @@ func getImageInfo(kvmDisk *diskutils.SKVMGuestDisk, rootfs fsdriver.IRootFsDrive
}
func (*DeployerServer) ProbeImageInfo(ctx context.Context, req *deployapi.ProbeImageInfoPramas) (*deployapi.ImageInfo, error) {
log.Infof("%s probe image info", req.DiskPath)
log.Infof("********* %s probe image info", req.DiskPath)
kvmDisk := diskutils.NewKVMGuestDisk(req.DiskPath)
defer kvmDisk.Disconnect()
if !kvmDisk.Connect() {
log.Infof("Failed to connect kvm disk")
if err := kvmDisk.Connect(); err != nil {
log.Infof("Failed to connect kvm disk %s: %s", req.DiskPath, err)
return new(deployapi.ImageInfo), errors.Error("Disk connector failed to connect image")
}
@@ -206,7 +212,7 @@ var connectedEsxiDisks = map[string]*diskutils.VDDKDisk{}
func (*DeployerServer) ConnectEsxiDisks(
ctx context.Context, req *deployapi.ConnectEsxiDisksParams,
) (*deployapi.EsxiDisksConnectionInfo, error) {
log.Infof("Connect esxi disks ...")
log.Infof("********* Connect esxi disks ...")
var (
err error
flatFilePath string
@@ -241,7 +247,7 @@ func (*DeployerServer) ConnectEsxiDisks(
func (*DeployerServer) DisconnectEsxiDisks(
ctx context.Context, req *deployapi.EsxiDisksConnectionInfo,
) (*deployapi.Empty, error) {
log.Infof("Disconnect esxi disks ...")
log.Infof("********* Disconnect esxi disks ...")
for i := 0; i < len(req.Disks); i++ {
if disk, ok := connectedEsxiDisks[req.Disks[i].DiskPath]; ok {
if e := disk.DisconnectBlockDevice(); e != nil {

View File

@@ -757,6 +757,7 @@ func (h *SHostInfo) tryCreateNetworkOnWire() {
params.Set("mask", jsonutils.NewInt(int64(mask)))
params.Set("is_on_premise", jsonutils.JSONTrue)
params.Set("server_type", jsonutils.NewString(api.NETWORK_TYPE_BAREMETAL))
params.Set("is_on_premise", jsonutils.JSONTrue)
ret, err := modules.Networks.PerformClassAction(
hostutils.GetComputeSession(context.Background()),
"try-create-network", params)
@@ -1295,6 +1296,9 @@ func (h *SHostInfo) onGetStorageInfoSucc(hoststorages []jsonutils.JSONObject) {
func (h *SHostInfo) uploadStorageInfo() {
for _, s := range storageman.GetManager().Storages {
if err := s.SetStorageInfo(s.GetId(), s.GetStorageName(), s.GetStorageConf()); err != nil {
h.onFail(err)
}
res, err := s.SyncStorageInfo()
if err != nil {
h.onFail(err)

View File

@@ -262,6 +262,7 @@ func (s *SBaseStorage) bindMountTo(sPath string) error {
return errors.Errorf("bind mount temp path to local image path failed %s", out)
}
}
log.Infof("bind mount %s -> %s", tempPath, sPath)
return nil
}

View File

@@ -66,7 +66,7 @@ func storageVerifyMountPoint(ctx context.Context, w http.ResponseWriter, r *http
hostutils.Response(ctx, w, httperrors.NewMissingParameterError("mount_point"))
return
}
output, err := procutils.NewCommand("mountpoint", mountPoint).Output()
output, err := procutils.NewRemoteCommandAsFarAsPossible("mountpoint", mountPoint).Output()
if err == nil {
appsrv.SendStruct(w, map[string]interface{}{"is_mount_point": true})
} else {

View File

@@ -603,6 +603,16 @@ func (self *SImage) ValidateUpdateData(ctx context.Context, userCred mcclient.To
if appParams != nil && appParams.Request.ContentLength > 0 {
return nil, httperrors.NewInvalidStatusError("cannot upload in status %s", self.Status)
}
if minDiskSize, err := data.Int("min_disk"); err == nil {
img, err := qemuimg.NewQemuImage(self.getLocalLocation())
if err != nil {
return nil, errors.Wrap(err, "open image")
}
virtualSizeMB := img.SizeBytes / 1024 / 1024
if virtualSizeMB > 0 && minDiskSize < virtualSizeMB {
return nil, httperrors.NewBadRequestError("min disk size must >= %v", virtualSizeMB)
}
}
} else {
appParams := appsrv.AppContextGetParams(ctx)
if appParams != nil {
@@ -654,7 +664,6 @@ func (self *SImage) ValidateUpdateData(ctx context.Context, userCred mcclient.To
return nil, errors.Wrap(err, "SSharableVirtualResourceBase.ValidateUpdateData")
}
data.Update(jsonutils.Marshal(input))
return data, nil
}

View File

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

View File

@@ -132,9 +132,16 @@ func (manager *SIdentityBaseResourceManager) ListItemFilter(
}
// override manager.SDomainizedResourceBaseManager.ListItemFilter()
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)
}
}
domains := DomainManager.Query().SubQuery()
subq := domains.Query(domains.Field("id")).Filter(sqlchemy.OR(
sqlchemy.In(domains.Field("id"), query.ProjectDomains),
sqlchemy.In(domains.Field("id"), idList),
sqlchemy.In(domains.Field("name"), query.ProjectDomains),
))
q = q.In("domain_id", subq.SubQuery())

View File

@@ -263,9 +263,9 @@ func (policy *SPolicy) Delete(ctx context.Context, userCred mcclient.TokenCreden
}
func (policy *SPolicy) ValidateDeleteCondition(ctx context.Context) error {
if policy.IsShared() {
return httperrors.NewInvalidStatusError("cannot delete shared policy")
}
// if policy.IsShared() {
// return httperrors.NewInvalidStatusError("cannot delete shared policy")
// }
if policy.Enabled.IsTrue() {
return httperrors.NewInvalidStatusError("cannot delete enabled policy")
}

View File

@@ -188,9 +188,9 @@ func (role *SRole) IsSystemRole() bool {
}
func (role *SRole) ValidateDeleteCondition(ctx context.Context) error {
if role.IsShared() {
return httperrors.NewInvalidStatusError("cannot delete shared role")
}
// if role.IsShared() {
// return httperrors.NewInvalidStatusError("cannot delete shared role")
// }
if role.IsSystemRole() {
return httperrors.NewForbiddenError("cannot delete system role")
}

View File

@@ -174,6 +174,7 @@ func (self *SAwsClient) CreateClouduser(path string, username string) (*SCloudus
}
func (self *SAwsClient) DeleteClouduser(name string) error {
self.DeleteLoginProfile(name)
params := map[string]string{
"UserName": name,
}

View File

@@ -20,6 +20,7 @@ import (
"github.com/vmware/govmomi/vim25/types"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
)
@@ -144,15 +145,25 @@ func NewUSBController(key *int32) types.BaseVirtualDevice {
return &device
}
func NewVNICDev(host *SHost, mac, driver string, vlanId int32, key, ctlKey, index int32) (types.BaseVirtualDevice, error) {
func NewVNICDev(host *SHost, mac, driver string, bridge string, vlanId int32, key, ctlKey, index int32) (types.BaseVirtualDevice, error) {
desc := types.Description{Label: fmt.Sprintf("Network adapter %d", index+1), Summary: "VM Network"}
inet, err := host.FindNetworkByVlanID(vlanId)
if err != nil {
return nil, errors.Wrap(err, "SHost.FindNetworkByVlanID")
var inet IVMNetwork
var err error
if (vlanId == 0 || vlanId == 1) && len(bridge) > 0 {
inet, err = host.findDVPGById(bridge)
if err != nil {
log.Errorf("fail to find dvportgroup by name %s: %s", bridge, err)
}
}
if inet == nil || reflect.ValueOf(inet).IsNil() {
return nil, errors.Error(fmt.Sprintf("VLAN %d not found", vlanId))
inet, err = host.FindNetworkByVlanID(vlanId)
if err != nil {
log.Errorf("fail to find network by vlanid %d: %s", vlanId, err)
}
}
if inet == nil || reflect.ValueOf(inet).IsNil() {
return nil, errors.Error(fmt.Sprintf("Brige %s VLAN %d not found", bridge, vlanId))
}
var (

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