mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-21 00:24:07 +08:00
Compare commits
192 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a0de53ff4 | ||
|
|
d9228f48f4 | ||
|
|
a6bb678825 | ||
|
|
41b4f563ee | ||
|
|
5a0a5ce6df | ||
|
|
d8b4d7a67e | ||
|
|
f7c84dae72 | ||
|
|
55cf0490fb | ||
|
|
da3eb1c0cc | ||
|
|
a8ab578435 | ||
|
|
d065967a4d | ||
|
|
12c67469c0 | ||
|
|
80aebbd93f | ||
|
|
f1c72e3968 | ||
|
|
31d75e333e | ||
|
|
d4834cb921 | ||
|
|
3bd65036dc | ||
|
|
104855a5d0 | ||
|
|
789273b44a | ||
|
|
d386e18006 | ||
|
|
2327bbee3b | ||
|
|
cda399984e | ||
|
|
2fc8014ea8 | ||
|
|
248e29bc12 | ||
|
|
91c892ba5e | ||
|
|
4c25401b4e | ||
|
|
13cde27dd2 | ||
|
|
10d45453c6 | ||
|
|
8281682aa8 | ||
|
|
8347f82273 | ||
|
|
b8f1f88ce0 | ||
|
|
fbdc4c23ac | ||
|
|
fc677ebf9f | ||
|
|
e25f8965c4 | ||
|
|
5b233c034b | ||
|
|
3ec3ded4c6 | ||
|
|
531fc24b81 | ||
|
|
942e9ef018 | ||
|
|
5348ff5d32 | ||
|
|
cbee060b46 | ||
|
|
1689e5adb5 | ||
|
|
5322c9032e | ||
|
|
420dcc5fef | ||
|
|
105203f647 | ||
|
|
9874c7e025 | ||
|
|
882d3f1060 | ||
|
|
97035e5f4f | ||
|
|
0ddf85a4bb | ||
|
|
d1bd8386f2 | ||
|
|
9b5d058c50 | ||
|
|
215e799dc8 | ||
|
|
9f0268595f | ||
|
|
2cdad90aec | ||
|
|
f0dc331816 | ||
|
|
619a1f144f | ||
|
|
1b74a6991f | ||
|
|
1d71fe001d | ||
|
|
9cd5d5e837 | ||
|
|
3645fae170 | ||
|
|
1d54481ce0 | ||
|
|
a3cd175b07 | ||
|
|
3c297a80a6 | ||
|
|
0bacd80fe9 | ||
|
|
ca9d22cee2 | ||
|
|
46385862cd | ||
|
|
a171fabdcf | ||
|
|
9542fce75e | ||
|
|
398a41c8fb | ||
|
|
8ef4320fc3 | ||
|
|
d5d787a83f | ||
|
|
2a4e71f582 | ||
|
|
d8cd974bf8 | ||
|
|
68742276da | ||
|
|
3cf56271e9 | ||
|
|
84f44eec0b | ||
|
|
050b787239 | ||
|
|
79f7bced43 | ||
|
|
4a639991a5 | ||
|
|
ff97f1d166 | ||
|
|
bd860493b9 | ||
|
|
2e02dc2706 | ||
|
|
238e1bc33d | ||
|
|
ab4914bdca | ||
|
|
cdb7fc3797 | ||
|
|
39ca020010 | ||
|
|
9160bf1409 | ||
|
|
46ed9c2c37 | ||
|
|
4dc5a5e2cf | ||
|
|
bbed5b4f23 | ||
|
|
bfe7c55eb1 | ||
|
|
8eb2771c12 | ||
|
|
678bae183a | ||
|
|
a7bd9e8454 | ||
|
|
5a33659855 | ||
|
|
026f7054a6 | ||
|
|
963373cd5f | ||
|
|
80e86fc5e1 | ||
|
|
220ab59785 | ||
|
|
4fc2f15b0c | ||
|
|
04a797e615 | ||
|
|
a5734f9ab0 | ||
|
|
e373214631 | ||
|
|
c88235c4a6 | ||
|
|
4dd5b2ac87 | ||
|
|
5d6eef1fd7 | ||
|
|
5983c54047 | ||
|
|
16a29bef6a | ||
|
|
976b638673 | ||
|
|
3bd60993e7 | ||
|
|
190738d607 | ||
|
|
b956548556 | ||
|
|
54b3650fdf | ||
|
|
996f6cd77c | ||
|
|
fa45bdb1c7 | ||
|
|
a0c1dcda29 | ||
|
|
e216c27c11 | ||
|
|
eab54544e5 | ||
|
|
ecd5508c59 | ||
|
|
0afd30cc3e | ||
|
|
682211292d | ||
|
|
026e469bc6 | ||
|
|
48d761169c | ||
|
|
ec3489e5b7 | ||
|
|
3d862a0cd6 | ||
|
|
8c5199ae84 | ||
|
|
db90c90dda | ||
|
|
0512c1a6a2 | ||
|
|
30f2619fd8 | ||
|
|
340cf2fab9 | ||
|
|
49e1495417 | ||
|
|
63b9bb0167 | ||
|
|
d94ca385bb | ||
|
|
2b107a960d | ||
|
|
9de7364d38 | ||
|
|
282cbb1624 | ||
|
|
97a18aaed9 | ||
|
|
a208f0afb7 | ||
|
|
f2070dc854 | ||
|
|
9cc78f1463 | ||
|
|
828643166d | ||
|
|
99f5ecd6ff | ||
|
|
d061c10c3b | ||
|
|
dbd94a1233 | ||
|
|
f66242d72e | ||
|
|
1a7ad83012 | ||
|
|
fb4f8d225b | ||
|
|
1d8009083a | ||
|
|
56b1d9e7fb | ||
|
|
0dbbd1c4fc | ||
|
|
e6e6e2c52e | ||
|
|
856bff47c3 | ||
|
|
33579abeb3 | ||
|
|
60e146063c | ||
|
|
7e04045903 | ||
|
|
12ddc552c7 | ||
|
|
19227df5fb | ||
|
|
3d9a825243 | ||
|
|
5796950b1b | ||
|
|
739eba5e8d | ||
|
|
81992ba365 | ||
|
|
9492e3aa20 | ||
|
|
13948c87f7 | ||
|
|
b2867062bc | ||
|
|
3e60efb32c | ||
|
|
7fa7cc47fa | ||
|
|
65b01af572 | ||
|
|
668cc71e30 | ||
|
|
837f40a3ad | ||
|
|
74140324cb | ||
|
|
f4fc88fc74 | ||
|
|
fce049d24a | ||
|
|
d2415d0033 | ||
|
|
a595c08b84 | ||
|
|
507c2922ec | ||
|
|
42bf085392 | ||
|
|
99b41a4d4c | ||
|
|
732c415be7 | ||
|
|
aa2d90fd3f | ||
|
|
09650b6cfd | ||
|
|
c217f1d800 | ||
|
|
f68d01fbce | ||
|
|
f1c6ca31ee | ||
|
|
67cde45a12 | ||
|
|
8fcdaf128a | ||
|
|
c24f5b0569 | ||
|
|
d36beabe00 | ||
|
|
967624a3b7 | ||
|
|
3d933429eb | ||
|
|
eb29ba53f4 | ||
|
|
9081895733 | ||
|
|
48b36d3094 | ||
|
|
cb96689caa |
@@ -3,22 +3,11 @@
|
||||
# Check https://circleci.com/docs/2.0/language-go/ for more details
|
||||
version: 2
|
||||
jobs:
|
||||
check:
|
||||
docker:
|
||||
- image: yunionio/centos-build:1.1-4
|
||||
environment:
|
||||
ONECLOUD_CI_BUILD: "1"
|
||||
working_directory: /root/go/src/yunion.io/x/onecloud
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
command: |
|
||||
make -j3 check
|
||||
build:
|
||||
test:
|
||||
requires:
|
||||
- check
|
||||
docker:
|
||||
- image: yunionio/centos-build:1.1-4
|
||||
- image: yunion/centos-build:go-1.18.3-0
|
||||
environment:
|
||||
ONECLOUD_CI_BUILD: "1"
|
||||
|
||||
@@ -27,58 +16,20 @@ jobs:
|
||||
#### /go/src/github.com/circleci/go-tool
|
||||
#### /go/src/bitbucket.org/circleci/go-tool
|
||||
working_directory: /root/go/src/yunion.io/x/onecloud
|
||||
parallelism: 4
|
||||
resource_class: large
|
||||
parallelism: 1
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
key: onecloud-build-cache-{{ checksum "go.mod" }}-{{ checksum "Makefile" }}
|
||||
paths:
|
||||
- /root/.cache/go-build
|
||||
- run:
|
||||
command: |
|
||||
make -j3 check
|
||||
targets="$(circleci tests glob "cmd/*" | grep -v cmd/host-image | circleci tests split)"
|
||||
echo $targets | tr ' ' '\n'
|
||||
make -j2 $targets
|
||||
make $targets
|
||||
ls -lh _output/bin/
|
||||
- save_cache:
|
||||
key: onecloud-build-cache-{{ checksum "go.mod" }}-{{ checksum "Makefile" }}
|
||||
paths:
|
||||
- /root/.cache/go-build
|
||||
- store_artifacts:
|
||||
path: _output/
|
||||
|
||||
test:
|
||||
requires:
|
||||
- check
|
||||
docker:
|
||||
- image: yunionio/centos-build:1.1-4
|
||||
environment:
|
||||
ONECLOUD_CI_BUILD: "1"
|
||||
working_directory: /root/go/src/yunion.io/x/onecloud
|
||||
parallelism: 4
|
||||
steps:
|
||||
- checkout
|
||||
- restore_cache:
|
||||
key: onecloud-test-cache-{{ checksum "go.mod" }}-{{ checksum "Makefile" }}
|
||||
paths:
|
||||
- /root/.cache/go-build
|
||||
- run:
|
||||
name: unit_test
|
||||
command: |
|
||||
./scripts/coverage.sh --codecov
|
||||
- save_cache:
|
||||
key: onecloud-test-cache-{{ checksum "go.mod" }}-{{ checksum "Makefile" }}
|
||||
paths:
|
||||
- /root/.cache/go-build
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
build_and_test:
|
||||
jobs:
|
||||
- check
|
||||
- build:
|
||||
requires:
|
||||
- check
|
||||
- test:
|
||||
requires:
|
||||
- check
|
||||
- test
|
||||
|
||||
2
Makefile
2
Makefile
@@ -331,7 +331,7 @@ image:
|
||||
.PHONY: image
|
||||
|
||||
image-telegraf-raid-plugin:
|
||||
VERSION=release-1.6.3 ARCH=all make image telegraf-raid-plugin
|
||||
VERSION=release-1.6.4 ARCH=all make image telegraf-raid-plugin
|
||||
|
||||
%:
|
||||
@:
|
||||
|
||||
@@ -40,13 +40,17 @@ import (
|
||||
func init() {
|
||||
type DiskListOptions struct {
|
||||
options.BaseListOptions
|
||||
Unused *bool `help:"Show unused disks"`
|
||||
Share *bool `help:"Show Share storage disks"`
|
||||
Local *bool `help:"Show Local storage disks"`
|
||||
Guest string `help:"Guest ID or name"`
|
||||
Storage string `help:"Storage ID or name"`
|
||||
Type string `help:"Disk type" choices:"sys|data|swap|volume"`
|
||||
CloudType string `help:"Public cloud or private cloud" choices:"Public|Private"`
|
||||
Unused *bool `help:"Show unused disks"`
|
||||
Share *bool `help:"Show Share storage disks"`
|
||||
Local *bool `help:"Show Local storage disks"`
|
||||
Guest string `help:"Guest ID or name"`
|
||||
GuestStatus string `help:"Guest Status"`
|
||||
OrderByServer string `help:"Order By Server"`
|
||||
Storage string `help:"Storage ID or name"`
|
||||
Type string `help:"Disk type" choices:"sys|data|swap|volume"`
|
||||
CloudType string `help:"Public cloud or private cloud" choices:"Public|Private"`
|
||||
|
||||
OrderByGuestCount string `help:"Order By Guest Count"`
|
||||
|
||||
BillingType string `help:"billing type" choices:"postpaid|prepaid"`
|
||||
|
||||
|
||||
@@ -56,9 +56,11 @@ func init() {
|
||||
cmd.BatchPerform("sync-config", &options.BaseIdsOptions{})
|
||||
cmd.BatchPerform("prepare", &options.BaseIdsOptions{})
|
||||
cmd.BatchPerform("ipmi-probe", &options.BaseIdsOptions{})
|
||||
cmd.BatchPerform("auto-migrate-on-host-down", &compute.HostAutoMigrateOnHostDownOptions{})
|
||||
|
||||
cmd.Get("ipmi", &options.BaseIdOptions{})
|
||||
cmd.Get("vnc", &options.BaseIdOptions{})
|
||||
cmd.Get("app-options", &options.BaseIdOptions{})
|
||||
|
||||
R(&options.BaseIdOptions{}, "host-logininfo", "Get SSH login information of a host", func(s *mcclient.ClientSession, args *options.BaseIdOptions) error {
|
||||
srvid, e := modules.Hosts.GetId(s, args.ID, nil)
|
||||
@@ -641,28 +643,6 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
type HostAutoMigrateOnHostDownOptions struct {
|
||||
ID string `help:"ID or name of host"`
|
||||
Enable bool `help:"enable auto migrate"`
|
||||
Disable bool `help:"disable auto migrate"`
|
||||
}
|
||||
R(&HostAutoMigrateOnHostDownOptions{}, "host-auto-migrate-on-host-down", "Get change owner candidate domain list", func(s *mcclient.ClientSession, args *HostAutoMigrateOnHostDownOptions) error {
|
||||
params := jsonutils.NewDict()
|
||||
if args.Disable {
|
||||
params.Set("auto_migrate_on_host_down", jsonutils.NewString("disable"))
|
||||
} else if args.Enable {
|
||||
params.Set("auto_migrate_on_host_down", jsonutils.NewString("enable"))
|
||||
} else {
|
||||
return fmt.Errorf("missing input enable or disable")
|
||||
}
|
||||
result, err := modules.Hosts.PerformAction(s, args.ID, "auto-migrate-on-host-down", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type HostSetReservedResourceForIsolatedDevice struct {
|
||||
ID []string `help:"ID or name of host" json:"-"`
|
||||
ReservedCpu *int `help:"reserved cpu count"`
|
||||
|
||||
@@ -94,6 +94,7 @@ func init() {
|
||||
ReservedCpu *int `help:"reserved cpu for isolated device"`
|
||||
ReservedMem *int `help:"reserved mem for isolated device"`
|
||||
ReservedStorage *int `help:"reserved storage for isolated device"`
|
||||
DevType string `help:"Device type" choices:"GPU-HPC|GPU-VGA"`
|
||||
}
|
||||
R(&DeviceUpdateOptions{}, "isolated-device-update", "Update a isolated device", func(s *mcclient.ClientSession, args *DeviceUpdateOptions) error {
|
||||
res := modules.IsolatedDevices.BatchUpdate(s, args.ID, jsonutils.Marshal(args))
|
||||
|
||||
@@ -156,7 +156,9 @@ func init() {
|
||||
params := jsonutils.NewDict()
|
||||
params.Add(jsonutils.NewString(args.DISK), "disk_id")
|
||||
if args.DeleteDisk {
|
||||
params.Add(jsonutils.NewInt(0), "keep_disk")
|
||||
params.Add(jsonutils.JSONFalse, "keep_disk")
|
||||
} else {
|
||||
params.Add(jsonutils.JSONTrue, "keep_disk")
|
||||
}
|
||||
srv, err := modules.Servers.PerformAction(s, args.SERVER, "detachdisk", params)
|
||||
if err != nil {
|
||||
|
||||
@@ -695,10 +695,11 @@ func init() {
|
||||
})
|
||||
|
||||
type ServerQemuParams struct {
|
||||
ID string `help:"ID or name of VM"`
|
||||
DisableIsaSerial string `help:"disable isa serial device" choices:"true|false"`
|
||||
DisablePvpanic string `help:"disable pvpanic device" choices:"true|false"`
|
||||
DisableUsbKbd string `help:"disable usb kbd" choices:"true|false"`
|
||||
ID string `help:"ID or name of VM"`
|
||||
DisableIsaSerial string `help:"disable isa serial device" choices:"true|false"`
|
||||
DisablePvpanic string `help:"disable pvpanic device" choices:"true|false"`
|
||||
DisableUsbKbd string `help:"disable usb kbd" choices:"true|false"`
|
||||
UsbControllerType string `help:"usb controller type" choices:"usb-ehci|qemu-xhci"`
|
||||
}
|
||||
|
||||
R(&ServerQemuParams{}, "server-set-qemu-params", "config qemu params", func(s *mcclient.ClientSession,
|
||||
@@ -713,6 +714,9 @@ func init() {
|
||||
if len(opts.DisableUsbKbd) > 0 {
|
||||
params.Set("disable_usb_kbd", jsonutils.NewString(opts.DisableUsbKbd))
|
||||
}
|
||||
if len(opts.UsbControllerType) > 0 {
|
||||
params.Set("usb_controller_type", jsonutils.NewString(opts.UsbControllerType))
|
||||
}
|
||||
result, err := modules.Servers.PerformAction(s, opts.ID, "set-qemu-params", params)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -40,6 +40,9 @@ type BaseEventListOptions struct {
|
||||
OwnerDomainIds []string `help:"filter by owner domain ids"`
|
||||
|
||||
PagingMarker string `help:"marker for pagination"`
|
||||
PagingOrder string `help:"pagination order" choices:"DESC|ASC"`
|
||||
|
||||
Filter []string `help:"Filters"`
|
||||
}
|
||||
|
||||
type EventListOptions struct {
|
||||
@@ -118,6 +121,12 @@ func DoEventList(man modulebase.ResourceManager, s *mcclient.ClientSession, args
|
||||
if len(args.PagingMarker) > 0 {
|
||||
params.Add(jsonutils.NewString(args.PagingMarker), "paging_marker")
|
||||
}
|
||||
if len(args.PagingOrder) > 0 {
|
||||
params.Add(jsonutils.NewString(args.PagingOrder), "paging_order")
|
||||
}
|
||||
if len(args.Filter) > 0 {
|
||||
params.Add(jsonutils.NewStringArray(args.Filter), "filter")
|
||||
}
|
||||
logs, err := man.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -181,7 +181,9 @@ func init() {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(jsonutils.Marshal(&secret))
|
||||
result := jsonutils.Marshal(secret)
|
||||
result.(*jsonutils.JSONDict).Add(jsonutils.NewString(secret.KeyId), "access_key")
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
|
||||
34
cmd/climc/shell/misc/appoptions.go
Normal file
34
cmd/climc/shell/misc/appoptions.go
Normal file
@@ -0,0 +1,34 @@
|
||||
// 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 misc
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type AppOptionsOptions struct {
|
||||
SERVICE string `help:"Service type"`
|
||||
}
|
||||
R(&AppOptionsOptions{}, "app-options-show", "query backend service for its options", func(s *mcclient.ClientSession, args *AppOptionsOptions) error {
|
||||
opts, err := modules.GetAppOptions(s, args.SERVICE)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(opts)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -78,7 +78,7 @@ func relayMain() error {
|
||||
time.Sleep(time.Hour)
|
||||
}
|
||||
|
||||
return nil
|
||||
// return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -40,6 +40,8 @@ func init() {
|
||||
Search []string `help:"search conditions, in format of field:value"`
|
||||
Field []string `help:"retrieve field info"`
|
||||
Scope string `help:"query scope" choices:"one|sub" default:"sub"`
|
||||
PageLimit uint32 `help:"page size" default:"100"`
|
||||
Limit uint32 `help:"maximal output items"`
|
||||
}
|
||||
shellutils.R(&LdapSearchOptions{}, "search", "search ldap", func(cli *ldaputils.SLDAPClient, args *LdapSearchOptions) error {
|
||||
search := make(map[string]string)
|
||||
@@ -50,13 +52,14 @@ func init() {
|
||||
}
|
||||
search[s[:colonPos]] = s[(colonPos + 1):]
|
||||
}
|
||||
entries, err := cli.Search(args.Base, args.Objectclass, search, "", args.Field, queryScope(args.Scope))
|
||||
total, err := cli.Search(args.Base, args.Objectclass, search, "", args.Field, queryScope(args.Scope), args.PageLimit, args.Limit, func(offset uint32, entry *ldap.Entry) error {
|
||||
entry.PrettyPrint(2)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, entry := range entries {
|
||||
entry.PrettyPrint(2)
|
||||
}
|
||||
fmt.Println("Total:", total)
|
||||
return nil
|
||||
})
|
||||
|
||||
|
||||
29
go.mod
29
go.mod
@@ -4,7 +4,7 @@ go 1.13
|
||||
|
||||
require (
|
||||
bazil.org/fuse v0.0.0-20180421153158-65cc252bf669
|
||||
cloud.google.com/go/storage v1.5.0
|
||||
cloud.google.com/go/storage v1.10.0
|
||||
github.com/360EntSecGroup-Skylar/excelize v1.4.0
|
||||
github.com/Azure/azure-sdk-for-go v36.1.0+incompatible
|
||||
github.com/Azure/go-autorest/autorest v0.9.6
|
||||
@@ -52,16 +52,15 @@ require (
|
||||
github.com/frankban/quicktest v1.14.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
github.com/gin-gonic/gin v1.7.0
|
||||
github.com/gin-gonic/gin v1.7.7
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.2 // indirect
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/go-sql-driver/mysql v1.6.0
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible
|
||||
github.com/gofrs/uuid v4.1.0+incompatible // indirect
|
||||
github.com/golang-plus/errors v1.0.0
|
||||
github.com/golang-plus/testing v1.0.0 // indirect
|
||||
github.com/golang-plus/uuid v1.0.0
|
||||
github.com/golang/mock v1.3.1
|
||||
github.com/golang/mock v1.4.4
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/google/gopacket v1.1.17
|
||||
github.com/googollee/go-engine.io v0.0.0-20180829091931-e2f255711dcb // indirect
|
||||
@@ -113,7 +112,8 @@ require (
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.135+incompatible
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.413
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc v1.0.413
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.24
|
||||
github.com/tinylib/msgp v1.1.0 // indirect
|
||||
github.com/tredoe/osutil v0.0.0-20161130133508-7d3ee1afa71c
|
||||
@@ -124,11 +124,11 @@ require (
|
||||
go.etcd.io/etcd/api/v3 v3.5.0
|
||||
go.etcd.io/etcd/client/v3 v3.5.0
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40
|
||||
golang.org/x/text v0.3.5
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad
|
||||
golang.org/x/text v0.3.6
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20191008142428-8d021180e987
|
||||
@@ -139,18 +139,17 @@ require (
|
||||
gopkg.in/fatih/set.v0 v0.2.1
|
||||
gopkg.in/ini.v1 v1.44.0 // indirect
|
||||
gopkg.in/ldap.v3 v3.0.3
|
||||
gopkg.in/yaml.v2 v2.3.0
|
||||
honnef.co/go/tools v0.0.1-2020.1.4 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
k8s.io/api v0.19.3
|
||||
k8s.io/apimachinery v0.19.3
|
||||
k8s.io/client-go v0.19.3
|
||||
k8s.io/cluster-bootstrap v0.19.3
|
||||
moul.io/http2curl/v2 v2.3.0
|
||||
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656
|
||||
yunion.io/x/jsonutils v0.0.0-20220106020632-953b71a4c3a8
|
||||
yunion.io/x/log v0.0.0-20201210064738-43181789dc74
|
||||
yunion.io/x/jsonutils v1.0.0
|
||||
yunion.io/x/log v1.0.0
|
||||
yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7
|
||||
yunion.io/x/pkg v0.0.0-20220406030238-39fbc60d5d4e
|
||||
yunion.io/x/pkg v1.0.1-0.20220630095420-9925accd7c5e
|
||||
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e
|
||||
yunion.io/x/sqlchemy v1.0.2
|
||||
yunion.io/x/structarg v0.0.0-20220312084958-9c6c79c7d1c6
|
||||
|
||||
196
go.sum
196
go.sum
@@ -8,19 +8,33 @@ cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxK
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.51.0 h1:PvKAVQWCtlGUSlZkGW3QLelKaWq7KYv/MW1EboG8bfM=
|
||||
cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0 h1:sAbMqjY1PEQKZBWfbu6Y6bsupJ9c4QdHnzg/VvYTLcE=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0 h1:9/vpR43S4aJaROxqQHQ3nH9lfyKKV0dC3vOmnw8ebQQ=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0 h1:RPUcBvDeYgQFMfQu1eBMq6piD1SXmLH+vK3qjewZPus=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0 h1:STgFzyU5/8miMl0//zKh2aQeTyeaUH3WN9bSUiJ09bA=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/360EntSecGroup-Skylar/excelize v1.4.0 h1:43rak9uafmwSJpXfFO1heKQph8tP3nlfWJWFQQtW1R0=
|
||||
github.com/360EntSecGroup-Skylar/excelize v1.4.0/go.mod h1:R8KYLmGns0vDPe6/HyphW0mzW+MFexlGDafU0ykVEnU=
|
||||
@@ -55,7 +69,6 @@ github.com/Azure/go-autorest/logger v0.1.0 h1:ruG4BSDXONFRrZZJ2GUXDiUyVpayPmb1Gn
|
||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VYyQflFE619k=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DataDog/dd-trace-go v0.6.1 h1:nsZ2lohbSw1CKtfNRu3wPh1jFirv6XSz8vqNpuIYWbM=
|
||||
@@ -159,8 +172,9 @@ github.com/bradfitz/iter v0.0.0-20140124041915-454541ec3da2/go.mod h1:PyRFw1Lt2w
|
||||
github.com/c-bata/go-prompt v0.2.1 h1:HTPxmnfY4y5x3Myo7Gq4ce989jfnvZIBgdBp6y8bjYM=
|
||||
github.com/c-bata/go-prompt v0.2.1/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cheggaaa/pb/v3 v3.0.8 h1:bC8oemdChbke2FHIIGy9mn4DPJ2caZYQnfbRqwmdCoA=
|
||||
github.com/cheggaaa/pb/v3 v3.0.8/go.mod h1:UICbiLec/XO6Hw6k+BHEtHeQFzzBH4i2/qk/ow1EJTA=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
@@ -227,8 +241,8 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.7.0 h1:jGB9xAJQ12AIGNB4HguylppmDK1Am9ppF7XnGXXJuoU=
|
||||
github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
|
||||
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2 h1:Ujru1hufTHVb++eG6OuNDKMxZnGIvF6o/u8q/8h2+I4=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
@@ -236,6 +250,7 @@ github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493 h1:OTanQnFt0bi5
|
||||
github.com/glycerine/goconvey v0.0.0-20180728074245-46e3a41ad493/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
@@ -260,8 +275,8 @@ github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD87
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
|
||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o=
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0=
|
||||
@@ -281,16 +296,23 @@ github.com/golang-plus/uuid v1.0.0 h1:ga84hG89vda++AGpup4N/cbfbM3O4d3R5ON9/jcN6A
|
||||
github.com/golang-plus/uuid v1.0.0/go.mod h1:pBDDRrdgRHHqyYlj1d1i2gwyBq62Zc+sP2cDiCDkBLI=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7 h1:5ZkaAPbicIKTF2I64qf5Fh8Aa83Q/dnOafMYV0OMwjA=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
@@ -312,6 +334,9 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
@@ -325,9 +350,15 @@ github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbB
|
||||
github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
|
||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
@@ -382,8 +413,9 @@ github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
@@ -479,8 +511,9 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||
@@ -528,8 +561,9 @@ github.com/pquerna/otp v1.2.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf3/SASFAGtQ=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk=
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
@@ -537,13 +571,15 @@ github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
|
||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
@@ -603,8 +639,10 @@ github.com/syncthing/syncthing v0.14.48-rc.4/go.mod h1:nw3siZwHPA6M8iSfjDCWQ402e
|
||||
github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8=
|
||||
github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e h1:nt2877sKfojlHCTOBXbpWjBkuWKritFaGIfgQwbQUls=
|
||||
github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e/go.mod h1:B4+Kq1u5FlULTjFSM707Q6e/cOHFv0z/6QRoxubDIQ8=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.135+incompatible h1:QIMoFqKCmNp4HPLiTR+couZbHsIZfoOllncHYvtqse8=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go v3.0.135+incompatible/go.mod h1:0PfYow01SHPMhKY31xa+EFz2RStxIqj6JFAJS+IkCi4=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.413 h1:DvydszksqriOr0Zze9OREt8OrIrtMSFcVD8lz3xNAQA=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.413/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc v1.0.413 h1:Wtx9ZMVfxT/5zKLmFgwDoiu0lahVgauXiC+6Gjxv8PM=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc v1.0.413/go.mod h1:8OcFH4CktPQvooXP0pt2hBZ+znNnj/bgbio7iazamDs=
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.24 h1:ZsZij764lOaPsj7mEAlyxXvslGt6/m312Tzqj/zeRpo=
|
||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.24/go.mod h1:wQBO5HdAkLjj2q6XQiIfDSP8DXDNrppDRw2Kp/1BODA=
|
||||
github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e h1:T5PdfK/M1xyrHwynxMIVMWLS7f/qHwfslZphxtGnw7s=
|
||||
@@ -632,7 +670,9 @@ github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPyS
|
||||
github.com/willf/bloom v0.0.0-20170505221640-54e3b963ee16/go.mod h1:MmAltL9pDMNTrvUkxdg0k0q5I0suxmuwp3KbyrZLOZ8=
|
||||
github.com/willf/bloom v2.0.3+incompatible h1:QDacWdqcAUI1MPOwIQZRy9kOR7yxfyEmxX8Wdm2/JPA=
|
||||
github.com/willf/bloom v2.0.3+incompatible/go.mod h1:MmAltL9pDMNTrvUkxdg0k0q5I0suxmuwp3KbyrZLOZ8=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.etcd.io/etcd/api/v3 v3.5.0 h1:GsV3S+OfZEOCNXdtNkBSR7kgLobAa/SO6tCxRa0GAYw=
|
||||
@@ -643,8 +683,10 @@ go.etcd.io/etcd/client/v3 v3.5.0 h1:62Eh0XOro+rDwkrypAGDfgmNh5Joq+z+W9HZdlXMzek=
|
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4 h1:LYy1Hy3MJdrCdMwwzxA/dRok4ejH+RwNGbuoD9fCjto=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
@@ -671,8 +713,10 @@ golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxT
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299 h1:zQpM52jfKHG6II1ISZY1ZcpygvuSFZpLwfluuF89XOg=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@@ -682,6 +726,8 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
@@ -689,6 +735,7 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
@@ -710,33 +757,46 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||
@@ -764,33 +824,50 @@ golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190830023255-19e00faab6ad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -821,9 +898,26 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200417140056-c07e33ef3290/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA=
|
||||
@@ -843,13 +937,23 @@ google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEn
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0 h1:yzlyyDW/J0w8yNFJIhiAJy4kq74S+1DOLdawELNxFMA=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
@@ -861,8 +965,24 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/grpc v1.29.0 h1:2pJjwYOdkZ9HlN4sWRYBg9ttH5bCOlsueaM+b/oYjwo=
|
||||
@@ -876,6 +996,7 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
@@ -907,8 +1028,9 @@ gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
@@ -917,7 +1039,7 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4 h1:UoveltGrhghAA7ePc+e+QYDHXrBps2PqFZiHkGR/xK8=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.19.3 h1:GN6ntFnv44Vptj/b+OnMW7FmzkpDoIDLZRvKX3XH9aU=
|
||||
k8s.io/api v0.19.3/go.mod h1:VF+5FT1B74Pw3KxMdKyinLo+zynBaMBiAfGMuldcNDs=
|
||||
@@ -937,6 +1059,8 @@ k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
|
||||
moul.io/http2curl/v2 v2.3.0 h1:9r3JfDzWPcbIklMOs2TnIFzDYvfAZvjeavG6EzP7jYs=
|
||||
moul.io/http2curl/v2 v2.3.0/go.mod h1:RW4hyBjTWSYDOxapodpNEtX0g5Eb16sxklBqmd2RHcE=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
@@ -945,21 +1069,23 @@ sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656 h1:0zlZD5uhZoIHgLVAWCz2aHaYk2ZrNsACCYD7R6EIBII=
|
||||
yunion.io/x/executor v0.0.0-20211018100936-39a2cd966656/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-20220106020632-953b71a4c3a8 h1:yFJVMnUoolC8mlUxa+LMTObYmqJ2H7iyxGIaXxT1fOc=
|
||||
yunion.io/x/jsonutils v0.0.0-20220106020632-953b71a4c3a8/go.mod h1:p0nyMqGA/apTxxyLIU/o1k4V7Vujl2O6ey30L594sYE=
|
||||
yunion.io/x/jsonutils v1.0.0 h1:ySgXdIoRqUZRYA0t8QVqRkWgV8IWJlh2JtGovqqc+iI=
|
||||
yunion.io/x/jsonutils v1.0.0/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-20201210064738-43181789dc74 h1:7D+sQ/XaUTUEm+NCrKXOhXBKlzEd0RyS2qZ4vBGjx2o=
|
||||
yunion.io/x/log v0.0.0-20201210064738-43181789dc74/go.mod h1:LC6f/4FozL0iaAbnFt2eDX9jlsyo3WiOUPm03d7+U4U=
|
||||
yunion.io/x/log v1.0.0 h1:VPgssPi8Om+KAHjlEjf6RDU86du//yO+X0upu+h6fZM=
|
||||
yunion.io/x/log v1.0.0/go.mod h1:LC6f/4FozL0iaAbnFt2eDX9jlsyo3WiOUPm03d7+U4U=
|
||||
yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7 h1:gjqNa2uQzIEXyySsbvVz0UltTEbGsnFFlvnzOpCfHdo=
|
||||
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-20200814072949-4f1b541857d6/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v0.0.0-20220406030238-39fbc60d5d4e h1:ovxSHuAa8hOBiZPU+ezrwqmVuCN7QTNx0sRRDGMaAkY=
|
||||
yunion.io/x/pkg v0.0.0-20220406030238-39fbc60d5d4e/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v1.0.1-0.20220630095420-9925accd7c5e h1:p/Cb7z6gyJbZKnGMeOPL3pTmnphB9GLCU+8qMsln7qA=
|
||||
yunion.io/x/pkg v1.0.1-0.20220630095420-9925accd7c5e/go.mod h1:nYOMflWG1wQC6301rGVglQva9bYbJxHThEJUxRAgMFc=
|
||||
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 v1.0.1/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI=
|
||||
yunion.io/x/sqlchemy v1.0.2 h1:fZ2rLveXgL94f+HQW4cJVJoP2o/ozOK7xUT2k/kKKEA=
|
||||
yunion.io/x/sqlchemy v1.0.2/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI=
|
||||
yunion.io/x/structarg v0.0.0-20220312084958-9c6c79c7d1c6 h1:WuWXhY3DvhdRTzWCJ/kwt3Ss6KIq7+KqJwb+esvNGwU=
|
||||
|
||||
@@ -157,6 +157,9 @@ func (apb *SAnsiblePlaybookV2) runPlaybook(ctx context.Context, userCred mcclien
|
||||
return fmt.Errorf("playbook is already running")
|
||||
}
|
||||
|
||||
// hack: force Sleep 15s to wait some host ssh service started
|
||||
time.Sleep(15 * time.Second)
|
||||
|
||||
var (
|
||||
privateKey string
|
||||
err error
|
||||
|
||||
@@ -69,6 +69,7 @@ func (h *AuthHandlers) AddMethods() {
|
||||
NewHP(h.getIdpSsoRedirectUri, "sso", "redirect", "<idp_id>"),
|
||||
NewHP(h.listTotpRecoveryQuestions, "recovery"),
|
||||
NewHP(h.handleSsoLogin, "ssologin"),
|
||||
NewHP(h.handleIdpInitSsoLogin, "ssologin", "<idp_id>"),
|
||||
NewHP(h.postLogoutHandler, "logout"),
|
||||
// oidc auth
|
||||
NewHP(handleOIDCAuth, "oidc", "auth"),
|
||||
|
||||
@@ -125,13 +125,38 @@ func findExtUserId(input string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (h *AuthHandlers) handleIdpInitSsoLogin(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
params := appctx.AppContextParams(ctx)
|
||||
idpId := params["<idp_id>"]
|
||||
s := auth.GetAdminSession(ctx, FetchRegion(req), "")
|
||||
resp, err := modules.IdentityProviders.Get(s, idpId, nil)
|
||||
if err != nil {
|
||||
httperrors.GeneralServerError(ctx, w, err)
|
||||
return
|
||||
}
|
||||
idpDriver, _ := resp.GetString("driver")
|
||||
h.internalSsoLogin(ctx, w, req, idpId, idpDriver)
|
||||
}
|
||||
|
||||
func (h *AuthHandlers) handleSsoLogin(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
||||
idpId := getCookie(req, "idp_id")
|
||||
idpDriver := getCookie(req, "idp_driver")
|
||||
|
||||
h.internalSsoLogin(ctx, w, req, "", "")
|
||||
}
|
||||
|
||||
func (h *AuthHandlers) internalSsoLogin(ctx context.Context, w http.ResponseWriter, req *http.Request, idpId, idpDriver string) {
|
||||
idpIdC := getCookie(req, "idp_id")
|
||||
idpDriverC := getCookie(req, "idp_driver")
|
||||
idpState := getCookie(req, "idp_state")
|
||||
idpReferer := getCookie(req, "idp_referer")
|
||||
idpLinkUser := getCookie(req, "idp_link_user")
|
||||
|
||||
if len(idpIdC) > 0 {
|
||||
idpId = idpIdC
|
||||
}
|
||||
if len(idpDriverC) > 0 {
|
||||
idpDriver = idpDriverC
|
||||
}
|
||||
|
||||
for _, k := range []string{"idp_id", "idp_driver", "idp_state", "idp_referer", "idp_link_user"} {
|
||||
clearCookie(w, k, "")
|
||||
}
|
||||
@@ -143,12 +168,12 @@ func (h *AuthHandlers) handleSsoLogin(ctx context.Context, w http.ResponseWriter
|
||||
if len(idpDriver) == 0 {
|
||||
missing = append(missing, "idp_driver")
|
||||
}
|
||||
if len(idpState) == 0 {
|
||||
/*if len(idpState) == 0 {
|
||||
missing = append(missing, "idp_state")
|
||||
}
|
||||
if len(idpReferer) == 0 {
|
||||
missing = append(missing, "idp_referer")
|
||||
}
|
||||
}*/
|
||||
if len(missing) > 0 {
|
||||
httperrors.TimeoutError(ctx, w, "session expires, missing %s", strings.Join(missing, ","))
|
||||
return
|
||||
|
||||
@@ -104,6 +104,7 @@ func GetModels(opts *GetModelsOptions) error {
|
||||
listOptions := options.BaseListOptions{
|
||||
System: options.Bool(true),
|
||||
Admin: options.Bool(true),
|
||||
Scope: "system",
|
||||
Details: options.Bool(opts.IncludeDetails),
|
||||
ShowEmulated: options.Bool(opts.IncludeEmulated),
|
||||
Filter: []string{
|
||||
@@ -118,8 +119,8 @@ func GetModels(opts *GetModelsOptions) error {
|
||||
listOptions.Filter = append(listOptions.Filter,
|
||||
"manager_id.isnullorempty()", // len(manager_id) > 0 is for pubcloud objects
|
||||
"external_id.isnullorempty()", // len(external_id) > 0 is for pubcloud objects
|
||||
"cloud_env=onpremise",
|
||||
)
|
||||
listOptions.CloudEnv = "onpremise"
|
||||
}
|
||||
if inter, ok := opts.ModelSet.(IModelSetFilter); ok {
|
||||
filter := inter.ModelFilter()
|
||||
|
||||
@@ -49,9 +49,9 @@ type CloudpolicyListInput struct {
|
||||
// 权限类型
|
||||
//
|
||||
//
|
||||
// | 类型 | 说明 |
|
||||
// |---------| ------------ |
|
||||
// | system | 过滤系统权限 |
|
||||
// | 类型 | 说明 |
|
||||
// |---------| ------------ |
|
||||
// | system | 过滤系统权限 |
|
||||
// | custom | 过滤自定义权限 |
|
||||
PolicyType string `json:"policy_type"`
|
||||
|
||||
|
||||
@@ -47,10 +47,12 @@ type ClouduserCreateInput struct {
|
||||
|
||||
// 用户密码, 若is_console_login = true时, 此参数不传时会生成12位随机密码
|
||||
//
|
||||
//
|
||||
//
|
||||
// | 云平台 | 说明 |
|
||||
// |----------|---------------------------------------------|
|
||||
// | Google | 不支持此参数 |
|
||||
// | Aliyun | 支持 |
|
||||
// | Aliyun | 支持 |
|
||||
// | Huawei | 支持 |
|
||||
// | Azure | 支持 |
|
||||
// | 腾讯云 | 支持 |
|
||||
@@ -68,10 +70,12 @@ type ClouduserCreateInput struct {
|
||||
|
||||
// 初始的权限Id列表, 权限必须属于指定的云账号
|
||||
//
|
||||
//
|
||||
//
|
||||
// | 云平台 | 说明 |
|
||||
// |----------|---------------------------------------------|
|
||||
// | Google | 至少需要一个初始权限 |
|
||||
// | Aliyun | 支持 |
|
||||
// | Aliyun | 支持 |
|
||||
// | Huawei | 不支持 |
|
||||
// | Azure | 支持 |
|
||||
// | 腾讯云 | 支持 |
|
||||
@@ -182,10 +186,12 @@ type ClouduserAttachPolicyInput struct {
|
||||
|
||||
// 权限Id
|
||||
//
|
||||
//
|
||||
//
|
||||
// | 云平台 | 说明 |
|
||||
// |----------|---------------------------------------------|
|
||||
// | Google | 支持 |
|
||||
// | Aliyun | 支持 |
|
||||
// | Aliyun | 支持 |
|
||||
// | Huawei | 不支持 |
|
||||
// | Azure | 支持 |
|
||||
// | 腾讯云 | 支持 |
|
||||
@@ -221,10 +227,12 @@ type ClouduserDetachPolicyInput struct {
|
||||
CloudproviderId string `json:"cloudprovider_id"`
|
||||
// 权限Id
|
||||
//
|
||||
//
|
||||
//
|
||||
// | 云平台 | 说明 |
|
||||
// |----------|---------------------------------------------|
|
||||
// | Google | 支持,但最少需要保留一个权限 |
|
||||
// | Aliyun | 支持 |
|
||||
// | Aliyun | 支持 |
|
||||
// | Huawei | 不支持 |
|
||||
// | Azure | 不支持 |
|
||||
// | 腾讯云 | 支持 |
|
||||
@@ -243,10 +251,12 @@ type ClouduserUpdateInput struct {
|
||||
type ClouduserResetPasswordInput struct {
|
||||
// 若此参数为空, 默认会生成随机12位密码
|
||||
//
|
||||
//
|
||||
//
|
||||
// | 云平台 | 说明 |
|
||||
// |----------|---------------------------------------------|
|
||||
// | Google | 不支持 |
|
||||
// | Aliyun | 支持 |
|
||||
// | Aliyun | 支持 |
|
||||
// | Huawei | 支持 |
|
||||
// | Azure | 支持 |
|
||||
// | 腾讯云 | 支持 |
|
||||
|
||||
@@ -62,11 +62,12 @@ type NetworkConfig struct {
|
||||
|
||||
// 驱动方式
|
||||
// 若指定镜像的网络驱动方式,此参数会被覆盖
|
||||
Driver string `json:"driver"`
|
||||
BwLimit int `json:"bw_limit"`
|
||||
Vip bool `json:"vip"`
|
||||
Reserved bool `json:"reserved"`
|
||||
NetType string `json:"net_type"`
|
||||
Driver string `json:"driver"`
|
||||
BwLimit int `json:"bw_limit"`
|
||||
Vip bool `json:"vip"`
|
||||
Reserved bool `json:"reserved"`
|
||||
NetType string `json:"net_type"`
|
||||
NumQueues int `json:"num_queues"`
|
||||
|
||||
RequireDesignatedIP bool `json:"require_designated_ip"`
|
||||
|
||||
@@ -152,42 +153,42 @@ type DiskConfig struct {
|
||||
//
|
||||
//
|
||||
//
|
||||
//| 平台 | 存储类型 | 中文 | 数据盘 | 系统盘 | 可否扩容 | 可否单独创建 | 扩容步长 | 说明 |
|
||||
//| ---- | ---- | ---- | ----- | ----- | ------- | ----------- | ------- | ----- |
|
||||
//| Esxi |local |本地盘 |1-500GB |30~500GB | 是 | 否 | 1G | |
|
||||
//| Esxi |nas |NAS盘 |30-3072GB |30~500GB | 是 | 否 | 1G | |
|
||||
//| Esxi |vsan |VSAN盘 |30-3072GB |30~500GB | 是 | 否 | 1G | |
|
||||
//| KVM |local |本地盘盘 |1-500GB |30~500GB | 是 | 否 | 1G | |
|
||||
//| KVM |rbd |云硬盘 |1-3072GB |30~500GB | 是 | 是 | 1G | |
|
||||
//| Azure |standard_lrs |标准 HDD |1-4095GB |30~4095GB | 是 | 是 | 1G | |
|
||||
//| Azure |standardssd_lrs |标准 SSD |1-4095GB |30~4095GB | 是 | 是 | 1G | |
|
||||
//| Azure |premium_lrs |高级SSD |1-4095GB |30~4095GB | 是 | 是 | 1G | |
|
||||
//| AWS |gp2 |通用型SSD |1-16384GB |20~16384GB | 是 | 是 | 1G | |
|
||||
//| AWS |io1 |预配置 IOPS SSD|4-16384GB |20-16384GB | 是 | 是 | 1G | |
|
||||
//| AWS |st1 |吞吐优化HDD |500-16384GB |不支持 | 是 | 是 | 1G | |
|
||||
//| AWS |sc1 |Cold HDD |500-16384GB |不支持 | 是 | 是 | 1G | |
|
||||
//| AWS |standard |磁介质 |1-1024GB |20-1024GB | 是 | 是 | 1G | |
|
||||
//| 腾讯云 |cloud_ssd |SSD云硬盘 |10-16000GB |50~500GB | 是 | 是 | 10G | |
|
||||
//| 腾讯云 |cloud_basic |普通云硬盘 |10-16000GB |50~500GB | 是 | 是 | 10G | |
|
||||
//| 腾讯云 |cloud_preium |高性能云硬盘 |10-16000GB |50~1024GB | 是 | 是 | 10G | |
|
||||
//| 腾讯云 |local_basic |普通本地盘 |10-1600GB |不支持 | 否 | 否 | | |
|
||||
//| 腾讯云 |local_ssd |SSD本地盘 |10-7000GB |部分区域套餐支持 | 否 | 否 | | |
|
||||
//| 腾讯云 |local_pro |HDD本地盘 |跟随套餐 |部分区域套餐支持 | 否 | 否 | | |
|
||||
//| 华为云或天翼云 |SSD |超高IO云硬盘 |10-32768GB |40~1024GB | 是 | 是 | 1G | |
|
||||
//| 华为云或天翼云 |SAS |高IO云硬盘 |10-32768GB |40~1024GB | 是 | 是 | 1G | |
|
||||
//| 华为云或天翼云 |SATA |普通IO云硬盘 |10-32768GB |40~1024GB | 是 | 是 | 1G | |
|
||||
//| OpenStack |nova |nova |不支持 |30-500GB | 否 | 否 | | |
|
||||
//| OpenStack |自定义 |... |无限制 |无限制 | 是 | 是 | 1G | |
|
||||
//| Ucloud |CLOUD_NORMAL |普通云盘 |20-8000GB |不支持 | 是 | 是 | 1G | |
|
||||
//| Ucloud |CLOUD_SSD |SSD云盘 |20-4000GB |20-500GB | 是 | 是 | 1G | |
|
||||
//| Ucloud |LOCAL_NORMAL |普通本地盘 | | | 是 | 是 | 1G | |
|
||||
//| Ucloud |LOCAL_SSD |SSD本地盘 | | | 是 | 是 | 1G | |
|
||||
//| Ucloud |EXCLUSIVE_LOCAL_DISK |独享本地盘 | | | 是 | 是 | 1G | |
|
||||
//| ZStack |localstorage |本地盘 | | | 是 | 是 | 1G | |
|
||||
//| ZStack |ceph |云硬盘 | | | 是 | 是 | 1G | |
|
||||
//| Google |local-ssd |本地SSD暂存盘 |375GB |不支持 | 否 | 否 | | 跟随实例创建,一次最多添加8个 |
|
||||
//| Google |pd-standard |标准永久性磁盘 |10-65536GB |10-65536GB | 是 | 是 | 1G | |
|
||||
//| Google |pd-ssd |SSD永久性磁盘 |10-65536GB |10-65536GB | 是 | 是 | 1G | |
|
||||
// | 平台 | 存储类型 | 中文 | 数据盘 | 系统盘 | 可否扩容 | 可否单独创建 | 扩容步长 | 说明 |
|
||||
// |---- | ---- | ---- | ----- | ----- | ------- | ----------- | ------- | ----- |
|
||||
// |Esxi |local |本地盘 |1-500GB |30~500GB | 是 | 否 | 1G | |
|
||||
// |Esxi |nas |NAS盘 |30-3072GB |30~500GB | 是 | 否 | 1G | |
|
||||
// |Esxi |vsan |VSAN盘 |30-3072GB |30~500GB | 是 | 否 | 1G | |
|
||||
// |KVM |local |本地盘盘 |1-500GB |30~500GB | 是 | 否 | 1G | |
|
||||
// |KVM |rbd |云硬盘 |1-3072GB |30~500GB | 是 | 是 | 1G | |
|
||||
// |Azure |standard_lrs |标准 HDD |1-4095GB |30~4095GB | 是 | 是 | 1G | |
|
||||
// |Azure |standardssd_lrs |标准 SSD |1-4095GB |30~4095GB | 是 | 是 | 1G | |
|
||||
// |Azure |premium_lrs |高级SSD |1-4095GB |30~4095GB | 是 | 是 | 1G | |
|
||||
// |AWS |gp2 |通用型SSD |1-16384GB |20~16384GB | 是 | 是 | 1G | |
|
||||
// |AWS |io1 |预配置 IOPS SSD |4-16384GB |20-16384GB | 是 | 是 | 1G | |
|
||||
// |AWS |st1 |吞吐优化HDD |500-16384GB |不支持 | 是 | 是 | 1G | |
|
||||
// |AWS |sc1 |Cold HDD |500-16384GB |不支持 | 是 | 是 | 1G | |
|
||||
// |AWS |standard |磁介质 |1-1024GB |20-1024GB | 是 | 是 | 1G | |
|
||||
// |腾讯云 |cloud_ssd |SSD云硬盘 |10-16000GB |50~500GB | 是 | 是 | 10G | |
|
||||
// |腾讯云 |cloud_basic |普通云硬盘 |10-16000GB |50~500GB | 是 | 是 | 10G | |
|
||||
// |腾讯云 |cloud_preium |高性能云硬盘 |10-16000GB |50~1024GB | 是 | 是 | 10G | |
|
||||
// |腾讯云 |local_basic |普通本地盘 |10-1600GB |不支持 | 否 | 否 | | |
|
||||
// |腾讯云 |local_ssd |SSD本地盘 |10-7000GB |部分区域套餐支持 | 否 | 否 | | |
|
||||
// |腾讯云 |local_pro |HDD本地盘 |跟随套餐 |部分区域套餐支持 | 否 | 否 | | |
|
||||
// |华为云或天翼云 |SSD |超高IO云硬盘 |10-32768GB |40~1024GB | 是 | 是 | 1G | |
|
||||
// |华为云或天翼云 |SAS |高IO云硬盘 |10-32768GB |40~1024GB | 是 | 是 | 1G | |
|
||||
// |华为云或天翼云 |SATA |普通IO云硬盘 |10-32768GB |40~1024GB | 是 | 是 | 1G | |
|
||||
// |OpenStack |nova |nova |不支持 |30-500GB | 否 | 否 | | |
|
||||
// |OpenStack |自定义 |... |无限制 |无限制 | 是 | 是 | 1G | |
|
||||
// |Ucloud |CLOUD_NORMAL |普通云盘 |20-8000GB |不支持 | 是 | 是 | 1G | |
|
||||
// |Ucloud |CLOUD_SSD |SSD云盘 |20-4000GB |20-500GB | 是 | 是 | 1G | |
|
||||
// |Ucloud |LOCAL_NORMAL |普通本地盘 | | | 是 | 是 | 1G | |
|
||||
// |Ucloud |LOCAL_SSD |SSD本地盘 | | | 是 | 是 | 1G | |
|
||||
// |Ucloud |EXCLUSIVE_LOCAL_DISK |独享本地盘 | | | 是 | 是 | 1G | |
|
||||
// |ZStack |localstorage |本地盘 | | | 是 | 是 | 1G | |
|
||||
// |ZStack |ceph |云硬盘 | | | 是 | 是 | 1G | |
|
||||
// |Google |local-ssd |本地SSD暂存盘 |375GB |不支持 | 否 | 否 | | 跟随实例创建,一次最多添加8个 |
|
||||
// |Google |pd-standard |标准永久性磁盘 |10-65536GB |10-65536GB | 是 | 是 | 1G | |
|
||||
// |Google |pd-ssd |SSD永久性磁盘 |10-65536GB |10-65536GB | 是 | 是 | 1G | |
|
||||
Backend string `json:"backend"`
|
||||
|
||||
//介质类型
|
||||
@@ -260,21 +261,21 @@ type ServerConfigs struct {
|
||||
//
|
||||
//
|
||||
//
|
||||
// |hypervisor | 技术或平台 |
|
||||
// |------- | ---------- |
|
||||
// |kvm | 本地私有云 |
|
||||
// |esxi | VMWare |
|
||||
// |baremetal | 裸金属 |
|
||||
// |aliyun | 阿里云 |
|
||||
// |aws | 亚马逊 |
|
||||
// |qcloud | 腾讯云 |
|
||||
// |azure | 微软云 |
|
||||
// |huawei | 华为云 |
|
||||
// |openstack | OpenStack |
|
||||
// |ucloud | Ucloud |
|
||||
// |zstack | ZStack |
|
||||
// |google | 谷歌云 |
|
||||
// |ctyun | 天翼云 |
|
||||
// |hypervisor | 技术或平台 |
|
||||
// |------- | ---------- |
|
||||
// |kvm | 本地私有云 |
|
||||
// |esxi | VMWare |
|
||||
// |baremetal | 裸金属 |
|
||||
// |aliyun | 阿里云 |
|
||||
// |aws | 亚马逊 |
|
||||
// |qcloud | 腾讯云 |
|
||||
// |azure | 微软云 |
|
||||
// |huawei | 华为云 |
|
||||
// |openstack | OpenStack |
|
||||
// |ucloud | Ucloud |
|
||||
// |zstack | ZStack |
|
||||
// |google | 谷歌云 |
|
||||
// |ctyun | 天翼云 |
|
||||
// default: kvm
|
||||
Hypervisor string `json:"hypervisor"`
|
||||
|
||||
@@ -361,6 +362,7 @@ type ServerCreateInput struct {
|
||||
VcpuCount int `json:"vcpu_count"`
|
||||
|
||||
// 用户自定义启动脚本
|
||||
// 公有云私有云只支持 #cloud-config yaml 格式, 且只有linux系统生效
|
||||
// required: false
|
||||
UserData string `json:"user_data"`
|
||||
|
||||
@@ -433,20 +435,20 @@ type ServerCreateInput struct {
|
||||
// 包年包月时长
|
||||
//
|
||||
//
|
||||
// |平台 |是否支持 |
|
||||
// |---- |------- |
|
||||
// |KVM |否 |
|
||||
// |ESxi |否 |
|
||||
// |OpenStack |否 |
|
||||
// |ZStack |否 |
|
||||
// |Google |否 |
|
||||
// |Azure |否 |
|
||||
// |AWS |否 |
|
||||
// |腾讯云 |是 |
|
||||
// |Aliyun |是 |
|
||||
// |Ucloud |是 |
|
||||
// |Huawei |是 |
|
||||
// |天翼云 |是 |
|
||||
// |平台 |是否支持 |
|
||||
// |---- |------- |
|
||||
// |KVM |否 |
|
||||
// |ESxi |否 |
|
||||
// |OpenStack |否 |
|
||||
// |ZStack |否 |
|
||||
// |Google |否 |
|
||||
// |Azure |否 |
|
||||
// |AWS |否 |
|
||||
// |腾讯云 |是 |
|
||||
// |Aliyun |是 |
|
||||
// |Ucloud |是 |
|
||||
// |Huawei |是 |
|
||||
// |天翼云 |是 |
|
||||
Duration string `json:"duration"`
|
||||
|
||||
// 是否自动续费
|
||||
@@ -477,18 +479,18 @@ type ServerCreateInput struct {
|
||||
// 私有云不支持此参数
|
||||
//
|
||||
//
|
||||
// |平台 |支持范围 |
|
||||
// |---- |------- |
|
||||
// |腾讯云 |按量计费1-100, 包年包月1-200 |
|
||||
// |平台 |支持范围 |
|
||||
// |---- |------- |
|
||||
// |腾讯云 |按量计费1-100, 包年包月1-200 |
|
||||
PublicIpBw int `json:"public_ip_bw,omitzero"`
|
||||
// 公网IP计费类型
|
||||
// 默认按流量计费
|
||||
//
|
||||
//
|
||||
// |类别 |说明 |
|
||||
// |---- |------- |
|
||||
// |traffic |按流量计费|
|
||||
// |bandwidth |按带宽计费|
|
||||
// |类别 |说明 |
|
||||
// |---- |------- |
|
||||
// |traffic |按流量计费|
|
||||
// |bandwidth |按带宽计费|
|
||||
PublicIpChargeType string `json:"public_ip_charge_type,omitempty"`
|
||||
|
||||
// 使用主机快照创建虚拟机, 主机快照不会重置密码及秘钥信息
|
||||
|
||||
@@ -27,6 +27,6 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
CACHED_IMAGE_REFRESH_SECONDS = 900 // 15 minutes
|
||||
CACHED_IMAGE_REFRESH_SECONDS = 1 // 1 second
|
||||
CACHED_IMAGE_REFERENCE_SESSION_EXPIRE_SECONDS = 86400 // 1 day
|
||||
)
|
||||
|
||||
@@ -106,6 +106,8 @@ const (
|
||||
CITY_MUMBAI = "Mumbai" //孟买
|
||||
CITY_KANCHIPURAM = "Kanchipuram" //甘吉布勒姆
|
||||
CITY_MAHARASHTRA = "Maharashtra" //马哈拉施特拉邦
|
||||
CITY_JAMNAGAR = "Jamnagar" //贾姆讷格尔
|
||||
CITY_NAGPUR = "Nagpur" //那格浦尔
|
||||
|
||||
// 美国
|
||||
CITY_VIRGINIA = "Virginia" //弗吉尼亚
|
||||
|
||||
@@ -45,10 +45,10 @@ type DBInstanceCreateInput struct {
|
||||
//
|
||||
//
|
||||
// | 云平台 | 最大支出安全组数量 |
|
||||
// |-------------|----------|
|
||||
// | 腾讯云 | 5 |
|
||||
// | 华为云 | 1 |
|
||||
// | 阿里云 | 不支持|
|
||||
// |-------------|---------- |
|
||||
// | 腾讯云 | 5 |
|
||||
// | 华为云 | 1 |
|
||||
// | 阿里云 | 不支持 |
|
||||
SecgroupIds []string `json:"secgroup_ids"`
|
||||
// swagger:ignore
|
||||
Secgroup string `json:"secgroup" yunion-deprecated-by:"secgroup_ids"`
|
||||
@@ -108,12 +108,12 @@ type DBInstanceCreateInput struct {
|
||||
//
|
||||
//
|
||||
//
|
||||
// | 平台 | 支持类型 | 说明 |
|
||||
// | ----- | ------ | --- |
|
||||
// | 华为云 |ha, single, replica| ha: 高可用, single: 单机, replica: 只读|
|
||||
// | 阿里云 |basic, high_availability, always_on, finance|basic: 基础版, high_availability: 高可用, always_on: 集群版, finance: 金融版, 三节点|
|
||||
// | Google |Zonal, Regional | Zonal: 单区域, Regional: 区域级|
|
||||
// | 腾讯云 |fe, ha, basic | ha: 高可用, basic: 基础版, fe: 金融版|
|
||||
// | 平台 | 支持类型 | 说明 |
|
||||
// | ----- | ------ | --- |
|
||||
// | 华为云 |ha, single, replica| ha: 高可用, single: 单机, replica: 只读|
|
||||
// | 阿里云 |basic, high_availability, always_on, finance|basic: 基础版, high_availability: 高可用, always_on: 集群版, finance: 金融版, 三节点|
|
||||
// | Google |Zonal, Regional | Zonal: 单区域, Regional: 区域级|
|
||||
// | 腾讯云 |fe, ha, basic | ha: 高可用, basic: 基础版, fe: 金融版|
|
||||
// required: true
|
||||
Category string `json:"category"`
|
||||
|
||||
@@ -121,12 +121,12 @@ type DBInstanceCreateInput struct {
|
||||
//
|
||||
//
|
||||
//
|
||||
// | 平台 | 支持类型 | 说明 |
|
||||
// | ----- | ------ | --- |
|
||||
// | 华为云 |SSD, SAS, SATA| |
|
||||
// | 阿里云 |local_ssd, cloud_essd, cloud_ssd| |
|
||||
// | Google |PD_SSD, PD_HDD| PD_SSD: SSD, PD_HDD: HDD|
|
||||
// | 腾讯云 |cloud_ssd, local_ssd| |
|
||||
// | 平台 | 支持类型 | 说明 |
|
||||
// | ----- | ------ | --- |
|
||||
// | 华为云 |SSD, SAS, SATA| |
|
||||
// | 阿里云 |local_ssd, cloud_essd, cloud_ssd| |
|
||||
// | Google |PD_SSD, PD_HDD| PD_SSD: SSD, PD_HDD: HDD|
|
||||
// | 腾讯云 |cloud_ssd, local_ssd| |
|
||||
// required: true
|
||||
StorageType string `json:"storage_type"`
|
||||
|
||||
@@ -178,11 +178,11 @@ type SDBInstanceRecoveryConfigInput struct {
|
||||
// 备份Id
|
||||
//
|
||||
//
|
||||
// | 平台 | 支持引擎 | 说明 |
|
||||
// | ----- | ------ | --- |
|
||||
// | 华为云 |MySQL, SQL Server | 仅SQL Server支持恢复到当前实例 |
|
||||
// | 阿里云 |MySQL, SQL Server | MySQL要求必须开启单库单表恢复功能 并且只能是MySQL 8.0 高可用版(本地SSD盘)MySQL 5.7 高可用版(本地SSD盘)或MySQL 5.6 高可用版, MySQL仅支持恢复到当前实例|
|
||||
// | Google |MySQL, PostgreSQL, SQL Server | PostgreSQL备份恢复时,要求实例不能有副本 |
|
||||
// | 平台 | 支持引擎 | 说明 |
|
||||
// | ----- | ------ | --- |
|
||||
// | 华为云 |MySQL, SQL Server | 仅SQL Server支持恢复到当前实例 |
|
||||
// | 阿里云 |MySQL, SQL Server | MySQL要求必须开启单库单表恢复功能 并且只能是MySQL 8.0 高可用版(本地SSD盘)MySQL 5.7 高可用版(本地SSD盘)或MySQL 5.6 高可用版, MySQL仅支持恢复到当前实例|
|
||||
// | Google |MySQL, PostgreSQL, SQL Server | PostgreSQL备份恢复时,要求实例不能有副本 |
|
||||
DBInstancebackupId string `json:"dbinstancebackup_id"`
|
||||
|
||||
// 数据库信息, 例如 {"src":"dest"} 是将备份中的src数据库恢复到目标实例的dest数据库中, 阿里云此参数为必传
|
||||
|
||||
@@ -27,11 +27,11 @@ type SDBInstanceAccountPrivilege struct {
|
||||
//
|
||||
//
|
||||
//
|
||||
// | 平台 |Rds引擎 | 支持类型 |
|
||||
// | ---- |------- | -------- |
|
||||
// | Aliyun |MySQL, MariaBD | rw, r, ddl, dml |
|
||||
// | Aliyun |SQLServer | rw, r, owner |
|
||||
// | Huawei |MySQL, MariaDB | rw, r |
|
||||
// | 平台 |Rds引擎 | 支持类型 |
|
||||
// | ---- |------- | -------- |
|
||||
// | Aliyun |MySQL, MariaBD | rw, r, ddl, dml |
|
||||
// | Aliyun |SQLServer | rw, r, owner |
|
||||
// | Huawei |MySQL, MariaDB | rw, r |
|
||||
// 同一平台不同的rds类型支持的权限不尽相同
|
||||
// required: true
|
||||
Privilege string `json:"privilege"`
|
||||
@@ -44,11 +44,11 @@ type DBInstanceAccountCreateInput struct {
|
||||
//
|
||||
//
|
||||
//
|
||||
// | 平台 |支持Rds引擎 |
|
||||
// | ---- |------- |
|
||||
// | Aliyun |MySQL, MariaBD, SQLServer |
|
||||
// | 华为云 |MySQL, MariaBD |
|
||||
// | 腾讯云 |MySQL |
|
||||
// | 平台 |支持Rds引擎 |
|
||||
// | ---- |------- |
|
||||
// | Aliyun |MySQL, MariaBD, SQLServer |
|
||||
// | 华为云 |MySQL, MariaBD |
|
||||
// | 腾讯云 |MySQL |
|
||||
// required: true
|
||||
// 阿里云SQL Server 2017集群版不支持创建账号
|
||||
// 实例状态必须是运行中
|
||||
|
||||
@@ -23,11 +23,14 @@ type SDBInstanceDatabasePrivilege struct {
|
||||
// swagger:ignore
|
||||
DBInstanceaccountId string
|
||||
// 权限
|
||||
// | 平台 |Rds引擎 | 支持类型 |
|
||||
// | ---- |------- | -------- |
|
||||
// | Aliyun |MySQL, MariaBD | rw, r, ddl, dml |
|
||||
// | Aliyun |SQLServer | rw, r, owner |
|
||||
// | Huawei |MySQL, MariaDB | rw, r |
|
||||
//
|
||||
//
|
||||
//
|
||||
// | 平台 |Rds引擎 | 支持类型 |
|
||||
// | ---- |------- | -------- |
|
||||
// | Aliyun |MySQL, MariaBD | rw, r, ddl, dml |
|
||||
// | Aliyun |SQLServer | rw, r, owner |
|
||||
// | Huawei |MySQL, MariaDB | rw, r |
|
||||
// 同一平台不同的rds类型支持的权限不尽相同
|
||||
// required: true
|
||||
Privilege string `json:"privilege"`
|
||||
@@ -40,11 +43,11 @@ type DBInstanceDatabaseCreateInput struct {
|
||||
//
|
||||
//
|
||||
//
|
||||
// | 平台 |支持Rds引擎 |
|
||||
// | ---- |------- |
|
||||
// | Aliyun |MySQL, MariaBD, SQLServer |
|
||||
// | 华为云 |MySQL, MariaBD |
|
||||
// | 腾讯云 | |
|
||||
// | 平台 |支持Rds引擎 |
|
||||
// | ---- |------- |
|
||||
// | Aliyun |MySQL, MariaBD, SQLServer |
|
||||
// | 华为云 |MySQL, MariaBD |
|
||||
// | 腾讯云 | |
|
||||
// required: true
|
||||
// 阿里云SQL Server 2017集群版不支持创建数据库
|
||||
// 阿里云只读实例不支持创建数据库
|
||||
|
||||
@@ -142,6 +142,9 @@ type DiskListInput struct {
|
||||
|
||||
FsFormat string `json:"fs_format"`
|
||||
|
||||
OrderByServer string `json:"order_by_server" choices:"asc|desc"`
|
||||
|
||||
OrderByGuestCount string `json:"order_by_guest_count" choices:"asc|desc"`
|
||||
// 镜像
|
||||
ImageId string `json:"image_id"`
|
||||
// swagger:ignore
|
||||
|
||||
@@ -63,3 +63,11 @@ const (
|
||||
DISK_NOT_EXIST = "not_exist"
|
||||
DISK_EXIST = "exist"
|
||||
)
|
||||
|
||||
const (
|
||||
DISK_DRIVER_VIRTIO = "virtio"
|
||||
DISK_DRIVER_SCSI = "scsi"
|
||||
DISK_DRIVER_PVSCSI = "pvscsi"
|
||||
DISK_DRIVER_IDE = "ide"
|
||||
DISK_DRIVER_SATA = "sata"
|
||||
)
|
||||
|
||||
@@ -99,10 +99,10 @@ type DnsZoneCreateInput struct {
|
||||
// 区域类型
|
||||
//
|
||||
//
|
||||
// | 类型 | 说明 |
|
||||
// |---------- |---------|
|
||||
// | PublicZone | 公有 |
|
||||
// | PrivateZone | 私有 |
|
||||
// | 类型 | 说明 |
|
||||
// |---------- |---------|
|
||||
// | PublicZone | 公有 |
|
||||
// | PrivateZone | 私有 |
|
||||
ZoneType string `json:"zone_type"`
|
||||
// 额外参数
|
||||
|
||||
@@ -134,10 +134,10 @@ type DnsZoneListInput struct {
|
||||
// 区域类型
|
||||
//
|
||||
//
|
||||
// | 类型 | 说明 |
|
||||
// |---------- |---------|
|
||||
// | PublicZone | 公有 |
|
||||
// | PrivateZone | 私有 |
|
||||
// | 类型 | 说明 |
|
||||
// |---------- |---------|
|
||||
// | PublicZone | 公有 |
|
||||
// | PrivateZone | 私有 |
|
||||
ZoneType string `json:"zone_type"`
|
||||
|
||||
// Filter dns zone By vpc
|
||||
@@ -152,9 +152,9 @@ type DnsZoneCacheInput struct {
|
||||
// 云账号Id
|
||||
//
|
||||
//
|
||||
// | 要求 |
|
||||
// |---------- |
|
||||
// | 1. dns zone 状态必须为available |
|
||||
// | 要求 |
|
||||
// |---------- |
|
||||
// | 1. dns zone 状态必须为available |
|
||||
// | 2. dns zone zone_type 必须为PublicZone |
|
||||
// | 3. 指定云账号未在云上创建相应的 dns zone |
|
||||
CloudaccountId string
|
||||
|
||||
@@ -110,12 +110,6 @@ type ElasticcacheRemoteUpdateInput struct {
|
||||
ReplaceTags *bool `json:"replace_tags" help:"replace all remote tags"`
|
||||
}
|
||||
|
||||
//type SElasticcacheJointsBase struct {
|
||||
// apis.SVirtualJointResourceBase
|
||||
// // 弹性缓存实例(ID or Name)
|
||||
// ElasticcacheId string `json:"elasticcache_id"`
|
||||
//}
|
||||
|
||||
type ElasticcacheJointResourceDetails struct {
|
||||
apis.VirtualJointResourceBaseDetails
|
||||
|
||||
@@ -140,11 +134,11 @@ type ElasticcacheSecgroupsInput struct {
|
||||
// 实例必须处于运行状态
|
||||
//
|
||||
//
|
||||
// | 平台 | 最多绑定安全组数量 |
|
||||
// |-------------|------------------- |
|
||||
// | 腾讯云 | 10 |
|
||||
// | 华为云 | 不支持安全组 |
|
||||
// | 阿里云 | 不支持安全组 |
|
||||
// | 平台 | 最多绑定安全组数量 |
|
||||
// |-------------|------------------- |
|
||||
// | 腾讯云 | 10 |
|
||||
// | 华为云 | 不支持安全组 |
|
||||
// | 阿里云 | 不支持安全组 |
|
||||
SecgroupIds []string `json:"secgroup_ids"`
|
||||
}
|
||||
|
||||
|
||||
@@ -42,20 +42,20 @@ type SElasticipCreateInput struct {
|
||||
//
|
||||
//
|
||||
//
|
||||
// | 平台 | 支持类型 |
|
||||
// | --- | -------- |
|
||||
// |Aliyun | traffic, bandwidth |
|
||||
// |腾讯云 | traffic |
|
||||
// |Azure | traffic |
|
||||
// |Google | traffic, bandwidth |
|
||||
// |Ucloud | traffic |
|
||||
// |Aws | traffic |
|
||||
// |华为云 | traffic, bandwidth |
|
||||
// |天翼云 | traffic, bandwidth |
|
||||
// |KVM | 不支持创建 |
|
||||
// |VMware | 不支持创建 |
|
||||
// |ZStack | traffic |
|
||||
// |OpenStack | traffic |
|
||||
// | 平台 | 支持类型 |
|
||||
// | --- | -------- |
|
||||
// |Aliyun | traffic, bandwidth |
|
||||
// |腾讯云 | traffic |
|
||||
// |Azure | traffic |
|
||||
// |Google | traffic, bandwidth |
|
||||
// |Ucloud | traffic |
|
||||
// |Aws | traffic |
|
||||
// |华为云 | traffic, bandwidth |
|
||||
// |天翼云 | traffic, bandwidth |
|
||||
// |KVM | 不支持创建 |
|
||||
// |VMware | 不支持创建 |
|
||||
// |ZStack | traffic |
|
||||
// |OpenStack | traffic |
|
||||
// default: traffic
|
||||
// enum: traffic, bandwidth
|
||||
ChargeType string `json:"charge_type"`
|
||||
|
||||
@@ -90,6 +90,7 @@ type GuestnetworkJsonDesc struct {
|
||||
Ifname string `json:"ifname"`
|
||||
Masklen int8 `json:"masklen"`
|
||||
Driver string `json:"driver"`
|
||||
NumQueues int `json:"num_queues"`
|
||||
Vlan int `json:"vlan"`
|
||||
Bw int `json:"bw"`
|
||||
Mtu int `json:"mtu"`
|
||||
|
||||
@@ -73,6 +73,7 @@ type ServerListInput struct {
|
||||
// enum: asc,desc
|
||||
OrderByDisk string `json:"order_by_disk"`
|
||||
|
||||
OrderByIp string `json:"order_by_ip"`
|
||||
// 根据ip查找机器
|
||||
IpAddr string `json:"ip_addr"`
|
||||
|
||||
@@ -397,13 +398,13 @@ type GuestSetSecgroupInput struct {
|
||||
// 实例必须处于运行,休眠或者关机状态
|
||||
//
|
||||
//
|
||||
// | 平台 | 最多绑定安全组数量 |
|
||||
// |-------------|------------------- |
|
||||
// | Azure | 1 |
|
||||
// | VMware | 不支持安全组 |
|
||||
// | Baremetal | 不支持安全组 |
|
||||
// | ZStack | 1 |
|
||||
// | 其他 | 5 |
|
||||
// | 平台 | 最多绑定安全组数量 |
|
||||
// |-------------|------------------- |
|
||||
// | Azure | 1 |
|
||||
// | VMware | 不支持安全组 |
|
||||
// | Baremetal | 不支持安全组 |
|
||||
// | ZStack | 1 |
|
||||
// | 其他 | 5 |
|
||||
SecgroupIds []string `json:"secgroup_ids"`
|
||||
}
|
||||
|
||||
@@ -432,13 +433,13 @@ type GuestAddSecgroupInput struct {
|
||||
// 实例必须处于运行,休眠或者关机状态
|
||||
//
|
||||
//
|
||||
// | 平台 | 最多绑定安全组数量 |
|
||||
// |-------------|------------------- |
|
||||
// | Azure | 1 |
|
||||
// | VMware | 不支持安全组 |
|
||||
// | Baremetal | 不支持安全组 |
|
||||
// | ZStack | 1 |
|
||||
// | 其他 | 5 |
|
||||
// | 平台 | 最多绑定安全组数量 |
|
||||
// |-------------|------------------- |
|
||||
// | Azure | 1 |
|
||||
// | VMware | 不支持安全组 |
|
||||
// | Baremetal | 不支持安全组 |
|
||||
// | ZStack | 1 |
|
||||
// | 其他 | 5 |
|
||||
SecgroupIds []string `json:"secgroup_ids"`
|
||||
}
|
||||
|
||||
@@ -716,7 +717,7 @@ type GuestJsonDesc struct {
|
||||
UserData string `json:"user_data"`
|
||||
PendingDeleted bool `json:"pending_deleted"`
|
||||
|
||||
ScallingGroupId string `json:"scalling_group_id"`
|
||||
ScalingGroupId string `json:"scaling_group_id"`
|
||||
|
||||
// baremetal
|
||||
DiskConfig jsonutils.JSONObject `json:"disk_config"`
|
||||
|
||||
@@ -183,7 +183,7 @@ type HostDetails struct {
|
||||
// CPU超售比
|
||||
CpuCommitBound float32 `json:"cpu_commit_bound"`
|
||||
// 内存超售比
|
||||
MemCommitBound float32 `json:"mem_commint_bound"`
|
||||
MemCommitBound float32 `json:"mem_commit_bound"`
|
||||
// 存储大小
|
||||
Storage int64 `json:"storage"`
|
||||
// 已使用存储大小
|
||||
@@ -204,8 +204,9 @@ type HostDetails struct {
|
||||
CanPrepare bool `json:"can_prepare"`
|
||||
PrepareFailReason string `json:"prepare_fail_reason"`
|
||||
// 允许开启宿主机健康检查
|
||||
AllowHealthCheck bool `json:"allow_health_check"`
|
||||
AutoMigrateOnHostDown bool `json:"auto_migrate_on_host_down"`
|
||||
AllowHealthCheck bool `json:"allow_health_check"`
|
||||
AutoMigrateOnHostDown bool `json:"auto_migrate_on_host_down"`
|
||||
AutoMigrateOnHostShutdown bool `json:"auto_migrate_on_host_shutdown"`
|
||||
|
||||
// reserved resource for isolated device
|
||||
ReservedResourceForGpu IsolatedDeviceReservedResourceInput `json:"reserved_resource_for_gpu"`
|
||||
@@ -450,3 +451,8 @@ type HostOfflineInput struct {
|
||||
UpdateHealthStatus *bool `json:"update_health_status"`
|
||||
Reason string
|
||||
}
|
||||
|
||||
type HostAutoMigrateInput struct {
|
||||
AutoMigrateOnHostDown string `json:"auto_migrate_on_host_down"`
|
||||
AutoMigrateOnHostShutdown string `json:"auto_migrate_on_host_shutdown"`
|
||||
}
|
||||
|
||||
@@ -136,7 +136,14 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
HOST_HEALTH_PREFIX = "/onecloud/kvm/host/health"
|
||||
HOST_HEALTH_STATUS_RUNNING = "running"
|
||||
HOST_HEALTH_LOCK_PREFIX = "host-health"
|
||||
HOST_HEALTH_PREFIX = "/onecloud/kvm/host/health"
|
||||
HOST_HEALTH_STATUS_RUNNING = "running"
|
||||
HOST_HEALTH_STATUS_RECONNECTING = "reconnecting"
|
||||
HOST_HEALTH_STATUS_UNKNOWN = "unknown"
|
||||
HOST_HEALTH_LOCK_PREFIX = "host-health"
|
||||
)
|
||||
|
||||
const (
|
||||
HOSTMETA_AUTO_MIGRATE_ON_HOST_DOWN = "__auto_migrate_on_host_down"
|
||||
HOSTMETA_AUTO_MIGRATE_ON_HOST_SHUTDOWN = "__auto_migrate_on_host_shutdown"
|
||||
)
|
||||
|
||||
@@ -97,6 +97,7 @@ type IsolatedDeviceReservedResourceInput struct {
|
||||
type IsolatedDeviceUpdateInput struct {
|
||||
apis.StandaloneResourceBaseUpdateInput
|
||||
IsolatedDeviceReservedResourceInput
|
||||
DevType string `json:"dev_type"`
|
||||
}
|
||||
|
||||
type IsolatedDeviceJsonDesc struct {
|
||||
|
||||
@@ -53,6 +53,8 @@ type NetworkAddressListInput struct {
|
||||
NetworkFilterListInput
|
||||
|
||||
GuestId []string
|
||||
|
||||
ManagedResourceListInput
|
||||
}
|
||||
|
||||
type NetworkAddressDetails struct {
|
||||
|
||||
@@ -553,4 +553,16 @@ var (
|
||||
City: CITY_US_GOV_WEST,
|
||||
CountryCode: COUNTRY_CODE_US,
|
||||
}
|
||||
RegionJioIndiaWest = cloudprovider.SGeographicInfo{
|
||||
Latitude: 22.4707,
|
||||
Longitude: 70.0577,
|
||||
City: CITY_JAMNAGAR,
|
||||
CountryCode: COUNTRY_CODE_IN,
|
||||
}
|
||||
RegionJioIndiaCentral = cloudprovider.SGeographicInfo{
|
||||
Latitude: 21.1466,
|
||||
Longitude: 79.0889,
|
||||
City: CITY_NAGPUR,
|
||||
CountryCode: COUNTRY_CODE_IN,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -77,14 +77,13 @@ type SchedtagDetails struct {
|
||||
|
||||
SSchedtag
|
||||
|
||||
DynamicSchedtagCount int `json:"dynamic_schedtag_count"`
|
||||
SchedpolicyCount int `json:"schedpolicy_count"`
|
||||
// ProjectId string `json:"project_id"`
|
||||
HostCount int `json:"host_count"`
|
||||
ServerCount int `json:"server_count"`
|
||||
OtherCount int `json:"other_count"`
|
||||
ResourceCount int `json:"resource_count"`
|
||||
JoinModelKeyword string `json:"join_model_keyword"`
|
||||
DynamicSchedtagCount int `json:"dynamic_schedtag_count"`
|
||||
SchedpolicyCount int `json:"schedpolicy_count"`
|
||||
HostCount int `json:"host_count"`
|
||||
ServerCount int `json:"server_count"`
|
||||
OtherCount int `json:"other_count"`
|
||||
ResourceCount int `json:"resource_count"`
|
||||
JoinModelKeyword string `json:"join_model_keyword"`
|
||||
}
|
||||
|
||||
type SchedtagResourceInfo struct {
|
||||
|
||||
@@ -37,23 +37,23 @@ type SSecgroupRuleResource struct {
|
||||
//
|
||||
//
|
||||
//
|
||||
// | protocol | name |
|
||||
// | -------- | ---- |
|
||||
// | any | 所有协议|
|
||||
// | tcp | TCP |
|
||||
// | icmp | ICMP |
|
||||
// | udp | UDP |
|
||||
// | protocol | name |
|
||||
// | -------- | ---- |
|
||||
// | any | 所有协议|
|
||||
// | tcp | TCP |
|
||||
// | icmp | ICMP |
|
||||
// | udp | UDP |
|
||||
// enum: any, tcp, udp, icmp
|
||||
Protocol string `json:"protocol"`
|
||||
|
||||
// 端口列表, 参数为空代表任意端口
|
||||
// 此参数仅对protocol是tcp, udp时生效
|
||||
// 支持格式:
|
||||
// | 格式类型 | 举例 |
|
||||
// | -------- | ---- |
|
||||
// | 单端口 | 22 |
|
||||
// | 端口范围 | 100-200 |
|
||||
// | 不连续端口| 80,443 |
|
||||
// | 格式类型 | 举例 |
|
||||
// | -------- | ---- |
|
||||
// | 单端口 | 22 |
|
||||
// | 端口范围 | 100-200 |
|
||||
// | 不连续端口| 80,443 |
|
||||
// requried: false
|
||||
Ports string `json:"ports"`
|
||||
|
||||
|
||||
@@ -36,16 +36,16 @@ type ServerSkuCreateInput struct {
|
||||
//
|
||||
//
|
||||
//
|
||||
// | instance_type_category | 说明 |
|
||||
// | ----- | --- |
|
||||
// |general_purpose |通用型 |
|
||||
// |burstable |突发性能型 |
|
||||
// |compute_optimized |计算优化型 |
|
||||
// |memory_optimized |内存优化型 |
|
||||
// |storage_optimized |存储IO优化型 |
|
||||
// |hardware_accelerated |硬件加速型 |
|
||||
// |high_storage |高存储型 |
|
||||
// |high_memory |高内存型 |
|
||||
// | instance_type_category | 说明 |
|
||||
// | ----- | --- |
|
||||
// |general_purpose |通用型 |
|
||||
// |burstable |突发性能型 |
|
||||
// |compute_optimized |计算优化型 |
|
||||
// |memory_optimized |内存优化型 |
|
||||
// |storage_optimized |存储IO优化型 |
|
||||
// |hardware_accelerated |硬件加速型 |
|
||||
// |high_storage |高存储型 |
|
||||
// |high_memory |高内存型 |
|
||||
// default: general_purpose
|
||||
InstanceTypeCategory string `json:"instance_type_category"`
|
||||
|
||||
|
||||
@@ -27,16 +27,16 @@ type StorageCreateInput struct {
|
||||
//
|
||||
//
|
||||
//
|
||||
// | storage_type | 参数 |是否必传 | 默认值 | 说明 |
|
||||
// | -------- | ------- | -------- | -------- | --------- |
|
||||
// | rbd | rbd_mon_host | 是 | | ceph mon_host |
|
||||
// | rbd | rbd_pool | 是 | | ceph pool |
|
||||
// | rbd | rbd_key | 否 | |若cephx认证开启,此参数必传 |
|
||||
// | rbd | rbd_rados_mon_op_timeout | 否 | 3 |单位: 秒 |
|
||||
// | rbd | rbd_rados_osd_op_timeout | 否 | 1200 |单位: 秒 |
|
||||
// | rbd | rbd_client_mount_timeout | 否 | 120 |单位: 秒 |
|
||||
// | nfs | nfs_host | 是 | |网络文件系统主机 |
|
||||
// | nfs | nfs_shared_dir | 是 | |网络文件系统共享目录 |
|
||||
// | storage_type | 参数 |是否必传 | 默认值 | 说明 |
|
||||
// | -------- | ------- | -------- | -------- | --------- |
|
||||
// | rbd | rbd_mon_host | 是 | | ceph mon_host |
|
||||
// | rbd | rbd_pool | 是 | | ceph pool |
|
||||
// | rbd | rbd_key | 否 | |若cephx认证开启,此参数必传 |
|
||||
// | rbd | rbd_rados_mon_op_timeout | 否 | 3 |单位: 秒 |
|
||||
// | rbd | rbd_rados_osd_op_timeout | 否 | 1200 |单位: 秒 |
|
||||
// | rbd | rbd_client_mount_timeout | 否 | 120 |单位: 秒 |
|
||||
// | nfs | nfs_host | 是 | |网络文件系统主机 |
|
||||
// | nfs | nfs_shared_dir | 是 | |网络文件系统共享目录 |
|
||||
// local: 本地存储
|
||||
// rbd: ceph块存储, ceph存储创建时仅会检测是否重复创建,不会具体检测认证参数是否合法,只有挂载存储时
|
||||
// 计算节点会验证参数,若挂载失败,宿主机和存储不会关联,可以通过查看存储日志查找挂载失败原因
|
||||
|
||||
@@ -33,10 +33,12 @@ const (
|
||||
STORAGE_PUBLIC_CLOUD = "cloud"
|
||||
STORAGE_CLOUD_EFFICIENCY = "cloud_efficiency"
|
||||
STORAGE_CLOUD_SSD = "cloud_ssd"
|
||||
STORAGE_CLOUD_ESSD = "cloud_essd" //增强型(Enhanced)SSD 云盘, 单盘最高随机读写IOPS 5万
|
||||
STORAGE_CLOUD_ESSD_PL2 = "cloud_essd_pl2" //单盘最高随机读写IOPS 10万
|
||||
STORAGE_CLOUD_ESSD_PL3 = "cloud_essd_pl3" //单盘最高随机读写IOPS 100万
|
||||
STORAGE_EPHEMERAL_SSD = "ephemeral_ssd" //单块本地SSD盘, 容量最大不能超过800 GiB
|
||||
STORAGE_CLOUD_ESSD = "cloud_essd" // 增强型(Enhanced)SSD 云盘, 单盘最高随机读写IOPS 5万
|
||||
STORAGE_CLOUD_ESSD_PL2 = "cloud_essd_pl2" // 单盘最高随机读写IOPS 10万
|
||||
STORAGE_CLOUD_ESSD_PL3 = "cloud_essd_pl3" // 单盘最高随机读写IOPS 100万
|
||||
STORAGE_EPHEMERAL_SSD = "ephemeral_ssd" // 单块本地SSD盘, 容量最大不能超过800 GiB
|
||||
STORAGE_LOCAL_HDD_PRO = "local_hdd_pro" // 实例规格族d1ne和d1搭载的SATA HDD本地盘
|
||||
STORAGE_LOCAL_SSD_PRO = "local_ssd_pro" // 实例规格族i2、i2g、i1、ga1和gn5等搭载的NVMe
|
||||
|
||||
//Azure hdd and ssd storagetype
|
||||
STORAGE_STANDARD_LRS = "standard_lrs"
|
||||
@@ -234,4 +236,7 @@ type StorageListInput struct {
|
||||
|
||||
// filter storages which attached the specified host
|
||||
HostId string `json:"host_id"`
|
||||
|
||||
// filter storages of baremetal host
|
||||
IsBaremetal *bool `json:"is_baremetal"`
|
||||
}
|
||||
|
||||
@@ -465,7 +465,7 @@ type UserCreateInput struct {
|
||||
|
||||
Email string `json:"email"`
|
||||
|
||||
Mobile string `json:"mobule"`
|
||||
Mobile string `json:"mobile"`
|
||||
|
||||
Displayname string `json:"displayname"`
|
||||
|
||||
|
||||
@@ -66,6 +66,8 @@ type Application struct {
|
||||
idleConnsClosed chan struct{}
|
||||
httpServer *http.Server
|
||||
slaveHttpServer *http.Server
|
||||
|
||||
isTLS bool
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -314,6 +316,9 @@ func (app *Application) defaultHandle(w http.ResponseWriter, r *http.Request, ri
|
||||
w.Header().Set("Server", "Yunion AppServer/Go/2018.4")
|
||||
w.Header().Set("X-Frame-Options", "SAMEORIGIN")
|
||||
w.Header().Set("X-XSS-Protection", "1; mode=block")
|
||||
if app.isTLS {
|
||||
w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
|
||||
}
|
||||
isCors := app.handleCORS(w, r)
|
||||
handler := app.getRoot(r.Method).Match(segs, params)
|
||||
if handler != nil {
|
||||
@@ -499,6 +504,7 @@ func (app *Application) ListenAndServeWithoutCleanup(addr, certFile, keyFile str
|
||||
}
|
||||
|
||||
func (app *Application) ListenAndServeTLSWithCleanup2(addr string, certFile, keyFile string, onStop func(), isMaster bool) {
|
||||
app.isTLS = true
|
||||
httpSrv := app.initServer(addr)
|
||||
if isMaster {
|
||||
app.addDefaultHandlers()
|
||||
|
||||
@@ -156,7 +156,7 @@ func SendStream(w http.ResponseWriter, isPartial bool, hdr http.Header, stream i
|
||||
|
||||
func SendRedirect(w http.ResponseWriter, redirectUrl string) {
|
||||
w.Header().Set("Location", redirectUrl)
|
||||
w.WriteHeader(301)
|
||||
w.WriteHeader(302)
|
||||
w.Write([]byte{})
|
||||
}
|
||||
|
||||
|
||||
@@ -25,9 +25,11 @@ import (
|
||||
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
"yunion.io/x/onecloud/pkg/baremetal"
|
||||
"yunion.io/x/onecloud/pkg/baremetal/options"
|
||||
baremetalstatus "yunion.io/x/onecloud/pkg/baremetal/status"
|
||||
"yunion.io/x/onecloud/pkg/baremetal/tasks"
|
||||
baremetaltypes "yunion.io/x/onecloud/pkg/baremetal/types"
|
||||
app_common "yunion.io/x/onecloud/pkg/cloudcommon/app"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
)
|
||||
@@ -60,6 +62,8 @@ func customizeHandlerInfo(info *appsrv.SHandlerInfo) {
|
||||
}
|
||||
|
||||
func initBaremetalsHandler(app *appsrv.Application) {
|
||||
app_common.ExportOptionsHandler(app, &options.Options)
|
||||
|
||||
// baremetal actions handler
|
||||
AddHandler(app, "GET", bmActionPrefix("notify"), bmObjMiddleware(handleBaremetalNotify))
|
||||
AddHandler(app, "POST", bmActionPrefix("maintenance"), bmObjMiddleware(handleBaremetalMaintenance))
|
||||
|
||||
@@ -82,7 +82,7 @@ func (h *DHCPHandler) ServeDHCP(pkt dhcp.Packet, _ *net.UDPAddr, _ *net.Interfac
|
||||
log.Infof("[DHCP] from relay %s packet, mac: %s", req.RelayAddr, req.ClientMac)
|
||||
conf, targets, err := req.fetchConfig(h.baremetalManager.GetClientSession())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, errors.Wrapf(err, "fetchConfig for %s", req.ClientMac.String())
|
||||
}
|
||||
if conf == nil {
|
||||
return nil, nil, fmt.Errorf("Empty packet config")
|
||||
@@ -206,18 +206,18 @@ func (req *dhcpRequest) fetchConfig(session *mcclient.ClientSession) (*dhcp.Resp
|
||||
log.Infof("DHCP relay from %s(%s) for %s, find matched networks: %#v", req.RelayAddr, req.ClientAddr, req.ClientMac, netConf)
|
||||
bmDesc, err := req.createOrUpdateBaremetal(session)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, errors.Wrapf(err, "createOrUpdateBaremetal for %s", req.ClientMac.String())
|
||||
}
|
||||
err = req.doInitBaremetalAdminNetif(bmDesc)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, errors.Wrapf(err, "doInitBaremetalAdminNetif for %s", req.ClientMac.String())
|
||||
}
|
||||
// always response PXE request
|
||||
// let bootloader decide boot local or remote
|
||||
// if req.baremetalInstance.NeedPXEBoot() {
|
||||
conf, err := req.baremetalInstance.GetPXEDHCPConfig(req.ClientArch)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "req.baremetalInstance.GetPXEDHCPConfig")
|
||||
return nil, nil, errors.Wrapf(err, "req.baremetalInstance.GetPXEDHCPConfig for %s", req.ClientMac.String())
|
||||
}
|
||||
return conf, dhcpAddrList, nil
|
||||
|
||||
@@ -243,18 +243,18 @@ func (req *dhcpRequest) fetchConfig(session *mcclient.ClientSession) (*dhcp.Resp
|
||||
err = req.baremetalInstance.InitAdminNetif(
|
||||
req.ClientMac, req.netConfig.WireId, api.NIC_TYPE_IPMI, api.NETWORK_TYPE_IPMI, false, "")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, errors.Wrapf(err, "InitAdminNetif for %s", req.ClientMac.String())
|
||||
}
|
||||
} else {
|
||||
err = req.baremetalInstance.RegisterNetif(req.ClientMac, req.netConfig.WireId)
|
||||
if err != nil {
|
||||
log.Errorf("RegisterNetif error: %v", err)
|
||||
return nil, nil, err
|
||||
log.Errorf("RegisterNetif %s error: %v", req.ClientMac.String(), err)
|
||||
return nil, nil, errors.Wrapf(err, "RegisterNetif for %s", req.ClientMac.String())
|
||||
}
|
||||
}
|
||||
conf, err := req.baremetalInstance.GetDHCPConfig(req.ClientMac)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "req.baremetalInstance.GetDHCPConfig")
|
||||
return nil, nil, errors.Wrapf(err, "req.baremetalInstance.GetDHCPConfig for %s", req.ClientMac.String())
|
||||
}
|
||||
return conf, dhcpAddrList, nil
|
||||
}
|
||||
|
||||
44
pkg/cloudcommon/app/options.go
Normal file
44
pkg/cloudcommon/app/options.go
Normal file
@@ -0,0 +1,44 @@
|
||||
// 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 app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/policy"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
)
|
||||
|
||||
func ExportOptionsHandler(app *appsrv.Application, options interface{}) {
|
||||
hf := func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
|
||||
userCred := auth.FetchUserCredential(ctx, policy.FilterPolicyCredential)
|
||||
result := policy.PolicyManager.Allow(rbacutils.ScopeSystem, userCred, consts.GetServiceType(), "app-options", "list")
|
||||
if result == rbacutils.Deny {
|
||||
httperrors.ForbiddenError(ctx, w, "Not allow to access")
|
||||
return
|
||||
}
|
||||
appsrv.SendJSON(w, jsonutils.Marshal(options))
|
||||
}
|
||||
ahf := auth.Authenticate(hf)
|
||||
name := "get_app_options"
|
||||
app.AddHandler2("GET", "/app-options", ahf, nil, name, nil)
|
||||
}
|
||||
@@ -181,6 +181,8 @@ func ParseNetworkConfig(desc string, idx int) (*compute.NetworkConfig, error) {
|
||||
netConfig.StandbyAddrCount, _ = strconv.Atoi(p[len("standby-addr="):])
|
||||
} else if utils.IsInStringArray(p, []string{"virtio", "e1000", "vmxnet3"}) {
|
||||
netConfig.Driver = p
|
||||
} else if strings.HasPrefix(p, "num-queues=") {
|
||||
netConfig.NumQueues, _ = strconv.Atoi(p[len("num-queues="):])
|
||||
} else if regutils.MatchSize(p) {
|
||||
bw, err := fileutils.GetSizeMb(p, 'M', 1000)
|
||||
if err != nil {
|
||||
|
||||
@@ -22,9 +22,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/appctx"
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
@@ -35,7 +34,7 @@ import (
|
||||
|
||||
var (
|
||||
DefaultAdminSessionGenerator = auth.AdminCredential
|
||||
ErrCronJobNameConflict = errors.New("Cron job Name Conflict")
|
||||
ErrCronJobNameConflict = errors.Error("Cron job Name Conflict")
|
||||
)
|
||||
|
||||
type TCronJobFunction func(ctx context.Context, userCred mcclient.TokenCredential, isStart bool)
|
||||
@@ -164,7 +163,7 @@ func (self *SCronJobManager) AddJobAtIntervals(name string, interval time.Durati
|
||||
|
||||
func (self *SCronJobManager) AddJobAtIntervalsWithStartRun(name string, interval time.Duration, jobFunc TCronJobFunction, startRun bool) error {
|
||||
if interval <= 0 {
|
||||
return errors.New("AddJobAtIntervals: interval must > 0")
|
||||
return errors.Error("AddJobAtIntervals: interval must > 0")
|
||||
}
|
||||
self.dataLock.Lock()
|
||||
defer self.dataLock.Unlock()
|
||||
@@ -193,13 +192,13 @@ func (self *SCronJobManager) AddJobAtIntervalsWithStartRun(name string, interval
|
||||
func (self *SCronJobManager) AddJobEveryFewDays(name string, day, hour, min, sec int, jobFunc TCronJobFunction, startRun bool) error {
|
||||
switch {
|
||||
case day <= 0:
|
||||
return errors.New("AddJobEveryFewDays: day must > 0")
|
||||
return errors.Error("AddJobEveryFewDays: day must > 0")
|
||||
case hour < 0:
|
||||
return errors.New("AddJobEveryFewDays: hour must > 0")
|
||||
return errors.Error("AddJobEveryFewDays: hour must > 0")
|
||||
case min < 0:
|
||||
return errors.New("AddJobEveryFewDays: min must > 0")
|
||||
return errors.Error("AddJobEveryFewDays: min must > 0")
|
||||
case sec < 0:
|
||||
return errors.New("AddJobEveryFewDays: sec must > 0")
|
||||
return errors.Error("AddJobEveryFewDays: sec must > 0")
|
||||
}
|
||||
|
||||
self.dataLock.Lock()
|
||||
@@ -232,11 +231,11 @@ func (self *SCronJobManager) AddJobEveryFewDays(name string, day, hour, min, sec
|
||||
func (self *SCronJobManager) AddJobEveryFewHour(name string, hour, min, sec int, jobFunc TCronJobFunction, startRun bool) error {
|
||||
switch {
|
||||
case hour <= 0:
|
||||
return errors.New("AddJobEveryFewHour: hour must > 0")
|
||||
return errors.Error("AddJobEveryFewHour: hour must > 0")
|
||||
case min < 0:
|
||||
return errors.New("AddJobEveryFewHour: min must > 0")
|
||||
return errors.Error("AddJobEveryFewHour: min must > 0")
|
||||
case sec < 0:
|
||||
return errors.New("AddJobEveryFewHour: sec must > 0")
|
||||
return errors.Error("AddJobEveryFewHour: sec must > 0")
|
||||
}
|
||||
|
||||
self.dataLock.Lock()
|
||||
|
||||
@@ -519,6 +519,8 @@ func ListItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
|
||||
limit, _ := query.Int("limit")
|
||||
offset, _ := query.Int("offset")
|
||||
pagingMarker, _ := query.GetString("paging_marker")
|
||||
pagingOrderStr, _ := query.GetString("paging_order")
|
||||
pagingOrder := sqlchemy.QueryOrderType(strings.ToUpper(pagingOrderStr))
|
||||
|
||||
var (
|
||||
q *sqlchemy.SQuery
|
||||
@@ -559,6 +561,9 @@ func ListItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
|
||||
if limit <= 0 {
|
||||
limit = int64(pagingConf.DefaultLimit)
|
||||
}
|
||||
if pagingOrder != sqlchemy.SQL_ORDER_ASC && pagingOrder != sqlchemy.SQL_ORDER_DESC {
|
||||
pagingOrder = pagingConf.Order
|
||||
}
|
||||
}
|
||||
|
||||
splitable := manager.GetSplitTable()
|
||||
@@ -584,7 +589,7 @@ func ListItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
|
||||
markers := decodePagingMarker(pagingMarker)
|
||||
for markerIdx, marker := range markers {
|
||||
if markerIdx < len(pagingConf.MarkerFields) {
|
||||
if pagingConf.Order == sqlchemy.SQL_ORDER_ASC {
|
||||
if pagingOrder == sqlchemy.SQL_ORDER_ASC {
|
||||
subq = subq.GE(pagingConf.MarkerFields[markerIdx], marker)
|
||||
} else {
|
||||
subq = subq.LE(pagingConf.MarkerFields[markerIdx], marker)
|
||||
@@ -593,7 +598,7 @@ func ListItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
|
||||
}
|
||||
}
|
||||
for _, f := range pagingConf.MarkerFields {
|
||||
if pagingConf.Order == sqlchemy.SQL_ORDER_ASC {
|
||||
if pagingOrder == sqlchemy.SQL_ORDER_ASC {
|
||||
subq = subq.Asc(f)
|
||||
} else {
|
||||
subq = subq.Desc(f)
|
||||
@@ -653,7 +658,7 @@ func ListItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
|
||||
// orders defined in pagingConf should have the highest priority
|
||||
if pagingConf != nil {
|
||||
for _, f := range pagingConf.MarkerFields {
|
||||
if pagingConf.Order == sqlchemy.SQL_ORDER_ASC {
|
||||
if pagingOrder == sqlchemy.SQL_ORDER_ASC {
|
||||
q = q.Asc(f)
|
||||
} else {
|
||||
q = q.Desc(f)
|
||||
@@ -727,7 +732,7 @@ func ListItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
|
||||
markers := decodePagingMarker(pagingMarker)
|
||||
for markerIdx, marker := range markers {
|
||||
if markerIdx < len(pagingConf.MarkerFields) {
|
||||
if pagingConf.Order == sqlchemy.SQL_ORDER_ASC {
|
||||
if pagingOrder == sqlchemy.SQL_ORDER_ASC {
|
||||
q = q.GE(pagingConf.MarkerFields[markerIdx], marker)
|
||||
} else {
|
||||
q = q.LE(pagingConf.MarkerFields[markerIdx], marker)
|
||||
@@ -752,7 +757,7 @@ func ListItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
|
||||
Data: retList, Limit: int(limit),
|
||||
NextMarker: nextMarker,
|
||||
MarkerField: strings.Join(pagingConf.MarkerFields, ","),
|
||||
MarkerOrder: string(pagingConf.Order),
|
||||
MarkerOrder: string(pagingOrder),
|
||||
}
|
||||
return &retResult, nil
|
||||
}
|
||||
|
||||
@@ -164,6 +164,10 @@ func (manager *SProjectizedResourceBaseManager) FetchCustomizeColumns(
|
||||
}
|
||||
}
|
||||
}
|
||||
domainRows := manager.SDomainizedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
for i := range ret {
|
||||
ret[i].DomainizedResourceInfo = domainRows[i]
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ type SVirtualResourceBase struct {
|
||||
IsSystem bool `nullable:"true" default:"false" list:"admin" create:"optional" json:"is_system"`
|
||||
|
||||
// 资源放入回收站时间
|
||||
PendingDeletedAt time.Time `json:"pending_deleted_at" list:"user"`
|
||||
PendingDeletedAt time.Time `json:"pending_deleted_at" list:"user" update:"admin"`
|
||||
// 资源是否处于回收站中
|
||||
PendingDeleted bool `nullable:"false" default:"false" index:"true" get:"user" list:"user" json:"pending_deleted"`
|
||||
// 资源是否被冻结
|
||||
|
||||
@@ -121,7 +121,7 @@ func NewEtcdClient(opt *SEtcdOptions, onKeepaliveFailure func()) (*SEtcdClient,
|
||||
|
||||
etcdClient.namespace = opt.EtcdNamspace
|
||||
|
||||
err = etcdClient.startSession()
|
||||
err = etcdClient.startSession(context.TODO())
|
||||
if err != nil {
|
||||
if e := etcdClient.Close(); e != nil {
|
||||
log.Errorf("etcd client close failed %s", e)
|
||||
@@ -150,16 +150,14 @@ func (cli *SEtcdClient) SessionLiving() bool {
|
||||
return cli.leaseLiving
|
||||
}
|
||||
|
||||
func (cli *SEtcdClient) startSession() error {
|
||||
ctx := context.TODO()
|
||||
|
||||
func (cli *SEtcdClient) startSession(ctx context.Context) error {
|
||||
resp, err := cli.client.Grant(ctx, int64(cli.leaseTtlTimeout))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cli.leaseId = resp.ID
|
||||
|
||||
ch, err := cli.client.KeepAlive(ctx, cli.leaseId)
|
||||
ch, err := cli.client.KeepAlive(context.Background(), cli.leaseId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -185,7 +183,15 @@ func (cli *SEtcdClient) RestartSession() error {
|
||||
if cli.leaseLiving {
|
||||
return errors.Error("session is living, can't restart")
|
||||
}
|
||||
return cli.startSession()
|
||||
ctx := context.TODO()
|
||||
return cli.startSession(ctx)
|
||||
}
|
||||
|
||||
func (cli *SEtcdClient) RestartSessionWithContext(ctx context.Context) error {
|
||||
if cli.leaseLiving {
|
||||
return errors.Error("session is living, can't restart")
|
||||
}
|
||||
return cli.startSession(ctx)
|
||||
}
|
||||
|
||||
func (cli *SEtcdClient) getKey(key string) string {
|
||||
|
||||
@@ -295,6 +295,10 @@ func ParseOptions(optStruct interface{}, args []string, configFileName string, s
|
||||
if err != nil {
|
||||
log.Fatalf("Set log level %q: %v", optionsRef.LogLevel, err)
|
||||
}
|
||||
log.Infof("Set log level to %q", optionsRef.LogLevel)
|
||||
log.Logger().Formatter = &log.TextFormatter{
|
||||
TimestampFormat: "2006-01-02 15:04:05",
|
||||
}
|
||||
if optionsRef.LogFilePrefix != "" {
|
||||
dir, name := filepath.Split(optionsRef.LogFilePrefix)
|
||||
h := &hooks.LogFileRotateHook{
|
||||
|
||||
@@ -256,6 +256,9 @@ func (manager *SCloudproviderManager) syncCloudeventTask(ctx context.Context, us
|
||||
}
|
||||
|
||||
func (manager *SCloudproviderManager) SyncCloudeventTask(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
if options.Options.DisableSyncCloudEvent {
|
||||
return
|
||||
}
|
||||
err := manager.syncCloudeventTask(ctx, userCred)
|
||||
if err != nil {
|
||||
log.Errorf("syncCloudeventTask error: %v", err)
|
||||
|
||||
@@ -23,6 +23,8 @@ type CloudeventOptions struct {
|
||||
CloudproviderSyncIntervalMinutes int `help:"frequency to sync region cloudprovider task" default:"15"`
|
||||
CloudeventSyncIntervalHours int `help:"frequency to sync cloud event task" default:"1"`
|
||||
|
||||
DisableSyncCloudEvent bool `help:"disable sync cloudevent" default:"false"`
|
||||
|
||||
SyncWithReadEvent bool `help:"sync read operation events" default:"false"`
|
||||
OneSyncForHours int `help:"Onece sync for hours" default:"1"`
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ package models
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
@@ -27,11 +29,81 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/samlutils/idp"
|
||||
)
|
||||
|
||||
func (d *SHuaweiSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
// not supported
|
||||
func (d *SHuaweiSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider, redirectUrl string) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
data := samlutils.SSAMLIdpInitiatedLoginData{}
|
||||
_account, err := CloudaccountManager.FetchById(cloudAccountId)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
return data, httperrors.NewResourceNotFoundError2("cloudaccount", cloudAccountId)
|
||||
}
|
||||
return data, httperrors.NewGeneralError(err)
|
||||
}
|
||||
account := _account.(*SCloudaccount)
|
||||
if account.Provider != api.CLOUD_PROVIDER_HUAWEI && account.Provider != api.CLOUD_PROVIDER_HCSO {
|
||||
return data, httperrors.NewClientError("cloudaccount %s is %s not %s", account.Id, account.Provider, api.CLOUD_PROVIDER_HUAWEI)
|
||||
}
|
||||
if account.SAMLAuth.IsFalse() {
|
||||
return data, httperrors.NewNotSupportedError("cloudaccount %s not open saml auth", account.Id)
|
||||
}
|
||||
|
||||
return data, httperrors.ErrNotSupported
|
||||
saml, valid := account.IsSAMLProviderValid()
|
||||
if !valid {
|
||||
return data, httperrors.NewResourceNotReadyError("SAMLProvider for account %s not ready", account.Id)
|
||||
}
|
||||
|
||||
uri := saml.AuthUrl
|
||||
if len(uri) == 0 {
|
||||
return data, httperrors.NewResourceNotReadyError("saml provider no auth url")
|
||||
}
|
||||
url, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return data, httperrors.NewInputParameterError("parse saml auth url %s error", uri)
|
||||
}
|
||||
|
||||
domainId := url.Query().Get("domain_id")
|
||||
idpId := url.Query().Get("idp")
|
||||
if len(domainId) == 0 {
|
||||
return data, httperrors.NewInputParameterError("saml auth url %s missing domain_id", uri)
|
||||
}
|
||||
if len(idpId) == 0 {
|
||||
return data, httperrors.NewInputParameterError("saml auth url %s missing idp", uri)
|
||||
}
|
||||
groups, err := account.GetUserCloudgroups(userCred.GetUserId())
|
||||
if err != nil {
|
||||
return data, httperrors.NewGeneralError(errors.Wrapf(err, "GetUserCloudgroups"))
|
||||
}
|
||||
if len(groups) == 0 {
|
||||
return data, httperrors.NewResourceNotFoundError("no available group found")
|
||||
}
|
||||
|
||||
data.NameId = userCred.GetUserName()
|
||||
data.NameIdFormat = samlutils.NAME_ID_FORMAT_TRANSIENT
|
||||
data.AudienceRestriction = sp.GetEntityId()
|
||||
for k, v := range map[string][]string{
|
||||
"User": {userCred.GetUserName()},
|
||||
"Groups": groups,
|
||||
} {
|
||||
data.Attributes = append(data.Attributes, samlutils.SSAMLResponseAttribute{
|
||||
Name: k, FriendlyName: k,
|
||||
NameFormat: "urn:oasis:names:tc:SAML:2.0:attrname-format:uri",
|
||||
Values: v,
|
||||
})
|
||||
}
|
||||
data.Attributes = append(data.Attributes, samlutils.SSAMLResponseAttribute{
|
||||
Name: "IAM_SAML_Attributes_identityProviders", FriendlyName: "IAM_SAML_Attributes_identityProviders",
|
||||
NameFormat: "urn:oasis:names:tc:SAML:2.0:attrname-format:basic",
|
||||
Values: []string{fmt.Sprintf("iam::%s:identityProvider:%s", domainId, idpId)},
|
||||
})
|
||||
|
||||
if len(redirectUrl) > 0 {
|
||||
data.Attributes = append(data.Attributes, samlutils.SSAMLResponseAttribute{
|
||||
Name: "IAM_SAML_Attributes_redirect_url", FriendlyName: "IAM_SAML_Attributes_redirect_url",
|
||||
NameFormat: "urn:oasis:names:tc:SAML:2.0:attrname-format:basic",
|
||||
Values: []string{redirectUrl},
|
||||
})
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (d *SHuaweiSAMLDriver) GetSpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider) (samlutils.SSAMLSpInitiatedLoginData, error) {
|
||||
@@ -78,6 +150,5 @@ func (d *SHuaweiSAMLDriver) GetSpInitiatedLoginData(ctx context.Context, userCre
|
||||
Values: v,
|
||||
})
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ type ICloudSAMLLoginDriver interface {
|
||||
GetMetadataFilename() string
|
||||
GetMetadataUrl() string
|
||||
|
||||
GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider) (samlutils.SSAMLIdpInitiatedLoginData, error)
|
||||
GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider, redirectUrl string) (samlutils.SSAMLIdpInitiatedLoginData, error)
|
||||
GetSpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccoutId string, sp *idp.SSAMLServiceProvider) (samlutils.SSAMLSpInitiatedLoginData, error)
|
||||
}
|
||||
|
||||
|
||||
@@ -46,18 +46,9 @@ func initSAMLIdp(app *appsrv.Application, prefix string) error {
|
||||
return data, errors.Wrap(err, "driver.GetSpInitiatedLoginData")
|
||||
}
|
||||
return data, nil
|
||||
/*
|
||||
switch sp.GetEntityId() {
|
||||
case SAML_ENTITY_ID_HUAWEI_CLOUD: // 华为云 SSO
|
||||
|
||||
case SAML_ENTITY_ID_TENCENT_CLOUD: // 腾讯云 role SSO
|
||||
|
||||
}
|
||||
return data
|
||||
*/
|
||||
}
|
||||
|
||||
idpFunc := func(ctx context.Context, sp *idp.SSAMLServiceProvider, idpId string) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
idpFunc := func(ctx context.Context, sp *idp.SSAMLServiceProvider, idpId, redirectUrl string) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
token := auth.FetchUserCredential(ctx, nil)
|
||||
log.Debugf("Recive IDP initiated Login: %s", sp.GetEntityId())
|
||||
data := samlutils.SSAMLIdpInitiatedLoginData{}
|
||||
@@ -65,7 +56,7 @@ func initSAMLIdp(app *appsrv.Application, prefix string) error {
|
||||
if driver == nil {
|
||||
return data, errors.Wrapf(httperrors.ErrResourceNotFound, "entityID %s not found", sp.GetEntityId())
|
||||
}
|
||||
data, err := driver.GetIdpInitiatedLoginData(ctx, token, idpId, sp)
|
||||
data, err := driver.GetIdpInitiatedLoginData(ctx, token, idpId, sp, redirectUrl)
|
||||
if err != nil {
|
||||
return data, errors.Wrap(err, "driver.GetIdpInitiatedLoginData")
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/samlutils/idp"
|
||||
)
|
||||
|
||||
func (d *SAliyunSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
func (d *SAliyunSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider, redirectUrl string) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
data := samlutils.SSAMLIdpInitiatedLoginData{}
|
||||
|
||||
_account, err := models.CloudaccountManager.FetchById(cloudAccountId)
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/samlutils/idp"
|
||||
)
|
||||
|
||||
func (d *SAWSSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
func (d *SAWSSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider, redirectUrl string) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
data := samlutils.SSAMLIdpInitiatedLoginData{}
|
||||
|
||||
_account, err := models.CloudaccountManager.FetchById(cloudAccountId)
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/samlutils/idp"
|
||||
)
|
||||
|
||||
func (d *SAWSCNSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
func (d *SAWSCNSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider, redirectUrl string) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
data := samlutils.SSAMLIdpInitiatedLoginData{}
|
||||
_account, err := models.CloudaccountManager.FetchById(cloudAccountId)
|
||||
if err != nil {
|
||||
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/samlutils/idp"
|
||||
)
|
||||
|
||||
func (d *SAzureSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
func (d *SAzureSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider, redirectUrl string) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
data := samlutils.SSAMLIdpInitiatedLoginData{}
|
||||
|
||||
_account, err := models.CloudaccountManager.FetchById(cloudAccountId)
|
||||
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/samlutils/idp"
|
||||
)
|
||||
|
||||
func (d *SGoogleSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
func (d *SGoogleSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider, redirectUrl string) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
// not supported
|
||||
data := samlutils.SSAMLIdpInitiatedLoginData{}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/samlutils/idp"
|
||||
)
|
||||
|
||||
func (d *SQcloudSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
func (d *SQcloudSAMLDriver) GetIdpInitiatedLoginData(ctx context.Context, userCred mcclient.TokenCredential, cloudAccountId string, sp *idp.SSAMLServiceProvider, redirectUrl string) (samlutils.SSAMLIdpInitiatedLoginData, error) {
|
||||
data := samlutils.SSAMLIdpInitiatedLoginData{}
|
||||
|
||||
_account, err := models.CloudaccountManager.FetchById(cloudAccountId)
|
||||
|
||||
@@ -37,70 +37,80 @@ func (self *SAzureCloudReport) CollectRegionMetric(region cloudprovider.ICloudRe
|
||||
|
||||
func (self *SAzureCloudReport) collectRegionMetricOfHost(region cloudprovider.ICloudRegion,
|
||||
servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
azureReg := region.(*azure.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, server := range servers {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
srvId, _ := server.GetString("id")
|
||||
srvName, _ := server.GetString("name")
|
||||
srvPrefix := srvId + "/" + "srvName"
|
||||
external_id, err := server.GetString("external_id")
|
||||
externalId, err := server.GetString("external_id")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
classicKey := "microsoft.classiccompute/virtualmachines"
|
||||
ns, metricSpecs := self.getMetricSpecs(server)
|
||||
if strings.Contains(strings.ToLower(external_id), classicKey) {
|
||||
if strings.Contains(strings.ToLower(externalId), classicKey) {
|
||||
ns = classicKey
|
||||
metricSpecs = azureClassicMetricsSpec
|
||||
}
|
||||
metricNameArr := make([]string, 0)
|
||||
for metricName := range metricSpecs {
|
||||
metricNameArr = append(metricNameArr, metricName)
|
||||
// SQLServer with databases/master
|
||||
if strings.Contains(strings.ToLower(externalId), "microsoft.sql/servers") {
|
||||
externalId = fmt.Sprintf("%s/databases/master", externalId)
|
||||
}
|
||||
metricNames := strings.Join(metricNameArr, ",")
|
||||
azureReg.GetClient().Debug(true)
|
||||
rtnMetrics, err := azureReg.GetMonitorData(metricNames, ns, external_id, since, until, self.Args.MetricInterval)
|
||||
if err != nil {
|
||||
log.Errorf("get metrics for server %s error: %v", srvPrefix, err)
|
||||
continue
|
||||
}
|
||||
if rtnMetrics == nil || rtnMetrics.Value == nil {
|
||||
log.Warningf("server %s metrics is nil", srvPrefix)
|
||||
continue
|
||||
}
|
||||
for metricName, influxDbSpecs := range metricSpecs {
|
||||
for _, value := range *rtnMetrics.Value {
|
||||
if value.Name.LocalizedValue != nil {
|
||||
if metricName == *(value.Name.LocalizedValue) || (value.Name.Value != nil && *value.Name.Value == metricName) {
|
||||
if self.Operator == string(common.SERVER) {
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "fill vm %q capacity", srvPrefix)
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
}
|
||||
if value.Timeseries != nil {
|
||||
for _, timeserie := range *value.Timeseries {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, timeserie, influxDbSpecs)
|
||||
|
||||
err = func() error {
|
||||
metricNameArr := make([]string, 0)
|
||||
for metricName := range metricSpecs {
|
||||
metricNameArr = append(metricNameArr, metricName)
|
||||
}
|
||||
metricNames := strings.Join(metricNameArr, ",")
|
||||
rtnMetrics, err := azureReg.GetMonitorData(metricNames, ns, externalId, since, until, self.Args.MetricInterval)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetMonitorData")
|
||||
}
|
||||
if rtnMetrics == nil || rtnMetrics.Value == nil {
|
||||
return fmt.Errorf("server %s metic is nil", srvPrefix)
|
||||
}
|
||||
|
||||
for metricName, influxDbSpecs := range metricSpecs {
|
||||
for _, value := range *rtnMetrics.Value {
|
||||
if value.Name.LocalizedValue != nil {
|
||||
if metricName == *(value.Name.LocalizedValue) || (value.Name.Value != nil && *value.Name.Value == metricName) {
|
||||
if self.Operator == string(common.SERVER) {
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "collect metrics from server %q", srvPrefix)
|
||||
return errors.Wrapf(err, "fill vm %q capacity", srvPrefix)
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
}
|
||||
if value.Timeseries != nil {
|
||||
for _, timeserie := range *value.Timeseries {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, timeserie, influxDbSpecs)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "collect metrics from server %q", srvPrefix)
|
||||
}
|
||||
dataList = append(dataList, serverMetric...)
|
||||
}
|
||||
dataList = append(dataList, serverMetric...)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
if err != nil {
|
||||
log.Errorf("collect azure %s %s %s metric error: %v", externalId, ns, srvName, err)
|
||||
continue
|
||||
}
|
||||
log.Infof("send %s %s %d metrics", ns, externalId, len(dataList))
|
||||
err = common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
if err != nil {
|
||||
log.Errorf("send %q metrics error: %v", srvName, err)
|
||||
}
|
||||
dataList = dataList[:0]
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -181,7 +191,7 @@ func (self *SAzureCloudReport) getRdsMetricSpecsByEngine(res jsonutils.JSONObjec
|
||||
}
|
||||
switch engine {
|
||||
case com_api.DBINSTANCE_TYPE_SQLSERVER:
|
||||
return "Microsoft.Sql/servers/databases", azureRdsMetricsSpec
|
||||
return "Microsoft.Sql/servers/databases", azureRdsMetricsSpecSqlserver
|
||||
case com_api.DBINSTANCE_TYPE_MYSQL:
|
||||
return fmt.Sprintf("Microsoft.DBforMySQL/%s", suffix), azureRdsMetricsSpec
|
||||
case com_api.DBINSTANCE_TYPE_POSTGRESQL:
|
||||
|
||||
@@ -192,10 +192,10 @@ var azureRdsMetricsSpec = map[string][]string{
|
||||
}
|
||||
|
||||
var azureRdsMetricsSpecSqlserver = map[string][]string{
|
||||
"cpu_percent": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"memory_usage_percent": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_MEM_USAGE},
|
||||
"storage_percent": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_DISK_USAGE},
|
||||
"connections_failed": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIELD_RDS_CONN_FAILED},
|
||||
"cpu_percent": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"sqlserver_process_memory_percent": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_MEM_USAGE},
|
||||
"storage_percent": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_DISK_USAGE},
|
||||
"connection_failed": {DEFAULT_STATISTICS, UNIT_COUNT, INFLUXDB_FIELD_RDS_CONN_FAILED},
|
||||
}
|
||||
|
||||
var azureElbMetricSpecs = map[string][]string{
|
||||
|
||||
@@ -142,10 +142,7 @@ func (self *CloudReportBase) InitProviderInstance() (cloudprovider.ICloudProvide
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getCloudAccount error")
|
||||
}
|
||||
options, err := cloudAccout.Get("options")
|
||||
if err != nil {
|
||||
log.Errorf("get cloudAccout options err:%v", err)
|
||||
}
|
||||
options, _ := cloudAccout.Get("options")
|
||||
if options == nil || options.Interface() == nil {
|
||||
options = jsonutils.NewDict()
|
||||
}
|
||||
|
||||
@@ -90,6 +90,8 @@ type PingProbeOptions struct {
|
||||
Debug bool `help:"debug"`
|
||||
ProbeCount int `help:"probe count, default is 3" default:"3"`
|
||||
TimeoutSecond int `help:"probe timeout in second, default is 1 second" default:"1"`
|
||||
|
||||
DisablePingProbe bool `help:"disable ping probe"`
|
||||
}
|
||||
|
||||
var InstanceProviders = "Aliyun,Azure,Aws,Qcloud,VMWare,Huawei,Openstack,Ucloud,ZStack"
|
||||
|
||||
@@ -34,6 +34,9 @@ import (
|
||||
)
|
||||
|
||||
func pingProbeCoolector(s *mcclient.ClientSession, args *common.ReportOptions) error {
|
||||
if args.DisablePingProbe {
|
||||
return nil
|
||||
}
|
||||
isRoot := sysutils.IsRootPermission()
|
||||
if !isRoot {
|
||||
return errors.Error("require root permissions")
|
||||
|
||||
@@ -109,38 +109,38 @@ type SCloudaccount struct {
|
||||
//
|
||||
//
|
||||
//
|
||||
// | 云平台 |字段 | 翻译 | 是否必传 | 默认值 | 可否更新 | 获取方式 |
|
||||
// | ------ |------ | ------ | --------- | -------- |-------- |-------- |
|
||||
// |Aliyun |access_key_id |秘钥ID | 是 | | 是 | |
|
||||
// |Aliyun |access_key_secret |秘钥Key | 是 | | 是 | |
|
||||
// |Qcloud |app_id |APP ID | 是 | | 否 | |
|
||||
// |Qcloud |secret_id |秘钥ID | 是 | | 是 | |
|
||||
// |Qcloud |secret_key |秘钥Key | 是 | | 是 | |
|
||||
// |OpenStack |project_name |用户所在项目 | 是 | | 是 | |
|
||||
// |OpenStack |username |用户名 | 是 | | 是 | |
|
||||
// |OpenStack |password |用户密码 | 是 | | 是 | |
|
||||
// |OpenStack |auth_url |认证地址 | 是 | | 否 | |
|
||||
// |OpenStack |domain_name |用户所在的域 | 否 |Default | 是 | |
|
||||
// |VMware |username |用户名 | 是 | | 是 | |
|
||||
// |VMware |password |密码 | 是 | | 是 | |
|
||||
// |VMware |host |主机IP或域名 | 是 | | 否 | |
|
||||
// |VMware |port |主机端口 | 否 |443 | 否 | |
|
||||
// |Azure |directory_id |目录ID | 是 | | 否 | |
|
||||
// |Azure |environment |区域 | 是 | | 否 | |
|
||||
// |Azure |client_id |客户端ID | 是 | | 是 | |
|
||||
// |Azure |client_secret |客户端密码 | 是 | | 是 | |
|
||||
// |Huawei |access_key_id |秘钥ID | 是 | | 是 | |
|
||||
// |Huawei |access_key_secret |秘钥 | 是 | | 是 | |
|
||||
// |Huawei |environment |区域 | 是 | | 否 | |
|
||||
// |Aws |access_key_id |秘钥ID | 是 | | 是 | |
|
||||
// |Aws |access_key_secret |秘钥 | 是 | | 是 | |
|
||||
// |Aws |environment |区域 | 是 | | 否 | |
|
||||
// |Ucloud |access_key_id |秘钥ID | 是 | | 是 | |
|
||||
// |Ucloud |access_key_secret |秘钥 | 是 | | 是 | |
|
||||
// |Google |project_id |项目ID | 是 | | 否 | |
|
||||
// |Google |client_email |客户端email | 是 | | 否 | |
|
||||
// |Google |private_key_id |秘钥ID | 是 | | 是 | |
|
||||
// |Google |private_key |秘钥Key | 是 | | 是 | |
|
||||
// | 云平台 |字段 | 翻译 | 是否必传 | 默认值 | 可否更新 | 获取方式 |
|
||||
// | ------ |------ | ------ | --------- | -------- |-------- |-------- |
|
||||
// |Aliyun |access_key_id |秘钥ID | 是 | | 是 | |
|
||||
// |Aliyun |access_key_secret |秘钥Key | 是 | | 是 | |
|
||||
// |Qcloud |app_id |APP ID | 是 | | 否 | |
|
||||
// |Qcloud |secret_id |秘钥ID | 是 | | 是 | |
|
||||
// |Qcloud |secret_key |秘钥Key | 是 | | 是 | |
|
||||
// |OpenStack |project_name |用户所在项目 | 是 | | 是 | |
|
||||
// |OpenStack |username |用户名 | 是 | | 是 | |
|
||||
// |OpenStack |password |用户密码 | 是 | | 是 | |
|
||||
// |OpenStack |auth_url |认证地址 | 是 | | 否 | |
|
||||
// |OpenStack |domain_name |用户所在的域 | 否 |Default | 是 | |
|
||||
// |VMware |username |用户名 | 是 | | 是 | |
|
||||
// |VMware |password |密码 | 是 | | 是 | |
|
||||
// |VMware |host |主机IP或域名 | 是 | | 否 | |
|
||||
// |VMware |port |主机端口 | 否 |443 | 否 | |
|
||||
// |Azure |directory_id |目录ID | 是 | | 否 | |
|
||||
// |Azure |environment |区域 | 是 | | 否 | |
|
||||
// |Azure |client_id |客户端ID | 是 | | 是 | |
|
||||
// |Azure |client_secret |客户端密码 | 是 | | 是 | |
|
||||
// |Huawei |access_key_id |秘钥ID | 是 | | 是 | |
|
||||
// |Huawei |access_key_secret |秘钥 | 是 | | 是 | |
|
||||
// |Huawei |environment |区域 | 是 | | 否 | |
|
||||
// |Aws |access_key_id |秘钥ID | 是 | | 是 | |
|
||||
// |Aws |access_key_secret |秘钥 | 是 | | 是 | |
|
||||
// |Aws |environment |区域 | 是 | | 否 | |
|
||||
// |Ucloud |access_key_id |秘钥ID | 是 | | 是 | |
|
||||
// |Ucloud |access_key_secret |秘钥 | 是 | | 是 | |
|
||||
// |Google |project_id |项目ID | 是 | | 否 | |
|
||||
// |Google |client_email |客户端email | 是 | | 否 | |
|
||||
// |Google |private_key_id |秘钥ID | 是 | | 是 | |
|
||||
// |Google |private_key |秘钥Key | 是 | | 是 | |
|
||||
Account string `json:"account"`
|
||||
|
||||
// swagger:ignore
|
||||
|
||||
@@ -673,8 +673,9 @@ func CompareDnsRecordSet(iRecords []ICloudDnsRecordSet, local []DnsRecordSet, de
|
||||
remoteRecord, ok := remoteMaps[key]
|
||||
if ok {
|
||||
record.ExternalId = remoteRecord.ExternalId
|
||||
remoteRecord.Id = record.Id
|
||||
if !record.Equals(remoteRecord) {
|
||||
updated = append(updated, record)
|
||||
updated = append(updated, remoteRecord)
|
||||
} else {
|
||||
common = append(common, record)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package cloudprovider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -71,6 +72,10 @@ type SaveImageOptions struct {
|
||||
}
|
||||
|
||||
func CloudImage2Image(image ICloudImage) SImage {
|
||||
uefiSupport := false
|
||||
if image.GetBios() == BIOS {
|
||||
uefiSupport = true
|
||||
}
|
||||
return SImage{
|
||||
CreatedAt: image.GetCreatedAt(),
|
||||
Deleted: false,
|
||||
@@ -81,10 +86,13 @@ func CloudImage2Image(image ICloudImage) SImage {
|
||||
MinRamMB: image.GetMinRamSizeMb(),
|
||||
Name: image.GetName(),
|
||||
Properties: map[string]string{
|
||||
"os_full_name": image.GetFullOsName(),
|
||||
"os_type": string(image.GetOsType()),
|
||||
"os_distribution": image.GetOsDist(),
|
||||
"os_version": image.GetOsVersion(),
|
||||
"os_arch": image.GetOsArch(),
|
||||
"os_language": image.GetOsLang(),
|
||||
"uefi_support": fmt.Sprintf("%v", uefiSupport),
|
||||
},
|
||||
Protected: true,
|
||||
SizeBytes: image.GetSizeByte(),
|
||||
|
||||
@@ -33,6 +33,22 @@ var (
|
||||
OsTypeWindows = TOsType(osprofile.OS_TYPE_WINDOWS)
|
||||
)
|
||||
|
||||
type TBiosType string
|
||||
|
||||
var (
|
||||
BIOS = TBiosType("BIOS")
|
||||
UEFI = TBiosType("UEFI")
|
||||
)
|
||||
|
||||
func ToBiosType(bios string) TBiosType {
|
||||
switch strings.ToLower(bios) {
|
||||
case "uefi", "efi":
|
||||
return UEFI
|
||||
default:
|
||||
return BIOS
|
||||
}
|
||||
}
|
||||
|
||||
type SDistDefaultAccount struct {
|
||||
// 操作系统发行版
|
||||
OsDistribution string
|
||||
@@ -168,9 +184,7 @@ func (vmConfig *SManagedVMCreateConfig) GetConfig(config *jsonutils.JSONDict) er
|
||||
if strings.ToLower(vmConfig.OsType) == strings.ToLower(osprofile.OS_TYPE_LINUX) {
|
||||
adminPublicKey, _ := config.GetString("admin_public_key")
|
||||
projectPublicKey, _ := config.GetString("project_public_key")
|
||||
oUserData, _ := config.GetString("user_data")
|
||||
|
||||
vmConfig.UserData = generateUserData(adminPublicKey, projectPublicKey, oUserData)
|
||||
vmConfig.UserData = generateUserData(adminPublicKey, projectPublicKey, vmConfig.UserData)
|
||||
}
|
||||
|
||||
resetPassword := jsonutils.QueryBoolean(config, "reset_password", false)
|
||||
|
||||
@@ -12,4 +12,18 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tasks // import "yunion.io/x/onecloud/pkg/monitor/tasks"
|
||||
package cloudprovider
|
||||
|
||||
type IOSInfo interface {
|
||||
GetFullOsName() string
|
||||
GetOsType() TOsType
|
||||
GetOsDist() string
|
||||
GetOsVersion() string
|
||||
GetOsArch() string
|
||||
GetOsLang() string
|
||||
GetBios() TBiosType
|
||||
}
|
||||
|
||||
func IsUEFI(ios IOSInfo) bool {
|
||||
return ios.GetBios() == UEFI
|
||||
}
|
||||
@@ -207,21 +207,20 @@ type ICloudZone interface {
|
||||
type ICloudImage interface {
|
||||
IVirtualResource
|
||||
|
||||
IOSInfo
|
||||
|
||||
Delete(ctx context.Context) error
|
||||
GetIStoragecache() ICloudStoragecache
|
||||
|
||||
GetSizeByte() int64
|
||||
GetImageType() TImageType
|
||||
GetImageStatus() string
|
||||
GetOsType() TOsType
|
||||
GetOsDist() string
|
||||
GetOsVersion() string
|
||||
GetOsArch() string
|
||||
|
||||
GetMinOsDiskSizeGb() int
|
||||
GetMinRamSizeMb() int
|
||||
GetImageFormat() string
|
||||
GetCreatedAt() time.Time
|
||||
UEFI() bool
|
||||
|
||||
GetPublicScope() rbacutils.TRbacScope
|
||||
GetSubImages() []SSubImage
|
||||
}
|
||||
@@ -314,6 +313,8 @@ type ICloudVM interface {
|
||||
IBillingResource
|
||||
IVirtualResource
|
||||
|
||||
IOSInfo
|
||||
|
||||
ConvertPublicIpToEip() error
|
||||
|
||||
GetIHost() ICloudHost
|
||||
@@ -334,10 +335,12 @@ type ICloudVM interface {
|
||||
GetBootOrder() string
|
||||
GetVga() string
|
||||
GetVdi() string
|
||||
GetOSArch() string
|
||||
GetOsType() TOsType
|
||||
GetOSName() string
|
||||
GetBios() string
|
||||
|
||||
// GetOSArch() string
|
||||
// GetOsType() TOsType
|
||||
// GetOSName() string
|
||||
// GetBios() string
|
||||
|
||||
GetMachine() string
|
||||
GetInstanceType() string
|
||||
|
||||
|
||||
@@ -503,9 +503,11 @@ func CompareRules(src, dest SecRuleInfo, debug bool) (common, inAdds, outAdds, i
|
||||
outCommon, outAdds, outDels = _compare(srcOutRules, destOutRules)
|
||||
}
|
||||
|
||||
var handleDefaultRules = func(removed, added []SecurityRule, isOnlyAllowList bool) ([]SecurityRule, []SecurityRule) {
|
||||
var handleDefaultRules = func(removed, added []SecurityRule, isOnlyAllowList bool) ([]SecurityRule, []SecurityRule, *SecurityRule) {
|
||||
ret := []SecurityRule{}
|
||||
for _, rule := range removed {
|
||||
var defaultRule *SecurityRule = nil
|
||||
for i := range removed {
|
||||
rule := removed[i]
|
||||
if rule.ExternalId == DEFAULT_DEST_RULE_ID {
|
||||
if debug {
|
||||
log.Debugf("remove dest default rule: %s external id %s priority: %d", rule.String(), rule.ExternalId, rule.Priority)
|
||||
@@ -520,30 +522,32 @@ func CompareRules(src, dest SecRuleInfo, debug bool) (common, inAdds, outAdds, i
|
||||
rule.Action = secrules.SecurityRuleDeny
|
||||
}
|
||||
rule.Priority = dest.MinPriority
|
||||
|
||||
find := false
|
||||
for i := range added {
|
||||
if added[i].String() == rule.String() {
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !find {
|
||||
if debug {
|
||||
log.Debugf("add new default rule: %s external id %s priority: %d", rule.String(), rule.ExternalId, rule.Priority)
|
||||
}
|
||||
added = append(added, rule)
|
||||
}
|
||||
defaultRule = &rule
|
||||
} else {
|
||||
ret = append(ret, rule)
|
||||
}
|
||||
}
|
||||
return ret, added
|
||||
return ret, added, defaultRule
|
||||
}
|
||||
|
||||
inDels, inAdds = handleDefaultRules(inDels, inAdds, dest.IsOnlySupportAllowRules)
|
||||
outDels, outAdds = handleDefaultRules(outDels, outAdds, dest.IsOnlySupportAllowRules)
|
||||
_common, _ := handleDefaultRules(append(inCommon, outCommon...), []SecurityRule{}, dest.IsOnlySupportAllowRules)
|
||||
var inDefault *SecurityRule
|
||||
var outDefault *SecurityRule
|
||||
inDels, inAdds, inDefault = handleDefaultRules(inDels, inAdds, dest.IsOnlySupportAllowRules)
|
||||
if inDefault != nil {
|
||||
inAllow, _ := append(inAdds, inCommon...).AllowList()
|
||||
if len(inAllow.String()) == 0 || (!strings.Contains(inAllow.String(), inDefault.String()) && !srcInAllowList.Equals(inAllow)) {
|
||||
inAdds = append(inAdds, *inDefault)
|
||||
}
|
||||
}
|
||||
outDels, outAdds, outDefault = handleDefaultRules(outDels, outAdds, dest.IsOnlySupportAllowRules)
|
||||
|
||||
if outDefault != nil {
|
||||
outAllow, _ := append(outAdds, outCommon...).AllowList()
|
||||
if len(outAllow.String()) == 0 || (!strings.Contains(outAllow.String(), outDefault.String()) && !srcOutAllowList.Equals(outAllow)) {
|
||||
outAdds = append(outAdds, *outDefault)
|
||||
}
|
||||
}
|
||||
_common, _, _ := handleDefaultRules(append(inCommon, outCommon...), []SecurityRule{}, dest.IsOnlySupportAllowRules)
|
||||
common = append(common, _common...)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package cloudprovider
|
||||
|
||||
type SSubAccount struct {
|
||||
Name string
|
||||
Desc string
|
||||
Account string
|
||||
HealthStatus string // 云端服务健康状态。例如欠费、项目冻结都属于不健康状态。
|
||||
DefaultProjectId string // 默认云订阅项目Id
|
||||
|
||||
@@ -110,7 +110,7 @@ func (proxyendpoint *SProxyEndpoint) remoteCheckMake(ctx context.Context, userCr
|
||||
case <-time.After(2 * time.Second):
|
||||
}
|
||||
}
|
||||
return httperrors.NewConflictError("remote sshd_config may have a problem with GatewayPorts")
|
||||
// return httperrors.NewConflictError("remote sshd_config may have a problem with GatewayPorts")
|
||||
}
|
||||
|
||||
func (proxyendpoint *SProxyEndpoint) remoteConfigure(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
|
||||
@@ -63,6 +63,7 @@ func (self *SManagedVirtualizedGuestDriver) GetJsonDescAtHost(ctx context.Contex
|
||||
config.Name = guest.Name
|
||||
config.Cpu = int(guest.VcpuCount)
|
||||
config.MemoryMB = guest.VmemSize
|
||||
config.UserData = guest.GetUserData(ctx, userCred)
|
||||
config.Description = guest.Description
|
||||
if params != nil {
|
||||
params.Unmarshal(&config.SPublicIpInfo)
|
||||
@@ -128,7 +129,8 @@ func (self *SManagedVirtualizedGuestDriver) GetJsonDescAtHost(ctx context.Contex
|
||||
}
|
||||
}
|
||||
|
||||
if guest.BillingType == billing_api.BILLING_TYPE_PREPAID {
|
||||
// 避免因同步包年包月实例billing_cycle失败,导致重置虚拟机密码异常
|
||||
if guest.BillingType == billing_api.BILLING_TYPE_PREPAID && len(guest.BillingCycle) > 0 {
|
||||
bc, err := billing.ParseBillingCycle(guest.BillingCycle)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "ParseBillingCycle(%s)", guest.BillingCycle)
|
||||
@@ -211,6 +213,12 @@ func (self *SManagedVirtualizedGuestDriver) ValidateCreateData(ctx context.Conte
|
||||
if input.Cdrom != "" {
|
||||
return nil, httperrors.NewInputParameterError("%s not support cdrom params", input.Hypervisor)
|
||||
}
|
||||
if len(input.UserData) > 0 {
|
||||
_, err := cloudinit.ParseUserData(input.UserData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return input, nil
|
||||
}
|
||||
|
||||
@@ -361,7 +369,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestDeployGuestOnHost(ctx context
|
||||
|
||||
desc.Tags, _ = guest.GetAllUserMetadata()
|
||||
|
||||
//创建并同步安全组规则
|
||||
//创建并同步安全组规则, 仅新建的安全组会同步规则
|
||||
{
|
||||
vpc, err := guest.GetVpc()
|
||||
if err != nil {
|
||||
@@ -382,7 +390,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestDeployGuestOnHost(ctx context
|
||||
return errors.Wrap(err, "GetSecgroups")
|
||||
}
|
||||
for i, secgroup := range secgroups {
|
||||
externalId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, task.GetUserCred(), vpcId, vpc, &secgroup, desc.ProjectId, "")
|
||||
externalId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, task.GetUserCred(), vpcId, vpc, &secgroup, desc.ProjectId, "", true)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "RequestSyncSecurityGroup")
|
||||
}
|
||||
@@ -994,11 +1002,10 @@ func (self *SManagedVirtualizedGuestDriver) OnGuestDeployTaskDataReceived(ctx co
|
||||
|
||||
disks, _ := guest.GetGuestDisks()
|
||||
if len(disks) != len(diskInfo) {
|
||||
msg := fmt.Sprintf("inconsistent disk number: guest have %d disks, data contains %d disks", len(disks), len(diskInfo))
|
||||
log.Errorf(msg)
|
||||
return fmt.Errorf(msg)
|
||||
// 公有云镜像可能包含数据盘, 若忽略设置磁盘的external id, 会导致部分磁盘状态异常
|
||||
log.Warningf("inconsistent disk number: guest have %d disks, data contains %d disks", len(disks), len(diskInfo))
|
||||
}
|
||||
for i := 0; i < len(diskInfo); i += 1 {
|
||||
for i := 0; i < len(diskInfo) && i < len(disks); i += 1 {
|
||||
disk := disks[i].GetDisk()
|
||||
_, err = db.Update(disk, func() error {
|
||||
disk.DiskSize = diskInfo[i].Size
|
||||
@@ -1087,6 +1094,12 @@ func (self *SManagedVirtualizedGuestDriver) OnGuestDeployTaskDataReceived(ctx co
|
||||
}
|
||||
|
||||
guest.SaveDeployInfo(ctx, task.GetUserCred(), data)
|
||||
|
||||
iVM, err := guest.GetIVM()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "guest.GetIVM")
|
||||
}
|
||||
guest.SyncOsInfo(ctx, task.GetUserCred(), iVM)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1123,7 +1136,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestSyncSecgroupsOnHost(ctx conte
|
||||
}
|
||||
externalIds := []string{}
|
||||
for _, secgroup := range secgroups {
|
||||
externalId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, task.GetUserCred(), vpcId, vpc, &secgroup, remoteProjectId, "")
|
||||
externalId, err := region.GetDriver().RequestSyncSecurityGroup(ctx, task.GetUserCred(), vpcId, vpc, &secgroup, remoteProjectId, "", true)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "RequestSyncSecurityGroup")
|
||||
}
|
||||
@@ -1334,6 +1347,7 @@ func (self *SManagedVirtualizedGuestDriver) RequestRemoteUpdate(ctx context.Cont
|
||||
logclient.AddSimpleActionLog(guest, logclient.ACT_UPDATE_TAGS, tagsUpdateInfo, userCred, true)
|
||||
// sync back cloud metadata
|
||||
iVM.Refresh()
|
||||
guest.SyncOsInfo(ctx, userCred, iVM)
|
||||
err = models.SyncVirtualResourceMetadata(ctx, userCred, guest, iVM)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "syncVirtualResourceMetadata")
|
||||
|
||||
@@ -50,19 +50,19 @@ func init() {
|
||||
}
|
||||
|
||||
func (self *SOpenStackGuestDriver) DoScheduleCPUFilter() bool {
|
||||
return scheduler.GetOptions().OpenstackSchedulerCPUFilter
|
||||
return scheduler.Options.OpenstackSchedulerCPUFilter
|
||||
}
|
||||
|
||||
func (self *SOpenStackGuestDriver) DoScheduleMemoryFilter() bool {
|
||||
return scheduler.GetOptions().OpenstackSchedulerMemoryFilter
|
||||
return scheduler.Options.OpenstackSchedulerMemoryFilter
|
||||
}
|
||||
|
||||
func (self *SOpenStackGuestDriver) DoScheduleSKUFilter() bool {
|
||||
return scheduler.GetOptions().OpenstackSchedulerSKUFilter
|
||||
return scheduler.Options.OpenstackSchedulerSKUFilter
|
||||
}
|
||||
|
||||
func (self *SOpenStackGuestDriver) DoScheduleStorageFilter() bool {
|
||||
return scheduler.GetOptions().OpenstackSchedulerStorageFilter
|
||||
return scheduler.Options.OpenstackSchedulerStorageFilter
|
||||
}
|
||||
|
||||
func (self *SOpenStackGuestDriver) GetHypervisor() string {
|
||||
|
||||
@@ -202,14 +202,21 @@ func (self *SVirtualizedGuestDriver) ChooseHostStorage(host *models.SHost, guest
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "fetch storages by ids: %v", storageIds)
|
||||
}
|
||||
// try to find mediumType matched storage
|
||||
for _, s := range ss {
|
||||
tmp := s
|
||||
if s.MediumType == diskConfig.Medium {
|
||||
return &tmp, nil
|
||||
var candidates []models.SStorage
|
||||
if len(diskConfig.Medium) > 0 {
|
||||
// try to find mediumType matched storage
|
||||
for i := range ss {
|
||||
if ss[i].MediumType == diskConfig.Medium {
|
||||
candidates = append(candidates, ss[i])
|
||||
}
|
||||
}
|
||||
if len(candidates) == 0 {
|
||||
candidates = ss
|
||||
}
|
||||
} else {
|
||||
candidates = ss
|
||||
}
|
||||
return &ss[0], nil
|
||||
return models.ChooseLeastUsedStorage(candidates, ""), nil
|
||||
}
|
||||
|
||||
func (self *SVirtualizedGuestDriver) RequestGuestCreateInsertIso(ctx context.Context, imageId string, guest *models.SGuest, task taskman.ITask) error {
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -512,7 +513,7 @@ func (self *SCachedimage) syncWithCloudImage(ctx context.Context, userCred mccli
|
||||
if image.GetPublicScope() == rbacutils.ScopeSystem {
|
||||
self.IsPublic = true
|
||||
}
|
||||
self.UEFI = tristate.NewFromBool(image.UEFI())
|
||||
self.UEFI = tristate.NewFromBool(cloudprovider.IsUEFI(image))
|
||||
sImage := cloudprovider.CloudImage2Image(image)
|
||||
self.Info = jsonutils.Marshal(&sImage)
|
||||
self.LastSync = time.Now().UTC()
|
||||
@@ -529,7 +530,7 @@ func (manager *SCachedimageManager) newFromCloudImage(ctx context.Context, userC
|
||||
cachedImage.SetModelManager(manager, &cachedImage)
|
||||
|
||||
cachedImage.Size = image.GetSizeByte()
|
||||
cachedImage.UEFI = tristate.NewFromBool(image.UEFI())
|
||||
cachedImage.UEFI = tristate.NewFromBool(cloudprovider.IsUEFI(image))
|
||||
sImage := cloudprovider.CloudImage2Image(image)
|
||||
cachedImage.Info = jsonutils.Marshal(&sImage)
|
||||
cachedImage.LastSync = time.Now().UTC()
|
||||
@@ -832,8 +833,11 @@ func (manager *SCachedimageManager) AutoCleanImageCaches(ctx context.Context, us
|
||||
caches[i].Delete(ctx, userCred)
|
||||
continue
|
||||
}
|
||||
deleteMark := "-deleted@"
|
||||
db.Update(&caches[i], func() error {
|
||||
caches[i].Name = fmt.Sprintf("%s-deleted@%s", caches[i].Name, timeutils.ShortDate(time.Now()))
|
||||
if !strings.Contains(caches[i].Name, deleteMark) {
|
||||
caches[i].Name = fmt.Sprintf("%s%s%s", caches[i].Name, deleteMark, timeutils.ShortDate(time.Now()))
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -735,6 +735,7 @@ func getGPUs(region *SCloudregion, zone *SZone, domainId string) []string {
|
||||
hosts := hostQuery.SubQuery()
|
||||
|
||||
q := devices.Query(devices.Field("model"))
|
||||
q = q.Startswith("dev_type", "GPU")
|
||||
if region != nil {
|
||||
subq := getRegionZoneSubq(region)
|
||||
q = q.Join(hosts, sqlchemy.Equals(devices.Field("host_id"), hosts.Field("id")))
|
||||
|
||||
@@ -439,26 +439,12 @@ func (manager *SCloudaccountManager) validateCreateData(
|
||||
input.Zone = obj.GetId()
|
||||
}
|
||||
|
||||
var endpointOptions jsonutils.JSONObject
|
||||
if input.SCloudaccountCredential.SApsaraEndpoints != nil {
|
||||
endpointOptions = jsonutils.Marshal(input.SCloudaccountCredential.SApsaraEndpoints)
|
||||
}
|
||||
|
||||
if input.SCloudaccountCredential.SHCSOEndpoints != nil {
|
||||
endpointOptions = jsonutils.Marshal(input.SCloudaccountCredential.SHCSOEndpoints)
|
||||
}
|
||||
|
||||
if input.SCloudaccountCredential.SCtyunExtraOptions != nil {
|
||||
endpointOptions = jsonutils.Marshal(input.SCloudaccountCredential.SCtyunExtraOptions)
|
||||
}
|
||||
|
||||
if endpointOptions != nil {
|
||||
if input.Options == nil {
|
||||
input.Options = jsonutils.NewDict()
|
||||
}
|
||||
|
||||
input.Options.Update(endpointOptions)
|
||||
if input.Options == nil {
|
||||
input.Options = jsonutils.NewDict()
|
||||
}
|
||||
input.Options.Update(jsonutils.Marshal(input.SCloudaccountCredential.SApsaraEndpoints))
|
||||
input.Options.Update(jsonutils.Marshal(input.SCloudaccountCredential.SHCSOEndpoints))
|
||||
input.Options.Update(jsonutils.Marshal(input.SCloudaccountCredential.SCtyunExtraOptions))
|
||||
|
||||
input.SCloudaccount, err = providerDriver.ValidateCreateCloudaccountData(ctx, userCred, input.SCloudaccountCredential)
|
||||
if err != nil {
|
||||
@@ -1034,8 +1020,32 @@ func (self *SCloudaccount) importSubAccount(ctx context.Context, userCred mcclie
|
||||
if err != nil {
|
||||
return nil, isNew, errors.Wrapf(err, "q.First")
|
||||
}
|
||||
if len(provider.ProjectId) == 0 {
|
||||
db.Update(provider, func() error {
|
||||
if len(subAccount.DefaultProjectId) > 0 {
|
||||
proj, err := self.getDefaultExternalProject(subAccount.DefaultProjectId)
|
||||
if err != nil {
|
||||
logclient.AddSimpleActionLog(provider, logclient.ACT_UPDATE, errors.Wrapf(err, "getDefaultExternalProject(%s)", subAccount.DefaultProjectId), userCred, false)
|
||||
} else {
|
||||
provider.DomainId = proj.DomainId
|
||||
provider.ProjectId = proj.ProjectId
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// find default project of domain
|
||||
ownerId := self.GetOwnerId()
|
||||
t, err := db.TenantCacheManager.FindFirstProjectOfDomain(ctx, ownerId.GetProjectDomainId())
|
||||
if err != nil {
|
||||
logclient.AddSimpleActionLog(provider, logclient.ACT_UPDATE, errors.Wrapf(err, "FindFirstProjectOfDomain(%s)", ownerId.GetProjectDomainId()), userCred, false)
|
||||
return errors.Wrapf(err, "FindFirstProjectOfDomain(%s)", ownerId.GetProjectDomainId())
|
||||
}
|
||||
provider.DomainId = t.DomainId
|
||||
provider.ProjectId = t.Id
|
||||
return nil
|
||||
})
|
||||
}
|
||||
provider.markProviderConnected(ctx, userCred, subAccount.HealthStatus)
|
||||
provider.updateName(ctx, userCred, subAccount.Name)
|
||||
provider.updateName(ctx, userCred, subAccount.Name, subAccount.Desc)
|
||||
return provider, isNew, nil
|
||||
}
|
||||
// not found, create a new cloudprovider
|
||||
@@ -1049,6 +1059,9 @@ func (self *SCloudaccount) importSubAccount(ctx context.Context, userCred mcclie
|
||||
newCloudprovider.Provider = self.Provider
|
||||
newCloudprovider.AccessUrl = self.AccessUrl
|
||||
newCloudprovider.HealthStatus = subAccount.HealthStatus
|
||||
newCloudprovider.Description = subAccount.Desc
|
||||
newCloudprovider.DomainId = self.DomainId
|
||||
newCloudprovider.ProjectId = self.ProjectId
|
||||
if !options.Options.CloudaccountHealthStatusCheck {
|
||||
newCloudprovider.HealthStatus = api.CLOUD_PROVIDER_HEALTH_NORMAL
|
||||
}
|
||||
@@ -1059,40 +1072,10 @@ func (self *SCloudaccount) importSubAccount(ctx context.Context, userCred mcclie
|
||||
newCloudprovider.SetEnabled(false)
|
||||
newCloudprovider.Status = api.CLOUD_PROVIDER_DISCONNECTED
|
||||
}
|
||||
if len(subAccount.DefaultProjectId) > 0 {
|
||||
proj, err := self.getDefaultExternalProject(subAccount.DefaultProjectId)
|
||||
if err != nil {
|
||||
log.Errorf("getDefaultExternalProject: %v", err)
|
||||
} else {
|
||||
newCloudprovider.DomainId = proj.DomainId
|
||||
newCloudprovider.ProjectId = proj.ProjectId
|
||||
}
|
||||
}
|
||||
if len(newCloudprovider.ProjectId) == 0 && (!self.AutoCreateProject || len(self.ProjectId) > 0) {
|
||||
if len(newCloudprovider.ProjectId) == 0 {
|
||||
ownerId := self.GetOwnerId()
|
||||
if len(self.ProjectId) > 0 {
|
||||
t, err := db.TenantCacheManager.FetchTenantById(ctx, self.ProjectId)
|
||||
if err != nil {
|
||||
log.Errorf("cannot find tenant %s for domain %s", self.ProjectId, ownerId.GetProjectDomainId())
|
||||
return nil, err
|
||||
}
|
||||
ownerId = &db.SOwnerId{
|
||||
DomainId: t.DomainId,
|
||||
ProjectId: t.Id,
|
||||
}
|
||||
} else if ownerId == nil || ownerId.GetProjectDomainId() == userCred.GetProjectDomainId() {
|
||||
if ownerId.GetProjectDomainId() == userCred.GetProjectDomainId() {
|
||||
ownerId = userCred
|
||||
} else {
|
||||
// find default project of domain
|
||||
t, err := db.TenantCacheManager.FindFirstProjectOfDomain(ctx, ownerId.GetProjectDomainId())
|
||||
if err != nil {
|
||||
log.Errorf("cannot find a valid porject for domain %s", ownerId.GetProjectDomainId())
|
||||
return nil, err
|
||||
}
|
||||
ownerId = &db.SOwnerId{
|
||||
DomainId: t.DomainId,
|
||||
ProjectId: t.Id,
|
||||
}
|
||||
}
|
||||
newCloudprovider.DomainId = ownerId.GetProjectDomainId()
|
||||
newCloudprovider.ProjectId = ownerId.GetProjectId()
|
||||
|
||||
@@ -1360,10 +1360,13 @@ func (provider *SCloudprovider) markProviderDisconnected(ctx context.Context, us
|
||||
return provider.ClearSchedDescCache()
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) updateName(ctx context.Context, userCred mcclient.TokenCredential, name string) error {
|
||||
if self.Name != name {
|
||||
func (self *SCloudprovider) updateName(ctx context.Context, userCred mcclient.TokenCredential, name, desc string) error {
|
||||
if self.Name != name || self.Description != desc {
|
||||
diff, err := db.Update(self, func() error {
|
||||
self.Name = name
|
||||
if len(self.Description) == 0 {
|
||||
self.Description = desc
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -270,7 +270,31 @@ func (manager *SDiskManager) OrderByExtraFields(
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SBillingResourceBaseManager.OrderByExtraFields")
|
||||
}
|
||||
if db.NeedOrderQuery([]string{query.OrderByServer}) {
|
||||
guestDiskQuery := GuestdiskManager.Query("disk_id", "guest_id").SubQuery()
|
||||
q = q.LeftJoin(guestDiskQuery, sqlchemy.Equals(q.Field("id"), guestDiskQuery.Field("disk_id")))
|
||||
guestQuery := GuestManager.Query().SubQuery()
|
||||
q.AppendField(q.QueryFields()...)
|
||||
q.AppendField(guestQuery.Field("name", "guest_name"))
|
||||
q.Join(guestQuery, sqlchemy.Equals(guestQuery.Field("id"), guestDiskQuery.Field("guest_id")))
|
||||
db.OrderByFields(q, []string{query.OrderByServer}, []sqlchemy.IQueryField{guestQuery.Field("name")})
|
||||
}
|
||||
if db.NeedOrderQuery([]string{query.OrderByGuestCount}) {
|
||||
guestdisks := GuestdiskManager.Query().SubQuery()
|
||||
disks := DiskManager.Query().SubQuery()
|
||||
guestdiskQ := guestdisks.Query(
|
||||
guestdisks.Field("guest_id"),
|
||||
guestdisks.Field("disk_id"),
|
||||
sqlchemy.COUNT("guest_count", guestdisks.Field("guest_id")),
|
||||
)
|
||||
|
||||
guestdiskQ = guestdiskQ.LeftJoin(disks, sqlchemy.Equals(guestdiskQ.Field("disk_id"), disks.Field("id")))
|
||||
guestdiskSQ := guestdiskQ.GroupBy(guestdiskQ.Field("disk_id")).SubQuery()
|
||||
q.AppendField(q.QueryFields()...)
|
||||
q.AppendField(guestdiskSQ.Field("guest_count"))
|
||||
q = q.LeftJoin(guestdiskSQ, sqlchemy.Equals(q.Field("id"), guestdiskSQ.Field("disk_id")))
|
||||
db.OrderByFields(q, []string{query.OrderByGuestCount}, []sqlchemy.IQueryField{guestdiskQ.Field("guest_count")})
|
||||
}
|
||||
q, err = manager.SVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.VirtualResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.OrderByExtraFields")
|
||||
@@ -286,6 +310,14 @@ func (manager *SDiskManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field s
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
if field == "guest_status" {
|
||||
guestDiskQuery := GuestdiskManager.Query("disk_id", "guest_id").SubQuery()
|
||||
q = q.LeftJoin(guestDiskQuery, sqlchemy.Equals(q.Field("id"), guestDiskQuery.Field("disk_id")))
|
||||
guestQuery := GuestManager.Query().SubQuery()
|
||||
q.AppendField(guestQuery.Field("status", field)).Distinct()
|
||||
q.Join(guestQuery, sqlchemy.Equals(guestQuery.Field("id"), guestDiskQuery.Field("guest_id")))
|
||||
return q, nil
|
||||
}
|
||||
q, err = manager.SStorageResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
@@ -2502,8 +2534,8 @@ func (manager *SDiskManager) CleanPendingDeleteDisks(ctx context.Context, userCr
|
||||
}
|
||||
|
||||
func (manager *SDiskManager) getAutoSnapshotDisksId(isExternal bool) ([]SSnapshotPolicyDisk, error) {
|
||||
|
||||
t := time.Now()
|
||||
tz, _ := time.LoadLocation(options.Options.TimeZone)
|
||||
t := time.Now().In(tz)
|
||||
week := t.Weekday()
|
||||
if week == 0 { // sunday is zero
|
||||
week += 7
|
||||
|
||||
@@ -301,8 +301,8 @@ func (manager *SDnsZoneManager) FetchCustomizeColumns(
|
||||
objs[i] = &caches[i]
|
||||
}
|
||||
cacheDetails := DnsZoneCacheManager.FetchCustomizeColumns(ctx, userCred, jsonutils.NewDict(), objs, stringutils2.SSortedStrings{}, true)
|
||||
for i := range cacheDetails {
|
||||
jsonDict := jsonutils.Marshal(cacheDetails[i]).(*jsonutils.JSONDict)
|
||||
for j := range cacheDetails {
|
||||
jsonDict := jsonutils.Marshal(cacheDetails[j]).(*jsonutils.JSONDict)
|
||||
jsonDict.Update(jsonutils.Marshal(objs[i]).(*jsonutils.JSONDict))
|
||||
rows[i].CloudCaches = append(rows[i].CloudCaches, jsonDict)
|
||||
}
|
||||
|
||||
@@ -88,12 +88,12 @@ type SElasticip struct {
|
||||
Mode string `width:"32" charset:"ascii" get:"user" list:"user" create:"optional"`
|
||||
|
||||
// IP地址
|
||||
IpAddr string `width:"17" charset:"ascii" list:"user"`
|
||||
IpAddr string `width:"17" charset:"ascii" list:"user" update:"admin"`
|
||||
|
||||
// 绑定资源类型
|
||||
AssociateType string `width:"32" charset:"ascii" list:"user"`
|
||||
AssociateType string `width:"32" charset:"ascii" list:"user" update:"admin"`
|
||||
// 绑定资源Id
|
||||
AssociateId string `width:"256" charset:"ascii" list:"user"`
|
||||
AssociateId string `width:"256" charset:"ascii" list:"user" update:"admin"`
|
||||
|
||||
// 带宽大小
|
||||
Bandwidth int `list:"user" create:"optional" default:"0"`
|
||||
@@ -221,6 +221,17 @@ func (manager *SElasticipManager) ListItemFilter(
|
||||
sqlchemy.IsNullOrEmpty(q.Field("associate_id")),
|
||||
),
|
||||
)
|
||||
case api.EIP_ASSOCIATE_TYPE_LOADBALANCER:
|
||||
_lb, err := validators.ValidateModel(userCred, LoadbalancerManager, &query.UsableEipForAssociateId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
lb := _lb.(*SLoadbalancer)
|
||||
q = q.Equals("cloudregion_id", lb.CloudregionId)
|
||||
if len(lb.ManagerId) > 0 {
|
||||
q = q.Equals("manager_id", lb.ManagerId)
|
||||
}
|
||||
q = q.IsNullOrEmpty("associate_type")
|
||||
default:
|
||||
return nil, httperrors.NewInputParameterError("Not support associate type %s, only support %s", associateType, api.EIP_ASSOCIATE_VALID_TYPES)
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
@@ -216,3 +217,20 @@ func (manager *SGroupnetworkManager) getVips(groupId string) ([]string, error) {
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (manager *SGroupnetworkManager) InitializeData() error {
|
||||
grps := GroupManager.Query("id").SubQuery()
|
||||
q := manager.Query().NotIn("group_id", grps)
|
||||
grpnets := make([]SGroupnetwork, 0)
|
||||
err := db.FetchModelObjects(manager, q, &grpnets)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "FetchModelObjects")
|
||||
}
|
||||
for i := range grpnets {
|
||||
err := grpnets[i].Delete(context.Background(), auth.AdminCredential())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Delete")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -227,6 +227,13 @@ func (group *SGroup) GetGuests() []SGuest {
|
||||
}
|
||||
|
||||
func (group *SGroup) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
|
||||
eip, err := group.getElasticIp()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getElasticIp")
|
||||
}
|
||||
if eip != nil {
|
||||
return errors.Wrapf(httperrors.ErrNotEmpty, "group associate with eip %s", eip.IpAddr)
|
||||
}
|
||||
q := GroupguestManager.Query().Equals("group_id", group.Id)
|
||||
count, err := q.CountWithError()
|
||||
if err != nil {
|
||||
@@ -237,8 +244,8 @@ func (group *SGroup) ValidateDeleteCondition(ctx context.Context, info jsonutils
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (group *SGroup) GetNetworks() ([]SGroupnetwork, error) {
|
||||
|
||||
func (group *SGroup) GetNetworks() ([]SGroupnetwork, error) {
|
||||
q := GroupnetworkManager.Query().Equals("group_id", group.Id)
|
||||
groupnets := make([]SGroupnetwork, 0)
|
||||
err := db.FetchModelObjects(GroupnetworkManager, q, &groupnets)
|
||||
@@ -253,16 +260,6 @@ func (group *SGroup) AllowPerformBindGuests(ctx context.Context, userCred mcclie
|
||||
return group.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, group, "bind-guests")
|
||||
}
|
||||
|
||||
func (group *SGroup) getGroupnetworks() ([]SGroupnetwork, error) {
|
||||
ret := make([]SGroupnetwork, 0)
|
||||
q := GroupnetworkManager.Query().Equals("group_id", group.Id)
|
||||
err := db.FetchModelObjects(GroupnetworkManager, q, &ret)
|
||||
if err != nil && errors.Cause(err) != sql.ErrNoRows {
|
||||
return nil, errors.Wrap(err, "FetchModelObjects")
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (group *SGroup) PerformBindGuests(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
|
||||
@@ -287,9 +284,9 @@ func (group *SGroup) PerformBindGuests(ctx context.Context, userCred mcclient.To
|
||||
}
|
||||
|
||||
var networkId string
|
||||
gns, err := group.getGroupnetworks()
|
||||
gns, err := group.GetNetworks()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getGroupnetworks")
|
||||
return nil, errors.Wrap(err, "GetNetworks")
|
||||
}
|
||||
if len(gns) > 0 {
|
||||
networkId = gns[0].NetworkId
|
||||
@@ -700,9 +697,9 @@ func (grp *SGroup) isEipAssociable() (*SNetwork, error) {
|
||||
return nil, errors.Wrap(httperrors.ErrInvalidStatus, "group network is not a VPC network")
|
||||
}
|
||||
|
||||
gns, err := grp.getGroupnetworks()
|
||||
gns, err := grp.GetNetworks()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getGroupnetworks")
|
||||
return nil, errors.Wrap(err, "GetNetworks")
|
||||
}
|
||||
if len(gns) == 0 {
|
||||
return nil, errors.Wrap(httperrors.ErrInvalidStatus, "group no vips")
|
||||
@@ -861,3 +858,18 @@ func (grp *SGroup) PerformDissociateEip(ctx context.Context, userCred mcclient.T
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (grp *SGroup) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
// cleanup groupnetwork
|
||||
grpnets, err := grp.GetNetworks()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetNetworks")
|
||||
}
|
||||
for i := range grpnets {
|
||||
err := grpnets[i].Delete(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "groupnetwork.Delete")
|
||||
}
|
||||
}
|
||||
return grp.SVirtualResourceBase.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
@@ -2585,7 +2585,7 @@ func (self *SGuest) PerformChangeConfig(ctx context.Context, userCred mcclient.T
|
||||
return nil, httperrors.NewInputParameterError("%v", err)
|
||||
}
|
||||
if !utils.IsInStringArray(self.Status, changeStatus) {
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot change config in %s", self.Status)
|
||||
return nil, httperrors.NewInvalidStatusError("Cannot change config in %s for %s, requires %s", self.Status, self.GetHypervisor(), changeStatus)
|
||||
}
|
||||
|
||||
_, err = self.GetHost()
|
||||
@@ -3110,16 +3110,7 @@ func (self *SGuest) AllowPerformAssociateEip(ctx context.Context, userCred mccli
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformAssociateEip(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.ServerAssociateEipInput) (jsonutils.JSONObject, error) {
|
||||
if !utils.IsInStringArray(self.Status, []string{api.VM_READY, api.VM_RUNNING}) {
|
||||
return nil, httperrors.NewInvalidStatusError("cannot associate eip in status %s", self.Status)
|
||||
}
|
||||
|
||||
err := ValidateAssociateEip(self)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = self.IsEipAssociable()
|
||||
err := self.IsEipAssociable()
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
@@ -3247,9 +3238,9 @@ func (self *SGuest) PerformCreateEip(ctx context.Context, userCred mcclient.Toke
|
||||
autoDellocate = (input.AutoDellocate != nil && *input.AutoDellocate)
|
||||
)
|
||||
|
||||
err := ValidateAssociateEip(self)
|
||||
err := self.IsEipAssociable()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
|
||||
if chargeType == "" {
|
||||
@@ -3322,8 +3313,13 @@ func (self *SGuest) setUserData(ctx context.Context, userCred mcclient.TokenCred
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuest) AllowPerformUserData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "user-data")
|
||||
func (self *SGuest) GetUserData(ctx context.Context, userCred mcclient.TokenCredential) string {
|
||||
userData := self.GetMetadata("user_data", userCred)
|
||||
if len(userData) == 0 {
|
||||
return userData
|
||||
}
|
||||
decodeData, _ := userdata.Decode(userData)
|
||||
return decodeData
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformUserData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.ServerUserDataInput) (jsonutils.JSONObject, error) {
|
||||
@@ -3366,6 +3362,13 @@ func (self *SGuest) PerformSetQemuParams(ctx context.Context, userCred mcclient.
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
usbContType, err := data.GetString("usb_controller_type")
|
||||
if err == nil {
|
||||
err = self.SetMetadata(ctx, "usb_controller_type", usbContType, userCred)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -3903,7 +3906,11 @@ func (self *SGuest) PerformPostpaidExpire(ctx context.Context, userCred mcclient
|
||||
}
|
||||
|
||||
err = self.SaveRenewInfo(ctx, userCred, bc, nil, billing_api.BILLING_TYPE_POSTPAID)
|
||||
return nil, err
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_SET_EXPIRED_TIME, input, userCred, true)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SGuest) AllowPerformRenew(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/tristate"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
@@ -48,12 +49,15 @@ func (manager *SGuestManager) FetchCustomizeColumns(
|
||||
virtRows := manager.SVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
hostRows := manager.SHostResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
guestIds := make([]string, len(objs))
|
||||
guests := make([]SGuest, len(objs))
|
||||
for i := range objs {
|
||||
rows[i] = api.ServerDetails{
|
||||
VirtualResourceDetails: virtRows[i],
|
||||
HostResourceInfo: hostRows[i],
|
||||
}
|
||||
guestIds[i] = objs[i].(*SGuest).GetId()
|
||||
guest := objs[i].(*SGuest)
|
||||
guestIds[i] = guest.GetId()
|
||||
guests[i] = *guest
|
||||
}
|
||||
|
||||
if len(fields) == 0 || fields.Contains("disk") {
|
||||
@@ -202,6 +206,14 @@ func (manager *SGuestManager) FetchCustomizeColumns(
|
||||
}
|
||||
}
|
||||
}
|
||||
instanceTypes := fetchGuestGpuInstanceTypes(guestIds)
|
||||
if len(instanceTypes) > 0 {
|
||||
for i := range rows {
|
||||
if utils.IsInStringArray(guests[i].InstanceType, instanceTypes) {
|
||||
rows[i].IsGpu = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(fields) == 0 || fields.Contains("cdrom") {
|
||||
gcds := fetchGuestCdroms(guestIds)
|
||||
@@ -636,6 +648,19 @@ func fetchGuestKeypairs(guestIds []string) map[string]sGuestKeypair {
|
||||
return ret
|
||||
}
|
||||
|
||||
func fetchGuestGpuInstanceTypes(guestIds []string) []string {
|
||||
sq := GuestManager.Query("instance_type").In("id", guestIds).SubQuery()
|
||||
q := ServerSkuManager.Query("name").In("name", sq).GT("gpu_count", 0).Distinct()
|
||||
instanceTypes := []string{}
|
||||
skus, _ := q.AllStringMap()
|
||||
for i := range skus {
|
||||
for _, v := range skus[i] {
|
||||
instanceTypes = append(instanceTypes, v)
|
||||
}
|
||||
}
|
||||
return instanceTypes
|
||||
}
|
||||
|
||||
func fetchGuestIsolatedDevices(guestIds []string) map[string][]api.SIsolatedDevice {
|
||||
q := IsolatedDeviceManager.Query().In("guest_id", guestIds)
|
||||
devs := make([]SIsolatedDevice, 0)
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/compute/options"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
@@ -152,10 +153,10 @@ func (manager *SGuestdiskManager) FetchCustomizeColumns(
|
||||
func (self *SGuestdisk) DoSave(ctx context.Context, driver string, cache string, mountpoint string) error {
|
||||
self.ImagePath = ""
|
||||
if len(driver) == 0 {
|
||||
driver = "scsi"
|
||||
driver = options.Options.DefaultDiskDriver
|
||||
}
|
||||
if len(cache) == 0 {
|
||||
cache = "writeback"
|
||||
cache = options.Options.DefaultDiskCacheMode
|
||||
}
|
||||
if len(mountpoint) > 0 {
|
||||
self.Mountpoint = mountpoint
|
||||
|
||||
@@ -85,6 +85,8 @@ type SGuestnetwork struct {
|
||||
Ip6Addr string `width:"64" charset:"ascii" nullable:"true" list:"user"`
|
||||
// 虚拟网卡驱动
|
||||
Driver string `width:"16" charset:"ascii" nullable:"true" list:"user" update:"user"`
|
||||
// 网卡队列数
|
||||
NumQueues int `nullable:"true" default:"1" list:"user" update:"user"`
|
||||
// 带宽限制,单位mbps
|
||||
BwLimit int `nullable:"false" default:"0" list:"user"`
|
||||
// 网卡序号
|
||||
@@ -264,6 +266,7 @@ type newGuestNetworkArgs struct {
|
||||
macAddr string
|
||||
bwLimit int
|
||||
nicDriver string
|
||||
numQueues int
|
||||
teamWithMac string
|
||||
|
||||
virtual bool
|
||||
@@ -284,6 +287,7 @@ func (manager *SGuestnetworkManager) newGuestNetwork(
|
||||
address = args.ipAddr
|
||||
mac = args.macAddr
|
||||
driver = args.nicDriver
|
||||
numQueues = args.numQueues
|
||||
bwLimit = args.bwLimit
|
||||
virtual = args.virtual
|
||||
reserved = args.tryReserved
|
||||
@@ -302,6 +306,7 @@ func (manager *SGuestnetworkManager) newGuestNetwork(
|
||||
driver = "virtio"
|
||||
}
|
||||
gn.Driver = driver
|
||||
gn.NumQueues = numQueues
|
||||
if bwLimit >= 0 {
|
||||
gn.BwLimit = bwLimit
|
||||
}
|
||||
@@ -592,6 +597,7 @@ func (self *SGuestnetwork) getJsonDesc() *api.GuestnetworkJsonDesc {
|
||||
desc.Ifname = self.GetIfname()
|
||||
desc.Masklen = net.GuestIpMask
|
||||
desc.Driver = self.Driver
|
||||
desc.NumQueues = self.NumQueues
|
||||
desc.Vlan = net.VlanId
|
||||
desc.Bw = self.getBandwidth()
|
||||
desc.Mtu = self.getMtu(net)
|
||||
|
||||
@@ -487,6 +487,7 @@ func (manager *SGuestManager) ListItemFilter(
|
||||
|
||||
devTypeQ := func(q *sqlchemy.SQuery, checkType *bool, dType string) *sqlchemy.SQuery {
|
||||
if checkType != nil {
|
||||
conditions := []sqlchemy.ICondition{}
|
||||
isodev := IsolatedDeviceManager.Query().SubQuery()
|
||||
sgq := isodev.Query(isodev.Field("guest_id")).
|
||||
Filter(sqlchemy.AND(
|
||||
@@ -496,7 +497,12 @@ func (manager *SGuestManager) ListItemFilter(
|
||||
if *checkType {
|
||||
cond = sqlchemy.In
|
||||
}
|
||||
return q.Filter(cond(q.Field("id"), sgq))
|
||||
if dType == "GPU" {
|
||||
sq := ServerSkuManager.Query("name").GT("gpu_count", 0).Distinct().SubQuery()
|
||||
conditions = append(conditions, cond(q.Field("instance_type"), sq))
|
||||
}
|
||||
conditions = append(conditions, cond(q.Field("id"), sgq))
|
||||
return q.Filter(sqlchemy.OR(conditions...))
|
||||
}
|
||||
return q
|
||||
}
|
||||
@@ -638,6 +644,13 @@ func (manager *SGuestManager) OrderByExtraFields(ctx context.Context, q *sqlchem
|
||||
q = q.LeftJoin(guestdiskSQ, sqlchemy.Equals(q.Field("id"), guestdiskSQ.Field("guest_id")))
|
||||
db.OrderByFields(q, []string{query.OrderByDisk}, []sqlchemy.IQueryField{guestdiskSQ.Field("disks_size")})
|
||||
}
|
||||
if db.NeedOrderQuery([]string{query.OrderByIp}) {
|
||||
guestnet := GuestnetworkManager.Query("guest_id", "ip_addr").SubQuery()
|
||||
q.AppendField(q.QueryFields()...)
|
||||
q.AppendField(guestnet.Field("ip_addr"))
|
||||
q = q.LeftJoin(guestnet, sqlchemy.Equals(q.Field("id"), guestnet.Field("guest_id")))
|
||||
db.OrderByFields(q, []string{query.OrderByIp}, []sqlchemy.IQueryField{sqlchemy.INET_ATON(q.Field("ip_addr"))})
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
@@ -2534,7 +2547,7 @@ func (self *SGuest) syncRemoveCloudVM(ctx context.Context, userCred mcclient.Tok
|
||||
}
|
||||
}
|
||||
} else if errors.Cause(err) != cloudprovider.ErrNotFound {
|
||||
return err
|
||||
return errors.Wrap(err, "GetIVMById")
|
||||
}
|
||||
|
||||
if options.SyncPurgeRemovedResources.Contains(self.Keyword()) {
|
||||
@@ -2587,6 +2600,32 @@ func (guest *SGuest) SyncAllWithCloudVM(ctx context.Context, userCred mcclient.T
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *SGuest) SyncOsInfo(ctx context.Context, userCred mcclient.TokenCredential, extVM cloudprovider.IOSInfo) error {
|
||||
// save os info
|
||||
osinfo := map[string]interface{}{}
|
||||
for k, v := range map[string]string{
|
||||
"os_full_name": extVM.GetFullOsName(),
|
||||
"os_name": string(extVM.GetOsType()),
|
||||
"os_arch": extVM.GetOsArch(),
|
||||
"os_type": string(extVM.GetOsType()),
|
||||
"os_distribution": extVM.GetOsDist(),
|
||||
"os_version": extVM.GetOsVersion(),
|
||||
"os_language": extVM.GetOsLang(),
|
||||
} {
|
||||
if len(v) == 0 {
|
||||
continue
|
||||
}
|
||||
osinfo[k] = v
|
||||
}
|
||||
if len(osinfo) > 0 {
|
||||
err := g.SetAllMetadata(ctx, osinfo, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SetAllMetadata")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuest) syncWithCloudVM(ctx context.Context, userCred mcclient.TokenCredential, provider cloudprovider.ICloudProvider, host *SHost, extVM cloudprovider.ICloudVM, syncOwnerId mcclient.IIdentityProvider, syncStatus bool) error {
|
||||
recycle := false
|
||||
|
||||
@@ -2610,9 +2649,15 @@ func (self *SGuest) syncWithCloudVM(ctx context.Context, userCred mcclient.Token
|
||||
self.BootOrder = extVM.GetBootOrder()
|
||||
self.Vga = extVM.GetVga()
|
||||
self.Vdi = extVM.GetVdi()
|
||||
self.OsArch = extVM.GetOSArch()
|
||||
self.OsType = string(extVM.GetOsType())
|
||||
self.Bios = extVM.GetBios()
|
||||
if len(self.OsArch) == 0 {
|
||||
self.OsArch = extVM.GetOsArch()
|
||||
}
|
||||
if len(self.OsType) == 0 {
|
||||
self.OsType = string(extVM.GetOsType())
|
||||
}
|
||||
if len(self.Bios) == 0 {
|
||||
self.Bios = string(extVM.GetBios())
|
||||
}
|
||||
self.Machine = extVM.GetMachine()
|
||||
if !recycle {
|
||||
self.HostId = host.Id
|
||||
@@ -2672,6 +2717,8 @@ func (self *SGuest) syncWithCloudVM(ctx context.Context, userCred mcclient.Token
|
||||
})
|
||||
}
|
||||
|
||||
self.SyncOsInfo(ctx, userCred, extVM)
|
||||
|
||||
syncVirtualResourceMetadata(ctx, userCred, self, extVM)
|
||||
SyncCloudProject(userCred, self, syncOwnerId, extVM, host.ManagerId)
|
||||
|
||||
@@ -2697,9 +2744,9 @@ func (manager *SGuestManager) newCloudVM(ctx context.Context, userCred mcclient.
|
||||
guest.BootOrder = extVM.GetBootOrder()
|
||||
guest.Vga = extVM.GetVga()
|
||||
guest.Vdi = extVM.GetVdi()
|
||||
guest.OsArch = extVM.GetOSArch()
|
||||
guest.OsArch = extVM.GetOsArch()
|
||||
guest.OsType = string(extVM.GetOsType())
|
||||
guest.Bios = extVM.GetBios()
|
||||
guest.Bios = string(extVM.GetBios())
|
||||
guest.Machine = extVM.GetMachine()
|
||||
guest.Hypervisor = extVM.GetHypervisor()
|
||||
|
||||
@@ -2770,6 +2817,8 @@ func (manager *SGuestManager) newCloudVM(ctx context.Context, userCred mcclient.
|
||||
return nil, errors.Wrapf(err, "Insert")
|
||||
}
|
||||
|
||||
guest.SyncOsInfo(ctx, userCred, extVM)
|
||||
|
||||
syncVirtualResourceMetadata(ctx, userCred, &guest, extVM)
|
||||
SyncCloudProject(userCred, &guest, syncOwnerId, extVM, host.ManagerId)
|
||||
|
||||
@@ -2887,6 +2936,7 @@ type Attach2NetworkArgs struct {
|
||||
|
||||
BwLimit int
|
||||
NicDriver string
|
||||
NumQueues int
|
||||
NicConfs []SNicConfig
|
||||
|
||||
Virtual bool
|
||||
@@ -2909,6 +2959,7 @@ func (args *Attach2NetworkArgs) onceArgs(i int) attach2NetworkOnceArgs {
|
||||
|
||||
bwLimit: args.BwLimit,
|
||||
nicDriver: args.NicDriver,
|
||||
numQueues: args.NumQueues,
|
||||
nicConf: args.NicConfs[i],
|
||||
|
||||
virtual: args.Virtual,
|
||||
@@ -2924,6 +2975,7 @@ func (args *Attach2NetworkArgs) onceArgs(i int) attach2NetworkOnceArgs {
|
||||
r.useDesignatedIP = false
|
||||
r.nicConf = args.NicConfs[i]
|
||||
r.nicDriver = ""
|
||||
r.numQueues = 1
|
||||
}
|
||||
return r
|
||||
}
|
||||
@@ -2939,6 +2991,7 @@ type attach2NetworkOnceArgs struct {
|
||||
|
||||
bwLimit int
|
||||
nicDriver string
|
||||
numQueues int
|
||||
nicConf SNicConfig
|
||||
teamWithMac string
|
||||
|
||||
@@ -3009,6 +3062,7 @@ func (self *SGuest) attach2NetworkOnce(
|
||||
macAddr: args.nicConf.Mac,
|
||||
bwLimit: args.bwLimit,
|
||||
nicDriver: nicDriver,
|
||||
numQueues: args.numQueues,
|
||||
teamWithMac: args.teamWithMac,
|
||||
|
||||
virtual: args.virtual,
|
||||
@@ -3268,7 +3322,12 @@ func (self *SGuest) attach2Disk(ctx context.Context, disk *SDisk, userCred mccli
|
||||
// depends the last disk of this guest
|
||||
existingDisks, _ := self.GetGuestDisks()
|
||||
if len(existingDisks) > 0 {
|
||||
driver = existingDisks[len(existingDisks)-1].Driver
|
||||
prevDisk := existingDisks[len(existingDisks)-1]
|
||||
if prevDisk.Driver == api.DISK_DRIVER_IDE {
|
||||
driver = api.DISK_DRIVER_VIRTIO
|
||||
} else {
|
||||
driver = prevDisk.Driver
|
||||
}
|
||||
} else {
|
||||
osProf := self.GetOSProfile()
|
||||
driver = osProf.DiskDriver
|
||||
@@ -3574,6 +3633,13 @@ func (self *SGuest) CreateNetworksOnHost(
|
||||
if candidateNet != nil {
|
||||
networkIds = candidateNet.NetworkIds
|
||||
}
|
||||
if idx == 0 && netConfig.NumQueues == 0 {
|
||||
numQueues := self.VcpuCount / 2
|
||||
if numQueues > 16 {
|
||||
numQueues = 16
|
||||
}
|
||||
netConfig.NumQueues = numQueues
|
||||
}
|
||||
_, err = self.attach2NetworkDesc(ctx, userCred, host, netConfig, pendingUsage, networkIds)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "self.attach2NetworkDesc")
|
||||
@@ -3638,6 +3704,7 @@ func (self *SGuest) attach2NamedNetworkDesc(ctx context.Context, userCred mcclie
|
||||
PendingUsage: pendingUsage,
|
||||
IpAddr: netConfig.Address,
|
||||
NicDriver: netConfig.Driver,
|
||||
NumQueues: netConfig.NumQueues,
|
||||
BwLimit: netConfig.BwLimit,
|
||||
Virtual: netConfig.Vip,
|
||||
TryReserved: netConfig.Reserved,
|
||||
@@ -4261,7 +4328,7 @@ func (self *SGuest) GetJsonDescAtHypervisor(ctx context.Context, host *SHost) *a
|
||||
// add scaling group
|
||||
sggs, err := ScalingGroupGuestManager.Fetch("", self.Id)
|
||||
if err == nil && len(sggs) > 0 {
|
||||
desc.ScallingGroupId = sggs[0].ScalingGroupId
|
||||
desc.ScalingGroupId = sggs[0].ScalingGroupId
|
||||
}
|
||||
|
||||
return desc
|
||||
@@ -4709,6 +4776,9 @@ func (manager *SGuestManager) CleanPendingDeleteServers(ctx context.Context, use
|
||||
for i := 0; i < len(guests); i += 1 {
|
||||
opts := api.ServerDeleteInput{
|
||||
OverridePendingDelete: true,
|
||||
DeleteSnapshots: options.Options.DeleteSnapshotExpiredRelease,
|
||||
DeleteEip: options.Options.DeleteEipExpiredRelease,
|
||||
DeleteDisks: options.Options.DeleteDisksExpiredRelease,
|
||||
}
|
||||
guests[i].StartDeleteGuestTask(ctx, userCred, "", opts)
|
||||
}
|
||||
@@ -4781,7 +4851,6 @@ func (manager *SGuestManager) DeleteExpiredPrepaidServers(ctx context.Context, u
|
||||
if guests == nil {
|
||||
return
|
||||
}
|
||||
deleteSnapshot := options.Options.DeleteSnapshotExpiredRelease
|
||||
for i := 0; i < len(guests); i += 1 {
|
||||
// fake delete expired prepaid servers
|
||||
if len(guests[i].ExternalId) > 0 {
|
||||
@@ -4792,7 +4861,9 @@ func (manager *SGuestManager) DeleteExpiredPrepaidServers(ctx context.Context, u
|
||||
}
|
||||
guests[i].SetDisableDelete(userCred, false)
|
||||
opts := api.ServerDeleteInput{
|
||||
DeleteSnapshots: deleteSnapshot,
|
||||
DeleteSnapshots: options.Options.DeleteSnapshotExpiredRelease,
|
||||
DeleteEip: options.Options.DeleteEipExpiredRelease,
|
||||
DeleteDisks: options.Options.DeleteDisksExpiredRelease,
|
||||
}
|
||||
guests[i].StartDeleteGuestTask(ctx, userCred, "", opts)
|
||||
}
|
||||
@@ -4821,7 +4892,6 @@ func (manager *SGuestManager) DeleteExpiredPostpaidServers(ctx context.Context,
|
||||
log.Infof("No expired postpaid guest")
|
||||
return
|
||||
}
|
||||
deleteSnapshot := options.Options.DeleteSnapshotExpiredRelease
|
||||
for i := 0; i < len(guests); i++ {
|
||||
if len(guests[i].ExternalId) > 0 {
|
||||
err := guests[i].doExternalSync(ctx, userCred)
|
||||
@@ -4830,7 +4900,11 @@ func (manager *SGuestManager) DeleteExpiredPostpaidServers(ctx context.Context,
|
||||
}
|
||||
}
|
||||
guests[i].SetDisableDelete(userCred, false)
|
||||
opts := api.ServerDeleteInput{DeleteSnapshots: deleteSnapshot}
|
||||
opts := api.ServerDeleteInput{
|
||||
DeleteSnapshots: options.Options.DeleteSnapshotExpiredRelease,
|
||||
DeleteEip: options.Options.DeleteEipExpiredRelease,
|
||||
DeleteDisks: options.Options.DeleteDisksExpiredRelease,
|
||||
}
|
||||
guests[i].StartDeleteGuestTask(ctx, userCred, "", opts)
|
||||
}
|
||||
}
|
||||
@@ -4945,8 +5019,16 @@ func (self *SGuest) isInReconcile(userCred mcclient.TokenCredential) bool {
|
||||
}
|
||||
|
||||
func (self *SGuest) IsEipAssociable() error {
|
||||
if !utils.IsInStringArray(self.Status, []string{api.VM_READY, api.VM_RUNNING}) {
|
||||
return errors.Wrapf(httperrors.ErrInvalidStatus, "cannot associate eip in status %s", self.Status)
|
||||
}
|
||||
|
||||
err := ValidateAssociateEip(self)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "ValidateAssociateEip")
|
||||
}
|
||||
|
||||
var eip *SElasticip
|
||||
var err error
|
||||
switch self.Hypervisor {
|
||||
case api.HYPERVISOR_AWS:
|
||||
eip, err = self.GetElasticIp()
|
||||
|
||||
@@ -17,9 +17,12 @@ package models
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
@@ -35,11 +38,11 @@ type SHostHealthChecker struct {
|
||||
// time of wait host reconnect
|
||||
timeout time.Duration
|
||||
// hosts chan
|
||||
hc map[string]chan struct{}
|
||||
hc *sync.Map
|
||||
}
|
||||
|
||||
func hostKey(hostId string) string {
|
||||
return fmt.Sprintf("%s/%s", api.HOST_HEALTH_PREFIX, hostId)
|
||||
func hostKey(hostname string) string {
|
||||
return fmt.Sprintf("%s/%s", api.HOST_HEALTH_PREFIX, hostname)
|
||||
}
|
||||
|
||||
func InitHostHealthChecker(cli *etcd.SEtcdClient, timeout int) *SHostHealthChecker {
|
||||
@@ -49,109 +52,138 @@ func InitHostHealthChecker(cli *etcd.SEtcdClient, timeout int) *SHostHealthCheck
|
||||
hostHealthChecker = &SHostHealthChecker{
|
||||
cli: cli,
|
||||
timeout: time.Duration(timeout) * time.Second,
|
||||
hc: make(map[string]chan struct{}),
|
||||
hc: new(sync.Map),
|
||||
}
|
||||
return hostHealthChecker
|
||||
}
|
||||
|
||||
func (h *SHostHealthChecker) StartHostsHealthCheck(ctx context.Context) {
|
||||
func (h *SHostHealthChecker) StartHostsHealthCheck(ctx context.Context) error {
|
||||
log.Infof("Start host health check......")
|
||||
h.startHealthCheck(ctx)
|
||||
return h.startHealthCheck(ctx)
|
||||
}
|
||||
|
||||
func (h *SHostHealthChecker) startHealthCheck(ctx context.Context) {
|
||||
func (h *SHostHealthChecker) load(hostname string) chan struct{} {
|
||||
v, _ := h.hc.Load(hostname)
|
||||
return v.(chan struct{})
|
||||
}
|
||||
|
||||
func (h *SHostHealthChecker) startHealthCheck(ctx context.Context) error {
|
||||
q := HostManager.Query().IsTrue("enabled").IsTrue("enable_health_check").Equals("host_type", api.HOST_TYPE_HYPERVISOR)
|
||||
rows, err := q.Rows()
|
||||
if err != nil {
|
||||
log.Errorf("HostHealth check Query hosts %s", err)
|
||||
return
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
host := new(SHost)
|
||||
q.Row2Struct(rows, host)
|
||||
err = q.Row2Struct(rows, host)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "q.Row2Struct")
|
||||
}
|
||||
host.SetModelManager(HostManager, host)
|
||||
h.startWatcher(ctx, host.Id)
|
||||
err = h.startWatcher(ctx, host.GetHostnameByName())
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "startWatcher")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *SHostHealthChecker) startWatcher(ctx context.Context, hostId string) {
|
||||
log.Infof("Start watch host %s", hostId)
|
||||
var (
|
||||
ch chan struct{}
|
||||
key = hostKey(hostId)
|
||||
)
|
||||
func (h *SHostHealthChecker) startWatcher(ctx context.Context, hostname string) error {
|
||||
log.Infof("Start watch host %s", hostname)
|
||||
var key = hostKey(hostname)
|
||||
|
||||
if _, ok := h.hc.Load(hostname); !ok {
|
||||
h.hc.Store(hostname, make(chan struct{}))
|
||||
}
|
||||
if err := h.cli.Watch(
|
||||
ctx, key,
|
||||
h.onHostOnline(ctx, hostname),
|
||||
h.onHostOffline(ctx, hostname),
|
||||
h.onHostOfflineDeleted(ctx, hostname),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// watched key not found, wait 60s(default) and do onHostUnhealthy
|
||||
_, err := h.cli.Get(ctx, key)
|
||||
if err == etcd.ErrNoSuchKey {
|
||||
log.Warningf("No such key %s", hostId)
|
||||
ch = make(chan struct{})
|
||||
log.Warningf("No such key %s", hostname)
|
||||
go func() {
|
||||
select {
|
||||
case <-time.NewTimer(h.timeout).C:
|
||||
h.onHostUnhealthy(ctx, hostId)
|
||||
case <-h.hc[hostId]:
|
||||
h.startWatcher(ctx, hostId)
|
||||
h.onHostUnhealthy(ctx, hostname)
|
||||
case <-h.load(hostname):
|
||||
if _err := h.startWatcher(ctx, hostname); _err != nil {
|
||||
log.Errorf("failed start watcher %s", _err)
|
||||
}
|
||||
case <-ctx.Done():
|
||||
log.Infof("exit watch host %s", hostId)
|
||||
log.Infof("exit watch host %s", hostname)
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
if _, ok := h.hc[hostId]; !ok {
|
||||
h.hc[hostId] = ch
|
||||
}
|
||||
h.cli.Watch(ctx, key, h.onHostOnline(ctx, hostId), h.onHostOffline(ctx, hostId), h.onHostOfflineDeleted(ctx, hostId))
|
||||
return err
|
||||
}
|
||||
|
||||
func (h *SHostHealthChecker) onHostUnhealthy(ctx context.Context, hostId string) {
|
||||
lockman.LockRawObject(ctx, api.HOST_HEALTH_LOCK_PREFIX, hostId)
|
||||
defer lockman.ReleaseRawObject(ctx, api.HOST_HEALTH_LOCK_PREFIX, hostId)
|
||||
host := HostManager.FetchHostById(hostId)
|
||||
if host != nil && host.EnableHealthCheck == true {
|
||||
func (h *SHostHealthChecker) onHostUnhealthy(ctx context.Context, hostname string) {
|
||||
lockman.LockRawObject(ctx, api.HOST_HEALTH_LOCK_PREFIX, hostname)
|
||||
defer lockman.ReleaseRawObject(ctx, api.HOST_HEALTH_LOCK_PREFIX, hostname)
|
||||
host := HostManager.FetchHostByHostname(hostname)
|
||||
if host != nil && !utils.IsInStringArray(host.RemoteHealthStatus(ctx),
|
||||
[]string{api.HOST_HEALTH_STATUS_RECONNECTING, api.HOST_HEALTH_STATUS_RUNNING},
|
||||
) {
|
||||
// in case hostagent health manager in status reconnecting
|
||||
host.OnHostDown(ctx, auth.AdminCredential())
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SHostHealthChecker) onHostOnline(ctx context.Context, hostId string) etcd.TEtcdCreateEventFunc {
|
||||
func (h *SHostHealthChecker) onHostOnline(ctx context.Context, hostname string) etcd.TEtcdCreateEventFunc {
|
||||
return func(ctx context.Context, key, value []byte) {
|
||||
log.Infof("Got host online %s", hostId)
|
||||
if h.hc[hostId] != nil {
|
||||
h.hc[hostId] <- struct{}{}
|
||||
log.Infof("Got host online %s", hostname)
|
||||
if v, ok := h.hc.Load(hostname); ok {
|
||||
c := v.(chan struct{})
|
||||
c <- struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SHostHealthChecker) processHostOffline(ctx context.Context, hostId string) {
|
||||
log.Warningf("host %s disconnect with etcd", hostId)
|
||||
func (h *SHostHealthChecker) processHostOffline(ctx context.Context, hostname string) {
|
||||
log.Warningf("host %s disconnect with etcd", hostname)
|
||||
go func() {
|
||||
select {
|
||||
case <-time.NewTimer(h.timeout).C:
|
||||
h.onHostUnhealthy(ctx, hostId)
|
||||
case <-h.hc[hostId]:
|
||||
h.startWatcher(ctx, hostId)
|
||||
h.onHostUnhealthy(ctx, hostname)
|
||||
case <-h.load(hostname):
|
||||
if err := h.startWatcher(ctx, hostname); err != nil {
|
||||
log.Errorf("failed start watcher %s", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (h *SHostHealthChecker) onHostOffline(ctx context.Context, hostId string) etcd.TEtcdModifyEventFunc {
|
||||
func (h *SHostHealthChecker) onHostOffline(ctx context.Context, hostname string) etcd.TEtcdModifyEventFunc {
|
||||
return func(ctx context.Context, key, oldvalue, value []byte) {
|
||||
h.processHostOffline(ctx, hostId)
|
||||
log.Errorf("watch host key modified %s %s %s", key, oldvalue, value)
|
||||
h.processHostOffline(ctx, hostname)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SHostHealthChecker) onHostOfflineDeleted(ctx context.Context, hostId string) etcd.TEtcdDeleteEventFunc {
|
||||
func (h *SHostHealthChecker) onHostOfflineDeleted(ctx context.Context, hostname string) etcd.TEtcdDeleteEventFunc {
|
||||
return func(ctx context.Context, key []byte) {
|
||||
h.processHostOffline(ctx, hostId)
|
||||
log.Errorf("watch host key deleled %s", key)
|
||||
h.processHostOffline(ctx, hostname)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SHostHealthChecker) WatchHost(ctx context.Context, hostId string) {
|
||||
h.cli.Unwatch(hostKey(hostId))
|
||||
h.startWatcher(ctx, hostId)
|
||||
func (h *SHostHealthChecker) WatchHost(ctx context.Context, hostname string) error {
|
||||
h.cli.Unwatch(hostKey(hostname))
|
||||
return h.startWatcher(ctx, hostname)
|
||||
}
|
||||
|
||||
func (h *SHostHealthChecker) UnwatchHost(ctx context.Context, hostId string) {
|
||||
log.Infof("Unwatch host %s", hostId)
|
||||
h.cli.Unwatch(hostKey(hostId))
|
||||
delete(h.hc, hostId)
|
||||
func (h *SHostHealthChecker) UnwatchHost(ctx context.Context, hostname string) {
|
||||
log.Infof("Unwatch host %s", hostname)
|
||||
h.cli.Unwatch(hostKey(hostname))
|
||||
h.hc.Delete(hostname)
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
@@ -57,6 +60,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/esxi"
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
"yunion.io/x/onecloud/pkg/util/k8s/tokens"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
@@ -169,8 +173,9 @@ type SHost struct {
|
||||
// 是否处于维护状态
|
||||
IsMaintenance bool `nullable:"true" default:"false" list:"domain"`
|
||||
|
||||
LastPingAt time.Time ``
|
||||
EnableHealthCheck bool `nullable:"true" default:"false"`
|
||||
LastPingAt time.Time ``
|
||||
// health check enabled by host agent online
|
||||
EnableHealthCheck bool `nullable:"true" default:"false"`
|
||||
|
||||
ResourceType string `width:"36" charset:"ascii" nullable:"false" list:"domain" update:"domain" create:"domain_optional" default:"shared"`
|
||||
|
||||
@@ -1461,7 +1466,7 @@ func _getLeastUsedStorage(storages []SStorage, backends []string) *SStorage {
|
||||
return best
|
||||
}
|
||||
|
||||
func getLeastUsedStorage(storages []SStorage, backend string) *SStorage {
|
||||
func ChooseLeastUsedStorage(storages []SStorage, backend string) *SStorage {
|
||||
var backends []string
|
||||
if backend == api.STORAGE_LOCAL {
|
||||
backends = []string{api.STORAGE_NAS, api.STORAGE_LOCAL}
|
||||
@@ -1476,7 +1481,7 @@ func getLeastUsedStorage(storages []SStorage, backend string) *SStorage {
|
||||
func (self *SHost) GetLeastUsedStorage(backend string) *SStorage {
|
||||
storages := self.GetAttachedEnabledHostStorages(nil)
|
||||
if storages != nil {
|
||||
return getLeastUsedStorage(storages, backend)
|
||||
return ChooseLeastUsedStorage(storages, backend)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -2700,6 +2705,18 @@ func (manager *SHostManager) FetchHostById(hostId string) *SHost {
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SHostManager) FetchHostByHostname(hostname string) *SHost {
|
||||
host := SHost{}
|
||||
host.SetModelManager(manager, &host)
|
||||
err := manager.Query().Startswith("name", hostname).First(&host)
|
||||
if err != nil {
|
||||
log.Errorf("fetch host by hostname %s failed %s", hostname, err)
|
||||
return nil
|
||||
} else {
|
||||
return &host
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SHostManager) totalCountQ(
|
||||
userCred mcclient.IIdentityProvider,
|
||||
scope rbacutils.TRbacScope,
|
||||
@@ -3112,9 +3129,12 @@ func (self *SHost) getMoreDetails(ctx context.Context, out api.HostDetails, show
|
||||
if self.EnableHealthCheck && hostHealthChecker != nil {
|
||||
out.AllowHealthCheck = true
|
||||
}
|
||||
if self.GetMetadata("__auto_migrate_on_host_down", nil) == "enable" {
|
||||
if self.GetMetadata(api.HOSTMETA_AUTO_MIGRATE_ON_HOST_DOWN, nil) == "enable" {
|
||||
out.AutoMigrateOnHostDown = true
|
||||
}
|
||||
if self.GetMetadata(api.HOSTMETA_AUTO_MIGRATE_ON_HOST_SHUTDOWN, nil) == "enable" {
|
||||
out.AutoMigrateOnHostShutdown = true
|
||||
}
|
||||
|
||||
if count, rs := self.GetReservedResourceForIsolatedDevice(); rs != nil {
|
||||
out.ReservedResourceForGpu = *rs
|
||||
@@ -3964,6 +3984,7 @@ func (self *SHost) AllowPerformOffline(ctx context.Context,
|
||||
}
|
||||
|
||||
func (self *SHost) PerformOffline(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input *api.HostOfflineInput) (jsonutils.JSONObject, error) {
|
||||
log.Errorf("input %v", *input.UpdateHealthStatus)
|
||||
if self.HostStatus != api.HOST_OFFLINE {
|
||||
_, err := self.SaveUpdates(func() error {
|
||||
self.HostStatus = api.HOST_OFFLINE
|
||||
@@ -3978,9 +3999,6 @@ func (self *SHost) PerformOffline(ctx context.Context, userCred mcclient.TokenCr
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if hostHealthChecker != nil {
|
||||
hostHealthChecker.UnwatchHost(context.Background(), self.Id)
|
||||
}
|
||||
db.OpsLog.LogEvent(self, db.ACT_OFFLINE, input.Reason, userCred)
|
||||
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_OFFLINE, input, userCred, true)
|
||||
ndata := jsonutils.Marshal(self).(*jsonutils.JSONDict)
|
||||
@@ -4015,7 +4033,7 @@ func (self *SHost) PerformOnline(ctx context.Context, userCred mcclient.TokenCre
|
||||
return nil, err
|
||||
}
|
||||
if hostHealthChecker != nil {
|
||||
hostHealthChecker.WatchHost(context.Background(), self.Id)
|
||||
hostHealthChecker.WatchHost(context.Background(), self.GetHostnameByName())
|
||||
}
|
||||
db.OpsLog.LogEvent(self, db.ACT_ONLINE, "", userCred)
|
||||
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_ONLINE, data, userCred, true)
|
||||
@@ -4033,26 +4051,29 @@ func (self *SHost) AllowPerformAutoMigrateOnHostDown(ctx context.Context,
|
||||
}
|
||||
|
||||
func (self *SHost) PerformAutoMigrateOnHostDown(
|
||||
ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject,
|
||||
ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.HostAutoMigrateInput,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
val, _ := data.GetString("auto_migrate_on_host_down")
|
||||
if input.AutoMigrateOnHostShutdown == "enable" &&
|
||||
input.AutoMigrateOnHostDown != "enable" {
|
||||
return nil, httperrors.NewBadRequestError("must enable auto_migrate_on_host_down at same time")
|
||||
}
|
||||
|
||||
var meta map[string]interface{}
|
||||
if val == "enable" {
|
||||
meta = map[string]interface{}{
|
||||
"__auto_migrate_on_host_down": "enable",
|
||||
"__on_host_down": "shutdown-servers",
|
||||
}
|
||||
var meta = make(map[string]interface{})
|
||||
if input.AutoMigrateOnHostShutdown == "enable" {
|
||||
meta[api.HOSTMETA_AUTO_MIGRATE_ON_HOST_SHUTDOWN] = "enable"
|
||||
} else if input.AutoMigrateOnHostShutdown == "disable" {
|
||||
meta[api.HOSTMETA_AUTO_MIGRATE_ON_HOST_SHUTDOWN] = "disable"
|
||||
}
|
||||
|
||||
if input.AutoMigrateOnHostDown == "enable" {
|
||||
meta[api.HOSTMETA_AUTO_MIGRATE_ON_HOST_DOWN] = "enable"
|
||||
_, err := self.Request(ctx, userCred, "POST", "/hosts/shutdown-servers-on-host-down",
|
||||
mcclient.GetTokenHeaders(userCred), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
meta = map[string]interface{}{
|
||||
"__auto_migrate_on_host_down": "disable",
|
||||
"__on_host_down": "",
|
||||
}
|
||||
} else if input.AutoMigrateOnHostDown == "disable" {
|
||||
meta[api.HOSTMETA_AUTO_MIGRATE_ON_HOST_DOWN] = "disable"
|
||||
}
|
||||
|
||||
return nil, self.SetAllMetadata(ctx, meta, userCred)
|
||||
@@ -4076,6 +4097,9 @@ func (self *SHost) AllowPerformPing(ctx context.Context,
|
||||
}
|
||||
|
||||
func (self *SHost) PerformPing(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
if self.HostType == api.HOST_TYPE_BAREMETAL {
|
||||
return nil, httperrors.NewNotSupportedError("ping host type %s not support", self.HostType)
|
||||
}
|
||||
if self.HostStatus != api.HOST_ONLINE {
|
||||
self.PerformOnline(ctx, userCred, query, data)
|
||||
} else {
|
||||
@@ -5603,8 +5627,74 @@ func (host *SHost) PerformHostMaintenance(ctx context.Context, userCred mcclient
|
||||
return nil, host.StartMaintainTask(ctx, userCred, kwargs)
|
||||
}
|
||||
|
||||
func (host *SHost) autoMigrateOnHostShutdown(ctx context.Context) bool {
|
||||
return host.GetMetadata(api.HOSTMETA_AUTO_MIGRATE_ON_HOST_SHUTDOWN, nil) == "enable"
|
||||
}
|
||||
|
||||
func (host *SHost) RemoteHealthStatus(ctx context.Context) string {
|
||||
var status = api.HOST_HEALTH_STATUS_UNKNOWN
|
||||
userCred := auth.AdminCredential()
|
||||
res, err := host.Request(
|
||||
ctx, userCred, "GET", "/hosts/health-status",
|
||||
mcclient.GetTokenHeaders(userCred), nil,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("failed get remote health status %s", err)
|
||||
} else {
|
||||
status, _ = res.GetString("status")
|
||||
}
|
||||
|
||||
log.Infof("remote health status %s", status)
|
||||
return status
|
||||
}
|
||||
|
||||
func (host *SHost) GetHostnameByName() string {
|
||||
hostname := host.Name
|
||||
accessIp := strings.Replace(host.AccessIp, ".", "-", -1)
|
||||
if strings.HasSuffix(host.Name, "-"+accessIp) {
|
||||
hostname = hostname[0 : len(hostname)-len(accessIp)-1]
|
||||
}
|
||||
return hostname
|
||||
}
|
||||
|
||||
func (host *SHost) OnHostDown(ctx context.Context, userCred mcclient.TokenCredential) {
|
||||
log.Errorf("watched host down %s", host.Id)
|
||||
log.Errorf("watched host down %s, status %s", host.Name, host.HostStatus)
|
||||
hostHealthChecker.UnwatchHost(ctx, host.GetHostnameByName())
|
||||
|
||||
if host.HostStatus == api.HOST_OFFLINE && !host.EnableHealthCheck &&
|
||||
!host.autoMigrateOnHostShutdown(ctx) {
|
||||
// hostagent requested offline, and not enable auto migrate on host shutdown
|
||||
log.Infof("host not need auto migrate on host shutdown")
|
||||
return
|
||||
}
|
||||
|
||||
hostname := host.Name
|
||||
if host.HostStatus == api.HOST_OFFLINE {
|
||||
// host has been marked offline, check host status in k8s
|
||||
coreCli, err := tokens.GetCoreClient()
|
||||
if err != nil {
|
||||
log.Errorf("failed get k8s client %s", err)
|
||||
return
|
||||
}
|
||||
hostname = host.GetHostnameByName()
|
||||
|
||||
node, err := coreCli.Nodes().Get(context.TODO(), hostname, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
log.Errorf("failed get node %s info %s", hostname, err)
|
||||
return
|
||||
}
|
||||
|
||||
// check node status is ready
|
||||
if length := len(node.Status.Conditions); length > 0 {
|
||||
if node.Status.Conditions[length-1].Type == v1.NodeReady &&
|
||||
node.Status.Conditions[length-1].Status == v1.ConditionTrue {
|
||||
log.Infof("node %s status ready, no need entry rescue", hostname)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log.Errorf("host %s down, try rescue guests", hostname)
|
||||
db.OpsLog.LogEvent(host, db.ACT_HOST_DOWN, "", userCred)
|
||||
if _, err := host.SaveCleanUpdates(func() error {
|
||||
host.EnableHealthCheck = false
|
||||
@@ -5666,7 +5756,7 @@ func (host *SHost) switchWithBackup(ctx context.Context, userCred mcclient.Token
|
||||
}
|
||||
|
||||
func (host *SHost) migrateOnHostDown(ctx context.Context, userCred mcclient.TokenCredential) {
|
||||
if host.GetMetadata("__auto_migrate_on_host_down", nil) == "enable" {
|
||||
if host.GetMetadata(api.HOSTMETA_AUTO_MIGRATE_ON_HOST_DOWN, nil) == "enable" {
|
||||
if err := host.MigrateSharedStorageServers(ctx, userCred); err != nil {
|
||||
db.OpsLog.LogEvent(host, db.ACT_HOST_DOWN, fmt.Sprintf("migrate servers failed %s", err), userCred)
|
||||
}
|
||||
@@ -5682,6 +5772,11 @@ func (host *SHost) MigrateSharedStorageServers(ctx context.Context, userCred mcc
|
||||
hostGuests := []*api.GuestBatchMigrateParams{}
|
||||
|
||||
for i := 0; i < len(guests); i++ {
|
||||
if guests[i].isNotRunningStatus(guests[i].Status) {
|
||||
// skip not running guests
|
||||
continue
|
||||
}
|
||||
|
||||
lockman.LockObject(ctx, &guests[i])
|
||||
defer lockman.ReleaseObject(ctx, &guests[i])
|
||||
_, err := guests[i].validateForBatchMigrate(ctx, true)
|
||||
@@ -6185,3 +6280,7 @@ func (host *SHost) IsAssignable(userCred mcclient.TokenCredential) error {
|
||||
func (self *SHost) PerformProbeIsolatedDevices(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
return self.GetHostDriver().RequestProbeIsolatedDevices(ctx, userCred, self, data)
|
||||
}
|
||||
|
||||
func (h *SHost) GetDetailsAppOptions(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
return h.Request(ctx, userCred, httputils.GET, "/app-options", nil, nil)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user