mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-20 08:03:53 +08:00
Compare commits
182 Commits
4abe94ca0b
...
v4.0.1-rc.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aed4db1454 | ||
|
|
5ba5d78344 | ||
|
|
d4840e0293 | ||
|
|
dd72ff2c4b | ||
|
|
84b0f1075a | ||
|
|
66587b4e52 | ||
|
|
206a4b5b19 | ||
|
|
90f479bafc | ||
|
|
1df9c11501 | ||
|
|
79561cd8ef | ||
|
|
435344ee1d | ||
|
|
15d079f966 | ||
|
|
90aef7ef0c | ||
|
|
390feec8ec | ||
|
|
911694c9fe | ||
|
|
73199002c3 | ||
|
|
0dc21f1b69 | ||
|
|
f593f7f660 | ||
|
|
046a6ac6cb | ||
|
|
7733907f9b | ||
|
|
b43953fc29 | ||
|
|
5f708fe816 | ||
|
|
69056db01a | ||
|
|
d48bab9ddd | ||
|
|
d10a322aec | ||
|
|
f694fead2e | ||
|
|
d4b04f3f2e | ||
|
|
6d633b5647 | ||
|
|
b7870e0453 | ||
|
|
4eb90fc442 | ||
|
|
35093fb7a7 | ||
|
|
9a3871014e | ||
|
|
b4e3d17178 | ||
|
|
4fa4cadb69 | ||
|
|
d0ec6885d6 | ||
|
|
634bdf7b90 | ||
|
|
117efad40d | ||
|
|
35aaafc09f | ||
|
|
421a3e9e87 | ||
|
|
fbefeae06f | ||
|
|
ef04ac2dac | ||
|
|
52d54cfc00 | ||
|
|
33936c937c | ||
|
|
3b2632fb26 | ||
|
|
412413c2f5 | ||
|
|
0970725598 | ||
|
|
1012991176 | ||
|
|
120725c311 | ||
|
|
ea88b81f3f | ||
|
|
c26ad31c8d | ||
|
|
4b0f3b4dd1 | ||
|
|
5a3bc2acb6 | ||
|
|
4080c2ddfb | ||
|
|
10a2c41d37 | ||
|
|
a196b19b0c | ||
|
|
50519e9099 | ||
|
|
44c487eeb1 | ||
|
|
1a7327c244 | ||
|
|
f5839b560e | ||
|
|
3e0231ae31 | ||
|
|
003de57c91 | ||
|
|
ddb64eaf2e | ||
|
|
8248bcd67e | ||
|
|
39a3918bb8 | ||
|
|
47d9f2f434 | ||
|
|
5bdf4d1d30 | ||
|
|
3e5e6e175c | ||
|
|
42e58b4996 | ||
|
|
a071cd2287 | ||
|
|
66748dbfcd | ||
|
|
d27c9be330 | ||
|
|
ea8f6c8221 | ||
|
|
c6f84dfa94 | ||
|
|
382c2bc6cd | ||
|
|
598f68a7e9 | ||
|
|
967d52f874 | ||
|
|
d1dcfc9ed3 | ||
|
|
ebd7298d0d | ||
|
|
992c5f498e | ||
|
|
570b371290 | ||
|
|
0b6a23e2fb | ||
|
|
da501a34d8 | ||
|
|
34fd2c5ca4 | ||
|
|
afe4afe095 | ||
|
|
9121720e21 | ||
|
|
b527b1ad6b | ||
|
|
bdcbc15cf5 | ||
|
|
397f165d37 | ||
|
|
f29a1d8567 | ||
|
|
47a9fa3505 | ||
|
|
7df2a43d22 | ||
|
|
826f4df8f7 | ||
|
|
7cee63907b | ||
|
|
0e50049ab1 | ||
|
|
975f4ed864 | ||
|
|
5643619a7c | ||
|
|
3e35ea56df | ||
|
|
1ba251f053 | ||
|
|
25d1b699c9 | ||
|
|
19143c134a | ||
|
|
27a8e098d6 | ||
|
|
cb12c9fe1c | ||
|
|
fc2603ce4d | ||
|
|
d9c5d5657e | ||
|
|
b6b5c6041b | ||
|
|
c1345560bb | ||
|
|
8448395003 | ||
|
|
5058f02538 | ||
|
|
31b766a7d6 | ||
|
|
650acf4ea9 | ||
|
|
1322a21445 | ||
|
|
fb26af0566 | ||
|
|
af0559ac35 | ||
|
|
72f68dd541 | ||
|
|
ae09aa3c82 | ||
|
|
b677cef407 | ||
|
|
9ae9879c56 | ||
|
|
2f8c719f03 | ||
|
|
712059cedb | ||
|
|
4bbc651732 | ||
|
|
24e525926b | ||
|
|
119140fe93 | ||
|
|
1b45c3d174 | ||
|
|
9675f1d4e4 | ||
|
|
e7e13552d9 | ||
|
|
91ad8f038e | ||
|
|
c5e70ed1aa | ||
|
|
cdd46c490d | ||
|
|
1d69a15372 | ||
|
|
5237beb197 | ||
|
|
ffdf7a3a6e | ||
|
|
c835c87afc | ||
|
|
58e2ea41af | ||
|
|
addbe7f9ea | ||
|
|
618722bc16 | ||
|
|
fd0c96e6f9 | ||
|
|
5a17a9e37b | ||
|
|
44ed13473a | ||
|
|
d8b00188a0 | ||
|
|
0b61ca0432 | ||
|
|
b9a9151555 | ||
|
|
17db7be134 | ||
|
|
892431d5b9 | ||
|
|
3d36c293e5 | ||
|
|
3ff50f0d11 | ||
|
|
6144325daf | ||
|
|
bf3b83870c | ||
|
|
62b7eea828 | ||
|
|
4e07811e2f | ||
|
|
f819e021b3 | ||
|
|
3224eac821 | ||
|
|
a1fce125da | ||
|
|
aa0a6b58d3 | ||
|
|
0c9a44e279 | ||
|
|
4dd92825a8 | ||
|
|
30a319fe5e | ||
|
|
faf35a6879 | ||
|
|
4520b54a5b | ||
|
|
fa53aea075 | ||
|
|
36b5532b04 | ||
|
|
01ab43941e | ||
|
|
249569be9f | ||
|
|
db0b275772 | ||
|
|
e6bb86c934 | ||
|
|
c53f707089 | ||
|
|
ef36176130 | ||
|
|
edd11ea1cd | ||
|
|
4ad7d635bc | ||
|
|
18604b46b1 | ||
|
|
4609c543c9 | ||
|
|
779559dbdc | ||
|
|
27c6c82b82 | ||
|
|
fa99905bf6 | ||
|
|
608e4edb4e | ||
|
|
43c646b537 | ||
|
|
ad798d7bbe | ||
|
|
238458066a | ||
|
|
90a8b10401 | ||
|
|
46195f72ee | ||
|
|
05829a225a | ||
|
|
f0858ce4d2 | ||
|
|
cc3477415d |
9
Makefile
9
Makefile
@@ -84,9 +84,6 @@ vet:
|
||||
# cmd/esxi-agent: prepare_dir
|
||||
# CGO_ENABLED=0 $(GO_BUILD) -o $(BIN_DIR)/$(shell basename $@) $(REPO_PREFIX)/$@
|
||||
|
||||
cmd/host: prepare_dir
|
||||
CGO_ENABLED=1 $(GO_BUILD) -o $(BIN_DIR)/$(shell basename $@) $(REPO_PREFIX)/$@
|
||||
|
||||
cmd/%: prepare_dir
|
||||
CGO_ENABLED=0 $(GO_BUILD) -o $(BIN_DIR)/$(shell basename $@) $(REPO_PREFIX)/$@
|
||||
|
||||
@@ -277,12 +274,12 @@ dep:
|
||||
@echo "$$depDeprecated"
|
||||
@$(MAKE) mod
|
||||
|
||||
RELEASE_BRANCH:=master
|
||||
RELEASE_BRANCH:=release/4.0
|
||||
GOPROXY ?= direct
|
||||
|
||||
mod:
|
||||
GOPROXY=$(GOPROXY) GONOSUMDB=yunion.io/x go get -d yunion.io/x/cloudmux@$(RELEASE_BRANCH)
|
||||
GOPROXY=$(GOPROXY) GONOSUMDB=yunion.io/x go get -d $(patsubst %,%@master,$(shell GO111MODULE=on go mod edit -print | sed -n -e 's|.*\(yunion.io/x/[a-z].*\) v.*|\1|p' | grep -v '/cloudmux$$'))
|
||||
GOPROXY=$(GOPROXY) GONOSUMDB=yunion.io/x go get yunion.io/x/cloudmux@$(RELEASE_BRANCH)
|
||||
GOPROXY=$(GOPROXY) GONOSUMDB=yunion.io/x go get $(patsubst %,%@master,$(shell GO111MODULE=on go mod edit -print | sed -n -e 's|.*\(yunion.io/x/[a-z].*\) v.*|\1|p' | grep -v '/cloudmux$$'))
|
||||
GOPROXY=$(GOPROXY) GONOSUMDB=yunion.io/x go mod tidy
|
||||
GOPROXY=$(GOPROXY) GONOSUMDB=yunion.io/x go mod vendor -v
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/host-deployer-base:1.4.9
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/host-deployer-base:1.4.10
|
||||
|
||||
MAINTAINER "Yaoqi Wan wanyaoqi@yunionyun.com"
|
||||
|
||||
|
||||
31
cmd/climc/shell/compute/ai_gateways.go
Normal file
31
cmd/climc/shell/compute/ai_gateways.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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 compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/cmd/climc/shell"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmd := shell.NewResourceCmd(&modules.AiGateways).WithKeyword("ai-gateway")
|
||||
cmd.List(&compute.AiGatewayListOptions{})
|
||||
cmd.Delete(&options.BaseIdOptions{})
|
||||
cmd.Create(&compute.AiGatewayCreateOptions{})
|
||||
cmd.Perform("syncstatus", &options.BaseIdOptions{})
|
||||
cmd.Perform("change-config", &compute.AiGatewayChangeConfigOptions{})
|
||||
}
|
||||
@@ -19,178 +19,71 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/multicloud/objectstore"
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/util/fileutils"
|
||||
"yunion.io/x/pkg/util/printutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/cmd/climc/shell"
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
computeoptions "yunion.io/x/onecloud/pkg/mcclient/options/compute"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type BucketListOptions struct {
|
||||
options.BaseListOptions
|
||||
DistinctField string `help:"query specified distinct field"`
|
||||
}
|
||||
R(&BucketListOptions{}, "bucket-list", "List all buckets", func(s *mcclient.ClientSession, args *BucketListOptions) error {
|
||||
params, err := options.ListStructToParams(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(args.DistinctField) > 0 {
|
||||
params.Add(jsonutils.NewString(args.DistinctField), "extra_field")
|
||||
result, err := modules.Buckets.Get(s, "distinct-field", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(result)
|
||||
return nil
|
||||
}
|
||||
result, err := modules.Buckets.List(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printList(result, modules.Buckets.GetColumns(s))
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketIdOptions struct {
|
||||
ID string `help:"ID or name of bucket"`
|
||||
}
|
||||
R(&BucketIdOptions{}, "bucket-show", "Id details of bucket", func(s *mcclient.ClientSession, args *BucketIdOptions) error {
|
||||
result, err := modules.Buckets.Get(s, args.ID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&BucketIdOptions{}, "bucket-syncstatus", "Sync bucket statust", func(s *mcclient.ClientSession, args *BucketIdOptions) error {
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "syncstatus", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketUpdateOptions struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
Name string `help:"new name of bucket" json:"name"`
|
||||
Desc string `help:"Description of bucket" json:"description" token:"desc"`
|
||||
}
|
||||
R(&BucketUpdateOptions{}, "bucket-update", "update bucket", func(s *mcclient.ClientSession, args *BucketUpdateOptions) error {
|
||||
params := jsonutils.Marshal(args)
|
||||
result, err := modules.Buckets.Update(s, args.ID, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketDeleteOptions struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
}
|
||||
R(&BucketDeleteOptions{}, "bucket-delete", "delete bucket", func(s *mcclient.ClientSession, args *BucketDeleteOptions) error {
|
||||
result, err := modules.Buckets.Delete(s, args.ID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketCreateOptions struct {
|
||||
NAME string `help:"name of bucket" json:"name"`
|
||||
CLOUDREGION string `help:"location of bucket" json:"cloudregion"`
|
||||
MANAGER string `help:"cloud provider" json:"manager"`
|
||||
|
||||
StorageClass string `help:"bucket storage class"`
|
||||
Acl string `help:"bucket ACL"`
|
||||
}
|
||||
R(&BucketCreateOptions{}, "bucket-create", "Create a bucket", func(s *mcclient.ClientSession, args *BucketCreateOptions) error {
|
||||
params, err := options.StructToParams(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.Buckets.Create(s, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketListObjectsOptions struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
Prefix string `help:"List objects with prefix"`
|
||||
Recursive bool `help:"List objects recursively"`
|
||||
Limit int `help:"maximal items per request"`
|
||||
PagingMarker string `help:"paging marker"`
|
||||
}
|
||||
R(&BucketListObjectsOptions{}, "bucket-object-list", "List objects in a bucket", func(s *mcclient.ClientSession, args *BucketListObjectsOptions) error {
|
||||
params, err := options.StructToParams(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.Buckets.GetSpecific(s, args.ID, "objects", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := shell.NewResourceCmd(&modules.Buckets)
|
||||
cmd.List(&computeoptions.BucketListOptions{})
|
||||
cmd.GetProperty(&computeoptions.BucketGetPropertyOptions{})
|
||||
cmd.Show(&computeoptions.BucketIdOptions{})
|
||||
cmd.Perform("syncstatus", &computeoptions.BucketIdOptions{})
|
||||
cmd.Update(&computeoptions.BucketUpdateOptions{})
|
||||
cmd.Delete(&computeoptions.BucketIdOptions{})
|
||||
cmd.Create(&computeoptions.BucketCreateOptions{})
|
||||
cmd.GetWithCustomOptionShow("objects", func(data jsonutils.JSONObject, args shell.IGetOpt) {
|
||||
listResult := printutils.ListResult{}
|
||||
err = result.Unmarshal(&listResult)
|
||||
err := data.Unmarshal(&listResult)
|
||||
if err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
printList(&listResult, []string{})
|
||||
return nil
|
||||
})
|
||||
}, &computeoptions.BucketListObjectsOptions{})
|
||||
cmd.Perform("delete", &computeoptions.BucketDeleteObjectsOptions{})
|
||||
cmd.Perform("makedir", &computeoptions.BucketMakeDirOptions{})
|
||||
cmd.Perform("temp-url", &computeoptions.BucketPresignObjectsOptions{})
|
||||
cmd.Perform("acl", &computeoptions.BucketSetAclOptions{})
|
||||
cmd.GetWithCustomOptionShow("acl", func(data jsonutils.JSONObject, args shell.IGetOpt) {
|
||||
printObject(data)
|
||||
}, &computeoptions.BucketAclOptions{})
|
||||
cmd.Perform("sync", &computeoptions.BucketSyncOptions{})
|
||||
cmd.Perform("limit", &computeoptions.BucketLimitOptions{})
|
||||
cmd.GetWithCustomOptionShow("access-info", func(data jsonutils.JSONObject, args shell.IGetOpt) {
|
||||
printObject(data)
|
||||
}, &computeoptions.BucketAccessInfoOptions{})
|
||||
cmd.Perform("metadata", &computeoptions.BucketSetMetadataOptions{})
|
||||
cmd.Perform("set-website", &computeoptions.BucketSetWebsiteOption{})
|
||||
cmd.GetWithCustomOptionShow("website", func(data jsonutils.JSONObject, args shell.IGetOpt) {
|
||||
printObject(data)
|
||||
}, &computeoptions.BucketGetWebsiteConfOption{})
|
||||
cmd.Perform("delete-website", &computeoptions.BucketDeleteWebsiteConfOption{})
|
||||
cmd.Perform("set-cors", &computeoptions.BucketSetCorsOption{})
|
||||
cmd.GetWithCustomOptionShow("cors", func(data jsonutils.JSONObject, args shell.IGetOpt) {
|
||||
printObject(data)
|
||||
}, &computeoptions.BucketGetCorsOption{})
|
||||
cmd.Perform("delete-cors", &computeoptions.BucketDeleteCorsOption{})
|
||||
cmd.Perform("set-referer", &computeoptions.BucketSetRefererOption{})
|
||||
cmd.GetWithCustomOptionShow("referer", func(data jsonutils.JSONObject, args shell.IGetOpt) {
|
||||
printObject(data)
|
||||
}, &computeoptions.BucketGetRefererOption{})
|
||||
cmd.GetWithCustomOptionShow("cdn-domain", func(data jsonutils.JSONObject, args shell.IGetOpt) {
|
||||
printObject(data)
|
||||
}, &computeoptions.BucketGetCdnDomainOption{})
|
||||
cmd.GetWithCustomOptionShow("policy", func(data jsonutils.JSONObject, args shell.IGetOpt) {
|
||||
printObject(data)
|
||||
}, &computeoptions.BucketGetPolicyOption{})
|
||||
cmd.Perform("set-policy", &computeoptions.BucketSetPolicyOption{})
|
||||
cmd.Perform("delete-policy", &computeoptions.BucketDeletePolicyOption{})
|
||||
|
||||
type BucketDeleteObjectsOptions struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
KEYS []string `help:"List of objects to delete"`
|
||||
}
|
||||
R(&BucketDeleteObjectsOptions{}, "bucket-object-delete", "Delete objects in a bucket", func(s *mcclient.ClientSession, args *BucketDeleteObjectsOptions) error {
|
||||
params := jsonutils.Marshal(args)
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "delete", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketMakeDirOptions struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
KEY string `help:"DIR key to create"`
|
||||
}
|
||||
R(&BucketMakeDirOptions{}, "bucket-mkdir", "Mkdir in a bucket", func(s *mcclient.ClientSession, args *BucketMakeDirOptions) error {
|
||||
params := jsonutils.Marshal(args)
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "makedir", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketUploadObjectsOptions struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
KEY string `help:"Key of object to upload"`
|
||||
Path string `help:"Path to file to upload" required:"true"`
|
||||
|
||||
ContentLength int64 `help:"Content lenght (bytes)" default:"-1"`
|
||||
StorageClass string `help:"storage CLass"`
|
||||
Acl string `help:"object acl." choices:"private|public-read|public-read-write"`
|
||||
|
||||
objectstore.ObjectHeaderOptions
|
||||
}
|
||||
R(&BucketUploadObjectsOptions{}, "bucket-object-upload", "Upload an object into a bucket", func(s *mcclient.ClientSession, args *BucketUploadObjectsOptions) error {
|
||||
R(&computeoptions.BucketUploadObjectsOptions{}, "bucket-object-upload", "Upload an object into a bucket", func(s *mcclient.ClientSession, args *computeoptions.BucketUploadObjectsOptions) error {
|
||||
var body io.Reader
|
||||
if len(args.Path) > 0 {
|
||||
file, err := os.Open(args.Path)
|
||||
@@ -223,332 +116,36 @@ func init() {
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketPresignObjectsOptions struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
KEY string `help:"Key of object to upload"`
|
||||
Method string `help:"Request method" choices:"GET|PUT|DELETE"`
|
||||
ExpireSeconds int `help:"expire in seconds" default:"60"`
|
||||
}
|
||||
R(&BucketPresignObjectsOptions{}, "bucket-object-tempurl", "Get temporal URL for an object in a bucket", func(s *mcclient.ClientSession, args *BucketPresignObjectsOptions) error {
|
||||
params, err := options.StructToParams(args)
|
||||
R(&computeoptions.BucketPerfMonOptions{}, "bucket-perf-mon", "Bucket performance monitor", func(s *mcclient.ClientSession, args *computeoptions.BucketPerfMonOptions) error {
|
||||
result, err := modules.Buckets.Get(s, args.ID, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "temp-url", params)
|
||||
bucketDetails := compute.BucketDetails{}
|
||||
err = result.Unmarshal(&bucketDetails)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketSetAclOptions struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
ACL string `help:"ACL to set" choices:"default|private|public-read|public-read-write" json:"acl"`
|
||||
Key []string `help:"Optional object key" json:"key"`
|
||||
}
|
||||
R(&BucketSetAclOptions{}, "bucket-set-acl", "Set ACL of bucket or object", func(s *mcclient.ClientSession, args *BucketSetAclOptions) error {
|
||||
params := jsonutils.Marshal(args)
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "acl", params)
|
||||
bucket, err := modules.GetIBucket(s.GetContext(), s, &bucketDetails)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketAclOptions struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
Key string `help:"Optional object key"`
|
||||
}
|
||||
R(&BucketAclOptions{}, "bucket-acl", "Get ACL of bucket or object", func(s *mcclient.ClientSession, args *BucketAclOptions) error {
|
||||
params, err := options.StructToParams(args)
|
||||
payload, err := fileutils.GetSizeBytes(args.Payload, 1024)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.Buckets.GetSpecific(s, args.ID, "acl", params)
|
||||
|
||||
stats, err := modules.ProbeBucketStats(s.GetContext(), bucket, "test", int64(payload))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketSyncOptions struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
StatsOnly bool `help:"sync statistics only"`
|
||||
}
|
||||
R(&BucketSyncOptions{}, "bucket-sync", "Sync bucket", func(s *mcclient.ClientSession, args *BucketSyncOptions) error {
|
||||
params, err := options.StructToParams(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "sync", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
fmt.Printf("Upload delay %f ms throughput %f MB/s\n", stats.UploadDelayMs(), stats.UploadThroughputMbps(payload/1024/1024))
|
||||
fmt.Printf("Download delay %f ms throughput %f MB/s\n", stats.DownloadDelayMs(), stats.DownloadThroughputMbps(payload/1024/1024))
|
||||
fmt.Printf("Delete delay %f ms\n", stats.DeleteDelayMs())
|
||||
|
||||
type BucketLimitOptions struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
SizeBytes int64 `help:"size limit in bytes"`
|
||||
ObjectCount int64 `help:"object count limit"`
|
||||
}
|
||||
R(&BucketLimitOptions{}, "bucket-limit", "Set limit of bucket", func(s *mcclient.ClientSession, args *BucketLimitOptions) error {
|
||||
limit := jsonutils.Marshal(args)
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("limit", limit)
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "limit", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketAccessInfoOptions struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
}
|
||||
R(&BucketAccessInfoOptions{}, "bucket-access-info", "Show backend access info of a bucket", func(s *mcclient.ClientSession, args *BucketAccessInfoOptions) error {
|
||||
result, err := modules.Buckets.GetSpecific(s, args.ID, "access-info", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketSetMetadataOptions struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
|
||||
Key []string `help:"Optional object key" json:"key"`
|
||||
|
||||
objectstore.ObjectHeaderOptions
|
||||
}
|
||||
R(&BucketSetMetadataOptions{}, "bucket-set-metadata", "Set metadata of object", func(s *mcclient.ClientSession, args *BucketSetMetadataOptions) error {
|
||||
input := api.BucketMetadataInput{}
|
||||
input.Key = args.Key
|
||||
input.Metadata = args.ObjectHeaderOptions.Options2Header()
|
||||
err := input.Validate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "metadata", jsonutils.Marshal(input))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketSetWebsiteOption struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
// 主页
|
||||
Index string `help:"main page"`
|
||||
// 错误时返回的文档
|
||||
ErrorDocument string `help:"error return"`
|
||||
// http或https
|
||||
Protocol string `help:"force https" choices:"http|https"`
|
||||
}
|
||||
R(&BucketSetWebsiteOption{}, "bucket-set-website", "Set bucket website", func(s *mcclient.ClientSession, args *BucketSetWebsiteOption) error {
|
||||
conf := api.BucketWebsiteConf{
|
||||
Index: args.Index,
|
||||
ErrorDocument: args.ErrorDocument,
|
||||
Protocol: args.Protocol,
|
||||
}
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "set-website", jsonutils.Marshal(conf))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketGetWebsiteConfOption struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
}
|
||||
R(&BucketGetWebsiteConfOption{}, "bucket-get-website", "Get bucket website", func(s *mcclient.ClientSession, args *BucketGetWebsiteConfOption) error {
|
||||
result, err := modules.Buckets.GetSpecific(s, args.ID, "website", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketDeleteWebsiteConfOption struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
}
|
||||
R(&BucketDeleteWebsiteConfOption{}, "bucket-delete-website", "Delete bucket website", func(s *mcclient.ClientSession, args *BucketDeleteWebsiteConfOption) error {
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "delete-website", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketSetCorsOption struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
AllowedMethods []string `help:"allowed http method" choices:"PUT|GET|POST|DELETE|HEAD"`
|
||||
// 允许的源站,可以设为*
|
||||
AllowedOrigins []string
|
||||
AllowedHeaders []string
|
||||
MaxAgeSeconds int
|
||||
ExposeHeaders []string
|
||||
RuleId string
|
||||
}
|
||||
R(&BucketSetCorsOption{}, "bucket-set-cors", "Set bucket cors", func(s *mcclient.ClientSession, args *BucketSetCorsOption) error {
|
||||
|
||||
rule := api.BucketCORSRule{
|
||||
AllowedOrigins: args.AllowedOrigins,
|
||||
AllowedMethods: args.AllowedMethods,
|
||||
AllowedHeaders: args.AllowedHeaders,
|
||||
MaxAgeSeconds: args.MaxAgeSeconds,
|
||||
ExposeHeaders: args.ExposeHeaders,
|
||||
Id: args.RuleId,
|
||||
}
|
||||
rules := api.BucketCORSRules{Data: []api.BucketCORSRule{rule}}
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "set-cors", jsonutils.Marshal(rules))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketGetCorsOption struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
}
|
||||
R(&BucketGetCorsOption{}, "bucket-get-cors", "Get bucket cors", func(s *mcclient.ClientSession, args *BucketGetCorsOption) error {
|
||||
result, err := modules.Buckets.GetSpecific(s, args.ID, "cors", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketDeleteCorsOption struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
Id []string `"help:Id of rules to delete"`
|
||||
}
|
||||
R(&BucketDeleteCorsOption{}, "bucket-delete-cors", "Delete bucket cors", func(s *mcclient.ClientSession, args *BucketDeleteCorsOption) error {
|
||||
input := api.BucketCORSRuleDeleteInput{}
|
||||
input.Id = args.Id
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "delete-cors", jsonutils.Marshal(input))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketSetRefererOption struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
// 域名列表
|
||||
DomainList []string
|
||||
// 是否允许空referer 访问
|
||||
AllowEmptyRefer bool `help:"all empty refer access"`
|
||||
Enabled bool
|
||||
RerererType string `help:"Referer type" choices:"Black-List|White-List"`
|
||||
}
|
||||
R(&BucketSetRefererOption{}, "bucket-set-referer", "Set bucket referer", func(s *mcclient.ClientSession, args *BucketSetRefererOption) error {
|
||||
conf := api.BucketRefererConf{
|
||||
Enabled: args.Enabled,
|
||||
AllowEmptyRefer: args.AllowEmptyRefer,
|
||||
RefererType: args.RerererType,
|
||||
DomainList: args.DomainList,
|
||||
}
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "set-referer", jsonutils.Marshal(conf))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketGetRefererOption struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
}
|
||||
R(&BucketGetRefererOption{}, "bucket-get-referer", "get bucket referer", func(s *mcclient.ClientSession, args *BucketGetRefererOption) error {
|
||||
result, err := modules.Buckets.GetSpecific(s, args.ID, "referer", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketGetCdnDomainOption struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
}
|
||||
R(&BucketGetRefererOption{}, "bucket-get-cdn-domain", "get bucket cdn domain", func(s *mcclient.ClientSession, args *BucketGetRefererOption) error {
|
||||
result, err := modules.Buckets.GetSpecific(s, args.ID, "cdn-domain", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketGetPolicyOption struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
}
|
||||
R(&BucketGetPolicyOption{}, "bucket-get-policy", "get bucket policy", func(s *mcclient.ClientSession, args *BucketGetPolicyOption) error {
|
||||
result, err := modules.Buckets.GetSpecific(s, args.ID, "policy", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketSetPolicyOption struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
// 格式主账号id:子账号id
|
||||
PrincipalId []string `help:"ext account id, accountId:subaccountId"`
|
||||
// Read|ReadWrite|FullControl
|
||||
CannedAction string `help:"authority action" choice:"Read|FullControl"`
|
||||
// Allow|Deny
|
||||
Effect string `help:"allow or deny" choice:"Allow|Deny"`
|
||||
// 被授权的资源地址
|
||||
ResourcePath []string
|
||||
// ip 条件
|
||||
IpEquals []string
|
||||
IpNotEquals []string
|
||||
}
|
||||
R(&BucketSetPolicyOption{}, "bucket-set-policy", "set bucket policy", func(s *mcclient.ClientSession, args *BucketSetPolicyOption) error {
|
||||
opts := api.BucketPolicyStatementInput{}
|
||||
opts.CannedAction = args.CannedAction
|
||||
opts.Effect = args.Effect
|
||||
opts.IpEquals = args.IpEquals
|
||||
opts.IpNotEquals = args.IpNotEquals
|
||||
opts.ResourcePath = args.ResourcePath
|
||||
opts.PrincipalId = args.PrincipalId
|
||||
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "set-policy", jsonutils.Marshal(opts))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
type BucketDeletePolicyOption struct {
|
||||
ID string `help:"ID or name of bucket" json:"-"`
|
||||
Id []string
|
||||
}
|
||||
R(&BucketDeletePolicyOption{}, "bucket-delete-policy", "delete bucket policy", func(s *mcclient.ClientSession, args *BucketDeletePolicyOption) error {
|
||||
input := api.BucketPolicyDeleteInput{}
|
||||
input.Id = args.Id
|
||||
result, err := modules.Buckets.PerformAction(s, args.ID, "delete-policy", jsonutils.Marshal(input))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -28,4 +28,8 @@ func init() {
|
||||
cmd.Update(&compute.CDNDomainUpdateOptions{})
|
||||
cmd.Delete(&options.BaseIdOptions{})
|
||||
cmd.Create(&compute.CDNDomainCreateOptions{})
|
||||
cmd.Perform("clear-cache", &compute.CDNClearCacheOptions{})
|
||||
cmd.Perform("change-config", &compute.CDNChangeConfigOptions{})
|
||||
cmd.Perform("delete-custom-hostname", &compute.CDNDeleteCustomHostnameOptions{})
|
||||
cmd.Get("custom-hostnames", &compute.CDNCustomHostnameOptions{})
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ func init() {
|
||||
cmd.Perform("rebuild", &compute_options.DiskRebuildOptions{})
|
||||
cmd.Perform("migrate", &compute_options.DiskMigrateOptions{})
|
||||
cmd.Perform("reset-template", &compute_options.DiskResetTemplateOptions{})
|
||||
cmd.Perform("change-billing-type", new(compute_options.DiskChangeBillingTypeOptions))
|
||||
|
||||
type DiskDetailOptions struct {
|
||||
ID string `help:"ID or Name of disk"`
|
||||
|
||||
31
cmd/climc/shell/compute/hostfiles.go
Normal file
31
cmd/climc/shell/compute/hostfiles.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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 compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/cmd/climc/shell"
|
||||
computemodules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmd := shell.NewResourceCmd(&computemodules.HostFiles)
|
||||
cmd.List(&compute.HostFileListOptions{})
|
||||
cmd.Create(&compute.HostFileCreateOptions{})
|
||||
cmd.Show(&compute.HostFileShowOptions{})
|
||||
cmd.Update(&compute.HostFileUpdateOptions{})
|
||||
cmd.Edit(&compute.HostFileEditOptions{})
|
||||
cmd.Delete(&compute.HostFileDeleteOptions{})
|
||||
}
|
||||
@@ -55,8 +55,8 @@ func init() {
|
||||
cmd.Perform("class-metadata", &options.ResourceMetadataOptions{})
|
||||
cmd.Perform("set-class-metadata", &options.ResourceMetadataOptions{})
|
||||
cmd.PerformClass("validate-ipmi", &compute.HostValidateIPMI{})
|
||||
cmd.Perform("set-commit-bound", &compute.HostSetCommitBoundOptions{})
|
||||
|
||||
cmd.BatchPerform("set-commit-bound", &compute.HostSetCommitBoundOptions{})
|
||||
cmd.BatchPerform("enable", &options.BaseIdsOptions{})
|
||||
cmd.BatchPerform("disable", &options.BaseIdsOptions{})
|
||||
cmd.BatchPerform("syncstatus", &options.BaseIdsOptions{})
|
||||
@@ -67,6 +67,7 @@ func init() {
|
||||
cmd.BatchPerform("unreserve-cpus", &options.BaseIdsOptions{})
|
||||
cmd.BatchPerform("auto-migrate-on-host-down", &compute.HostAutoMigrateOnHostDownOptions{})
|
||||
cmd.BatchPerform("restart-host-agent", &options.BaseIdsOptions{})
|
||||
cmd.BatchPerform("set-host-files", &compute.HostSetHostFilesOptions{})
|
||||
|
||||
cmd.Get("ipmi", &options.BaseIdOptions{})
|
||||
cmd.Get("vnc", &options.BaseIdOptions{})
|
||||
@@ -93,6 +94,9 @@ func init() {
|
||||
fmt.Println("error", err)
|
||||
}
|
||||
}, &options.BaseIdOptions{})
|
||||
cmd.GetWithCustomShow("host-files", func(data jsonutils.JSONObject) {
|
||||
printObject(data)
|
||||
}, &options.BaseIdOptions{})
|
||||
|
||||
R(&compute.HostShowOptions{}, "host-show", "Show details of a host", func(s *mcclient.ClientSession, args *compute.HostShowOptions) error {
|
||||
params, err := args.Params()
|
||||
@@ -259,6 +263,7 @@ func init() {
|
||||
INDEX int64 `help:"nic index"`
|
||||
Type string `help:"Nic type" choices:"admin|ipmi"`
|
||||
IpAddr string `help:"IP address"`
|
||||
Ip6Addr string `help:"IPv6 address"`
|
||||
Bridge string `help:"Bridge of hostwire"`
|
||||
Interface string `help:"Interface name, eg:eth0, en0"`
|
||||
}
|
||||
@@ -274,6 +279,9 @@ func init() {
|
||||
if len(args.IpAddr) > 0 {
|
||||
params.Add(jsonutils.NewString(args.IpAddr), "ip_addr")
|
||||
}
|
||||
if len(args.Ip6Addr) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Ip6Addr), "ip6_addr")
|
||||
}
|
||||
if len(args.Bridge) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Bridge), "bridge")
|
||||
}
|
||||
@@ -306,7 +314,8 @@ func init() {
|
||||
type HostEnableNetIfOptions struct {
|
||||
ID string `help:"ID or Name of host"`
|
||||
MAC string `help:"MAC of NIC to enable"`
|
||||
Ip string `help:"IP address"`
|
||||
Ip string `help:"IPv4 address"`
|
||||
Ip6 string `help:"IPv6 address"`
|
||||
Network string `help:"network to connect"`
|
||||
Reserved bool `help:"fetch IP from reserved pool"`
|
||||
}
|
||||
@@ -315,6 +324,11 @@ func init() {
|
||||
params.Add(jsonutils.NewString(args.MAC), "mac")
|
||||
if len(args.Ip) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Ip), "ip_addr")
|
||||
}
|
||||
if len(args.Ip6) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Ip6), "ip6_addr")
|
||||
}
|
||||
if len(args.Ip) > 0 || len(args.Ip6) > 0 {
|
||||
if args.Reserved {
|
||||
params.Add(jsonutils.JSONTrue, "reserve")
|
||||
}
|
||||
|
||||
31
cmd/climc/shell/compute/loadbalancer_health_check.go
Normal file
31
cmd/climc/shell/compute/loadbalancer_health_check.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// 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 compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/cmd/climc/shell"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
options "yunion.io/x/onecloud/pkg/mcclient/options/compute"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmd := shell.NewResourceCmd(&modules.LoadbalancerHealthChecks).WithKeyword("lb-health-check")
|
||||
cmd.List(&options.LoadbalancerHealthCheckListOptions{})
|
||||
cmd.Show(&options.LoadbalancerHealthCheckIdOptions{})
|
||||
cmd.Create(&options.LoadbalancerHealthCheckCreateOptions{})
|
||||
cmd.Delete(&options.LoadbalancerHealthCheckIdOptions{})
|
||||
cmd.Update(&options.LoadbalancerHealthCheckUpdateOptions{})
|
||||
cmd.Perform("syncstatus", &options.LoadbalancerHealthCheckIdOptions{})
|
||||
}
|
||||
@@ -234,7 +234,7 @@ func init() {
|
||||
|
||||
fmt.Println("[Slave Addresses]")
|
||||
for _, addr := range netIf.GetSlaveAddresses() {
|
||||
fmt.Printf("%s/%s\n", addr[0], addr[1])
|
||||
fmt.Printf("%s/%d\n", addr.Addr, addr.MaskLen)
|
||||
}
|
||||
fmt.Println("[Routes]")
|
||||
for _, r := range netIf.GetRouteSpecs() {
|
||||
|
||||
@@ -32,6 +32,7 @@ func init() {
|
||||
cmd.Perform("syncstatus", &options.SecgroupIdOptions{})
|
||||
cmd.Perform("private", &options.SecgroupIdOptions{})
|
||||
cmd.Perform("add-rule", &options.SecgroupsAddRuleOptions{})
|
||||
cmd.Perform("clone", &options.SecgroupCloneOptions{})
|
||||
cmd.Perform("change-owner", &options.SecgroupChangeOwnerOptions{})
|
||||
cmd.Perform("import-rules", &options.SecgroupImportRulesOptions{})
|
||||
cmd.PerformClass("clean", &options.SecgroupCleanOptions{})
|
||||
|
||||
@@ -165,8 +165,9 @@ func init() {
|
||||
})
|
||||
|
||||
type ServerAttachNetworkOptions struct {
|
||||
SERVER string `help:"ID or Name of server"`
|
||||
NETDESC []string `help:"Network description"`
|
||||
SERVER string `help:"ID or Name of server"`
|
||||
DisableSyncConfig bool `help:"Disable sync config"`
|
||||
NETDESC []string `help:"Network description"`
|
||||
}
|
||||
R(&ServerAttachNetworkOptions{}, "server-attach-network", "Attach a server to a virtual network", func(s *mcclient.ClientSession, args *ServerAttachNetworkOptions) error {
|
||||
input := compute.AttachNetworkInput{}
|
||||
@@ -177,6 +178,7 @@ func init() {
|
||||
}
|
||||
input.Nets = append(input.Nets, conf)
|
||||
}
|
||||
input.DisableSyncConfig = &args.DisableSyncConfig
|
||||
params := jsonutils.Marshal(input)
|
||||
srv, err := modules.Servers.PerformAction(s, args.SERVER, "attachnetwork", params)
|
||||
if err != nil {
|
||||
|
||||
@@ -129,7 +129,7 @@ func init() {
|
||||
cmd.BatchPerform("stop-rescue", &options.ServerStartOptions{})
|
||||
cmd.BatchPerform("sync-os-info", &options.ServerIdsOptions{})
|
||||
cmd.BatchPerform("set-root-disk-matcher", &options.ServerSetRootDiskMatcher{})
|
||||
|
||||
cmd.Perform("disable-auto-merge-snapshot", &options.ServerDisableAutoMergeSnapshot{})
|
||||
cmd.Get("vnc", new(options.ServerVncOptions))
|
||||
cmd.Get("desc", new(options.ServerIdOptions))
|
||||
cmd.Get("status", new(options.ServerIdOptions))
|
||||
|
||||
@@ -28,5 +28,7 @@ func init() {
|
||||
cmd.Create(&compute.SnapshotPolicyCreateOptions{})
|
||||
cmd.Perform("bind-disks", &compute.SnapshotPolicyDisksOptions{})
|
||||
cmd.Perform("unbind-disks", &compute.SnapshotPolicyDisksOptions{})
|
||||
cmd.Perform("bind-resources", &compute.SnapshotPolicyResourcesOptions{})
|
||||
cmd.Perform("unbind-resources", &compute.SnapshotPolicyResourcesOptions{})
|
||||
cmd.Perform("syncstatus", &options.BaseIdOptions{})
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ func init() {
|
||||
DiskType string `help:"Filter by disk type" choices:"sys|data"`
|
||||
Server string `help:"Filter by server" json:"server_id"`
|
||||
Unused bool
|
||||
StorageId string `help:"Filter by storage id"`
|
||||
|
||||
OrderByGuest string
|
||||
OrderByDiskName string
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
func init() {
|
||||
cmd := shell.NewResourceCmd(&modules.SslCerticicate).WithKeyword("ssl-certificate")
|
||||
cmd.List(&compute.SslCertificateListOptions{})
|
||||
cmd.Create(&compute.SslCertificateCreateOptions{})
|
||||
cmd.Show(&options.BaseShowOptions{})
|
||||
cmd.Delete(&options.BaseIdOptions{})
|
||||
}
|
||||
|
||||
@@ -74,12 +74,7 @@ func init() {
|
||||
if info.StorageType != "rbd" {
|
||||
return errors.Errorf("invalid storage_type %s", info.StorageType)
|
||||
}
|
||||
cli, err := cephutils.NewClient(
|
||||
info.StorageConf.MonHost,
|
||||
info.StorageConf.Key,
|
||||
info.StorageConf.Pool,
|
||||
info.StorageConf.EnableMessengerV2,
|
||||
)
|
||||
cli, err := cephutils.NewClient(info.StorageConf.MonHost, info.StorageConf.Key, info.StorageConf.Pool, info.StorageConf.EnableMessengerV2, 0, 0, 0)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cephutils.NewClient")
|
||||
}
|
||||
|
||||
@@ -29,4 +29,6 @@ func init() {
|
||||
cmd.Show(&options.BaseIdOptions{})
|
||||
cmd.Delete(&options.BaseIdOptions{})
|
||||
cmd.Perform("syncstatus", &options.BaseIdOptions{})
|
||||
cmd.Perform("enable", &options.BaseIdOptions{})
|
||||
cmd.Perform("disable", &options.BaseIdOptions{})
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/util/printutils"
|
||||
"yunion.io/x/pkg/util/shellutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
@@ -544,6 +545,81 @@ func (cmd ResourceCmd) Update(args IUpdateOpt) {
|
||||
cmd.UpdateWithKeyword("update", args)
|
||||
}
|
||||
|
||||
type EditType string
|
||||
|
||||
const (
|
||||
EditTypeText EditType = "text"
|
||||
EditTypeYaml EditType = "yaml"
|
||||
EditTypeJson EditType = "json"
|
||||
)
|
||||
|
||||
type IEditOpt interface {
|
||||
IGetOpt
|
||||
EditType() EditType
|
||||
EditFields() []string
|
||||
}
|
||||
|
||||
func (cmd ResourceCmd) Edit(args IEditOpt) {
|
||||
man := cmd.manager
|
||||
callback := func(s *mcclient.ClientSession, args IEditOpt) error {
|
||||
params, err := args.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
obj, err := man.(modulebase.Manager).Get(s, args.GetId(), params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
format := args.EditType()
|
||||
fields := args.EditFields()
|
||||
var editText string
|
||||
|
||||
switch format {
|
||||
case EditTypeText:
|
||||
editText, _ = obj.GetString(fields...)
|
||||
default:
|
||||
editJson, _ := obj.Get(fields...)
|
||||
if editJson == nil {
|
||||
editJson = jsonutils.NewDict()
|
||||
}
|
||||
if format == EditTypeYaml {
|
||||
editText = editJson.YAMLString()
|
||||
} else if format == EditTypeJson {
|
||||
editText = editJson.PrettyString()
|
||||
}
|
||||
}
|
||||
editText, err = shellutils.Edit(editText)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updateParams := jsonutils.NewDict()
|
||||
switch format {
|
||||
case EditTypeText:
|
||||
updateParams.Add(jsonutils.NewString(editText), fields...)
|
||||
case EditTypeYaml:
|
||||
yamlObj, err := jsonutils.ParseYAML(editText)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updateParams.Add(yamlObj, fields...)
|
||||
case EditTypeJson:
|
||||
jsonObj, err := jsonutils.ParseString(editText)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updateParams.Add(jsonObj, fields...)
|
||||
}
|
||||
updateResult, err := man.(modulebase.Manager).Update(s, args.GetId(), updateParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
PrintObject(updateResult)
|
||||
return nil
|
||||
}
|
||||
cmd.Run("edit", args, callback)
|
||||
}
|
||||
|
||||
type IMetadataOpt interface {
|
||||
IIdOpt
|
||||
IOpt
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
|
||||
@@ -27,11 +27,17 @@ import (
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
Help bool `help:"Show help"`
|
||||
Help bool `help:"Show help"`
|
||||
|
||||
Interface string `help:"Listening interface, e.g. eth0"`
|
||||
Ip string `help:"Listening interface IP, e.g. 192.168.22.2"`
|
||||
Port int `help:"listening port" default:"67"`
|
||||
Relay string `help:"Relay server address, e.g. 192.168.22.23"`
|
||||
|
||||
Ip string `help:"Listening interface IP, e.g. 192.168.22.2"`
|
||||
Port int `help:"listening port" default:"67"`
|
||||
Relay string `help:"Relay server address, e.g. 192.168.22.23"`
|
||||
|
||||
Ip6 string `help:"Listening interface IP, e.g. 2001:db8::1"`
|
||||
Port6 int `help:"listening port" default:"547"`
|
||||
Relay6 string `help:"Relay server address, e.g. 2001:db8::23"`
|
||||
}
|
||||
|
||||
func relayMain() error {
|
||||
@@ -45,6 +51,10 @@ func relayMain() error {
|
||||
}
|
||||
|
||||
err = parse.ParseArgs(os.Args[1:], false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
options := parse.Options().(*Options)
|
||||
|
||||
if options.Help {
|
||||
@@ -55,24 +65,45 @@ func relayMain() error {
|
||||
if len(options.Interface) == 0 {
|
||||
return errors.Error("Missing interface")
|
||||
}
|
||||
if len(options.Ip) == 0 {
|
||||
return errors.Error("Missing interface IP")
|
||||
}
|
||||
if len(options.Relay) == 0 {
|
||||
return errors.Error("Missing DHCP relay server")
|
||||
if len(options.Ip) == 0 && len(options.Ip6) == 0 {
|
||||
return errors.Error("Missing interface IP or IP6")
|
||||
}
|
||||
|
||||
srv, err := hostdhcp.NewGuestDHCPServer(options.Interface, options.Port, []string{
|
||||
options.Relay, "67",
|
||||
})
|
||||
if len(options.Ip) > 0 {
|
||||
if len(options.Relay) == 0 {
|
||||
return errors.Error("Missing DHCP relay server or relay server6")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "NewGuestDHCPServer")
|
||||
relayConfig := &hostdhcp.SDHCPRelayUpstream{}
|
||||
relayConfig.IP = options.Relay
|
||||
relayConfig.Port = 67
|
||||
srv, err := hostdhcp.NewGuestDHCPServer(options.Interface, options.Port, relayConfig)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "NewGuestDHCPServer")
|
||||
}
|
||||
|
||||
srv.Start(false)
|
||||
|
||||
srv.RelaySetup(options.Ip)
|
||||
}
|
||||
|
||||
srv.Start(false)
|
||||
if len(options.Ip6) > 0 {
|
||||
if len(options.Relay6) == 0 {
|
||||
return errors.Error("Missing DHCP relay server or relay server6")
|
||||
}
|
||||
|
||||
srv.RelaySetup(options.Ip)
|
||||
relayConfig6 := &hostdhcp.SDHCPRelayUpstream{}
|
||||
relayConfig6.IP = options.Relay6
|
||||
relayConfig6.Port = options.Port6
|
||||
srv6, err := hostdhcp.NewGuestDHCP6Server(options.Interface, options.Port6, relayConfig6)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "NewGuestDHCP6Server")
|
||||
}
|
||||
|
||||
srv6.Start(false)
|
||||
|
||||
srv6.RelaySetup(options.Ip6)
|
||||
}
|
||||
|
||||
for {
|
||||
time.Sleep(time.Hour)
|
||||
|
||||
34
go.mod
34
go.mod
@@ -12,11 +12,13 @@ require (
|
||||
github.com/bitly/go-simplejson v0.5.0
|
||||
github.com/c-bata/go-prompt v0.2.4
|
||||
github.com/cheggaaa/pb/v3 v3.0.8
|
||||
github.com/containerd/containerd v1.4.1
|
||||
github.com/coredns/coredns v1.3.0
|
||||
github.com/coreos/go-iptables v0.6.0
|
||||
github.com/creack/pty v1.1.18
|
||||
github.com/docker/docker v17.12.0-ce-rc1.0.20200916142827-bd33bbf0497b+incompatible
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96
|
||||
github.com/eggsampler/acme/v3 v3.6.2
|
||||
github.com/fernet/fernet-go v0.0.0-20180830025343-9eac43b88a5e
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/ghodss/yaml v1.0.0
|
||||
@@ -24,6 +26,7 @@ require (
|
||||
github.com/go-yaml/yaml v2.1.0+incompatible
|
||||
github.com/golang-plus/uuid v1.0.0
|
||||
github.com/golang/mock v1.4.4
|
||||
github.com/golang/protobuf v1.5.3
|
||||
github.com/google/cadvisor v0.38.5
|
||||
github.com/google/gopacket v1.1.17
|
||||
github.com/google/uuid v1.6.0
|
||||
@@ -32,7 +35,6 @@ require (
|
||||
github.com/gorilla/websocket v1.4.1
|
||||
github.com/gosuri/uitable v0.0.0-20160404203958-36ee7e946282
|
||||
github.com/hako/durafmt v0.0.0-20180520121703-7b7ae1e72ead
|
||||
github.com/hugozhu/godingtalk v1.0.6
|
||||
github.com/influxdata/influxql v1.1.0
|
||||
github.com/influxdata/promql/v2 v2.12.0
|
||||
github.com/jaypipes/ghw v0.11.0
|
||||
@@ -48,6 +50,7 @@ require (
|
||||
github.com/miekg/dns v1.1.25
|
||||
github.com/minio/minio-go v6.0.14+incompatible
|
||||
github.com/mitchellh/go-wordwrap v1.0.1
|
||||
github.com/petermattis/goid v0.0.0-20250508124226-395b08cebbdb
|
||||
github.com/pierrec/lz4/v4 v4.1.15
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pkg/sftp v1.13.6
|
||||
@@ -58,7 +61,7 @@ require (
|
||||
github.com/sevlyar/go-daemon v0.1.5
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||
github.com/shirou/gopsutil/v3 v3.22.10
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9
|
||||
github.com/smartystreets/goconvey v1.7.2
|
||||
github.com/stretchr/testify v1.9.0
|
||||
@@ -74,14 +77,14 @@ require (
|
||||
go.etcd.io/etcd/client/v3 v3.5.0
|
||||
golang.org/x/crypto v0.19.0
|
||||
golang.org/x/net v0.21.0
|
||||
golang.org/x/sync v0.6.0
|
||||
golang.org/x/sys v0.17.0
|
||||
golang.org/x/sync v0.8.0
|
||||
golang.org/x/sys v0.26.0
|
||||
golang.org/x/text v0.14.0
|
||||
golang.org/x/time v0.5.0
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028
|
||||
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230215201556-9c5414ab4bde
|
||||
google.golang.org/grpc v1.62.0
|
||||
google.golang.org/protobuf v1.32.0
|
||||
google.golang.org/protobuf v1.35.1
|
||||
gopkg.in/fatih/set.v0 v0.2.1
|
||||
gopkg.in/ldap.v3 v3.0.3
|
||||
gopkg.in/mail.v2 v2.3.1
|
||||
@@ -93,14 +96,14 @@ require (
|
||||
k8s.io/cri-api v0.22.17
|
||||
k8s.io/klog/v2 v2.20.0
|
||||
moul.io/http2curl/v2 v2.3.0
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250427071042-3ec467b38f4d
|
||||
yunion.io/x/executor v0.0.0-20241205080005-48f5b1212256
|
||||
yunion.io/x/jsonutils v1.0.1-0.20250406102002-98c9140a9edd
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250820024120-20f73c47b078
|
||||
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0
|
||||
yunion.io/x/jsonutils v1.0.1-0.20250507052344-1abcf4f443b1
|
||||
yunion.io/x/log v1.0.1-0.20240305175729-7cf2d6cd5a91
|
||||
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900
|
||||
yunion.io/x/pkg v1.10.4-0.20250403114914-586e94d39281
|
||||
yunion.io/x/pkg v1.10.4-0.20250814065738-8df5d9d07297
|
||||
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1
|
||||
yunion.io/x/sqlchemy v1.1.3-0.20250420094945-40f40c75a31f
|
||||
yunion.io/x/sqlchemy v1.1.3-0.20250806073422-e37f5197cec0
|
||||
yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c
|
||||
)
|
||||
|
||||
@@ -125,7 +128,8 @@ require (
|
||||
github.com/DataDog/dd-trace-go v0.6.1 // indirect
|
||||
github.com/DataDog/zstd v1.3.4 // indirect
|
||||
github.com/Microsoft/azure-vhd-utils v0.0.0-20181115010904-44cbada2ece3 // indirect
|
||||
github.com/Microsoft/go-winio v0.4.15 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.8.14 // indirect
|
||||
github.com/RoaringBitmap/roaring v0.4.16 // indirect
|
||||
github.com/Shopify/sarama v1.20.0 // indirect
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible // indirect
|
||||
@@ -155,9 +159,12 @@ require (
|
||||
github.com/checkpoint-restore/go-criu/v4 v4.1.0 // indirect
|
||||
github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775 // indirect
|
||||
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 // indirect
|
||||
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 // indirect
|
||||
github.com/containerd/console v1.0.0 // indirect
|
||||
github.com/containerd/containerd v1.4.1 // indirect
|
||||
github.com/containerd/continuity v0.4.5 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/ttrpc v1.0.2 // indirect
|
||||
github.com/containerd/typeurl v1.0.1 // indirect
|
||||
github.com/coreos/go-semver v0.3.0 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.2 // indirect
|
||||
@@ -167,6 +174,7 @@ require (
|
||||
github.com/dnstap/golang-dnstap v0.0.0-20170829151710-2cf77a2b5e11 // indirect
|
||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-events v0.0.0-20250114142523-c867878c5e32 // indirect
|
||||
github.com/docker/go-units v0.4.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/eapache/go-resiliency v1.1.0 // indirect
|
||||
@@ -195,7 +203,6 @@ require (
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-plus/errors v1.0.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/btree v1.0.1 // indirect
|
||||
github.com/google/go-querystring v1.0.0 // indirect
|
||||
@@ -292,6 +299,7 @@ require (
|
||||
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect
|
||||
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
go.etcd.io/bbolt v1.3.7 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0 // indirect
|
||||
|
||||
80
go.sum
80
go.sum
@@ -93,8 +93,12 @@ github.com/LeeEirc/terminalparser v0.0.0-20240205084113-fbf78c8480f2 h1:XGB3B065
|
||||
github.com/LeeEirc/terminalparser v0.0.0-20240205084113-fbf78c8480f2/go.mod h1:tiLv6VBLH4Z3KdBSe2qIKRwQDGCVQ9/F5fOKpQGvyoA=
|
||||
github.com/Microsoft/azure-vhd-utils v0.0.0-20181115010904-44cbada2ece3 h1:gImoAO1xAcC1oDlYmD/X7dggsodGf2DFJOVE5m0ssms=
|
||||
github.com/Microsoft/azure-vhd-utils v0.0.0-20181115010904-44cbada2ece3/go.mod h1:u0H9gMieFLxkUy8RS0X8VbFWyPs2815qQAaitRbj6x0=
|
||||
github.com/Microsoft/go-winio v0.4.15 h1:qkLXKzb1QoVatRyd/YlXZ/Kg0m5K3SPuoD82jjSOaBc=
|
||||
github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||
github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/Microsoft/hcsshim v0.8.14 h1:lbPVK25c1cu5xTLITwpUcxoA9vKrKErASPYygvouJns=
|
||||
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
@@ -207,6 +211,7 @@ github.com/cheggaaa/pb/v3 v3.0.8/go.mod h1:UICbiLec/XO6Hw6k+BHEtHeQFzzBH4i2/qk/o
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
|
||||
github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775 h1:cHzBGGVew0ezFsq2grfy2RsB8hO/eNyBgOLHBCqfR1U=
|
||||
github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
@@ -216,12 +221,25 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ=
|
||||
github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM=
|
||||
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59 h1:qWj4qVYZ95vLWwqyNJCQg7rDsG5wPdze0UaPolH7DUk=
|
||||
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
|
||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||
github.com/containerd/console v1.0.0 h1:fU3UuQapBs+zLJu82NhR11Rif1ny2zfMMAyPJzSN5tQ=
|
||||
github.com/containerd/console v1.0.0/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
|
||||
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/containerd v1.4.1 h1:pASeJT3R3YyVn+94qEPk0SnU1OQ20Jd/T+SPKy9xehY=
|
||||
github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||
github.com/containerd/continuity v0.4.5 h1:ZRoN1sXq9u7V6QoHMcVWGhOwDFqZ4B9i5H6un1Wh0x4=
|
||||
github.com/containerd/continuity v0.4.5/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
|
||||
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v1.0.2 h1:2/O3oTZN36q2xRolk0a2WWGgh7/Vf/liElg5hFYLX9U=
|
||||
github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
|
||||
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
|
||||
github.com/containerd/typeurl v1.0.1 h1:PvuK4E3D5S5q6IqsPDCy928FhP0LUIGcmZ/Yhgp5Djw=
|
||||
github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
|
||||
github.com/coredns/coredns v1.3.0 h1:Ubjr8ZrOpEj95/A9dqQqQAG2k5DWEFdg2ZB3tUXuULA=
|
||||
@@ -230,10 +248,12 @@ github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo
|
||||
github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
|
||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
@@ -256,6 +276,8 @@ github.com/docker/docker v20.10.27+incompatible h1:Id/ZooynV4ZlD6xX20RCd3SR0Ikn7
|
||||
github.com/docker/docker v20.10.27+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-events v0.0.0-20250114142523-c867878c5e32 h1:EHZfspsnLAz8Hzccd67D5abwLiqoqym2jz/jOS39mCk=
|
||||
github.com/docker/go-events v0.0.0-20250114142523-c867878c5e32/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg=
|
||||
@@ -273,6 +295,8 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP
|
||||
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/eggsampler/acme/v3 v3.6.2 h1:gvyZbQ92wNQLDASVftGpHEdFwPSfg0+17P0lLt09Tp8=
|
||||
github.com/eggsampler/acme/v3 v3.6.2/go.mod h1:/qh0rKC/Dh7Jj+p4So7DbWmFNzC4dpcpK53r226Fhuo=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/elgatito/upnp v0.0.0-20180711183757-2f244d205f9a h1:2Zw3pxDRTs4nX1WCLAEm27UN0hvjZSge7EaUUQexRZw=
|
||||
github.com/elgatito/upnp v0.0.0-20180711183757-2f244d205f9a/go.mod h1:afkYpY8JAIL4341N7Zj9xJ5yTovsg6BkWfBFlCzIoF4=
|
||||
@@ -430,7 +454,6 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@@ -496,15 +519,12 @@ github.com/huandu/xstrings v1.2.0 h1:yPeWdRnmynF7p+lLYz0H2tthW9lqhMJrQV/U7yy4wX0
|
||||
github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
|
||||
github.com/huaweicloud/huaweicloud-sdk-go v1.0.26 h1:aWTl4Ng9lZUW1DupYyqYiqkTwuTKMmqUZBKLmX0iWxo=
|
||||
github.com/huaweicloud/huaweicloud-sdk-go v1.0.26/go.mod h1:YHXxw/bm7AohI4jTY8Z43JYw+DPCDLqjxoLTqmcyja4=
|
||||
github.com/hugozhu/godingtalk v1.0.6 h1:K280OQGbYVS/UQuVWJz5cHhv/Wvfj1FHNo8lbbLGsNQ=
|
||||
github.com/hugozhu/godingtalk v1.0.6/go.mod h1:Je6PSjUH7IKCPpFq5ti2I9ak1szzSNgCIMlP0s+8pbQ=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
|
||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/influxdata/influxql v1.1.0 h1:sPsaumLFRPMwR5QtD3Up54HXpNND8Eu7G1vQFmi3quQ=
|
||||
github.com/influxdata/influxql v1.1.0/go.mod h1:KpVI7okXjK6PRi3Z5B+mtKZli+R1DnZgb3N+tzevNgo=
|
||||
github.com/ipandtcp/godingtalk v0.0.0-20180410032244-ca3d6ac197fb/go.mod h1:3umLciE1jBnh2LgrL15R2zbEe+HVPRZXnlSjjb/dYiw=
|
||||
github.com/jaypipes/ghw v0.11.0 h1:i0pKvAM7eZk0KvLm9vzpcpDKTRnfR6AQ5pFkPVnYJXU=
|
||||
github.com/jaypipes/ghw v0.11.0/go.mod h1:jeJGbkRB2lL3/gxYzNYzEDETV1ZJ56OKr+CSeSEym+g=
|
||||
github.com/jdcloud-api/jdcloud-sdk-go v1.55.0 h1:mzVj8r6fluEwjn8ogqtGfYW2qSIVUaEq0JAsvjCav3A=
|
||||
@@ -669,12 +689,15 @@ github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGV
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
|
||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
||||
github.com/opencontainers/runc v1.0.0-rc92 h1:+IczUKCRzDzFDnw99O/PAqrcBBCoRp9xN3cB1SYSNS4=
|
||||
github.com/opencontainers/runc v1.0.0-rc92/go.mod h1:X1zlU4p7wOlX4+WRCz+hvlRv8phdL7UqbYD+vQwNMmE=
|
||||
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6 h1:NhsM2gc769rVWDqJvapK37r+7+CBXI8xHhnfnt8uQsg=
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.6.0 h1:+bIAS/Za3q5FTwWym4fTB0vObnfCf3G/NC7K6Jx62mY=
|
||||
@@ -688,6 +711,8 @@ github.com/openzipkin/zipkin-go-opentracing v0.3.4/go.mod h1:js2AbwmHW0YD9DwIw2J
|
||||
github.com/oracle/oci-go-sdk v24.3.0+incompatible h1:x4mcfb4agelf1O4/1/auGlZ1lr97jXRSSN5MxTgG/zU=
|
||||
github.com/oracle/oci-go-sdk v24.3.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||
github.com/petermattis/goid v0.0.0-20250508124226-395b08cebbdb h1:3PrKuO92dUTMrQ9dx0YNejC6U/Si6jqKmyQ9vWjwqR4=
|
||||
github.com/petermattis/goid v0.0.0-20250508124226-395b08cebbdb/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
|
||||
github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
|
||||
github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
@@ -727,6 +752,7 @@ github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB8
|
||||
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-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
@@ -773,8 +799,9 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 h1:lpEzuenPuO1XNTeikEmvqYFcU37GVLl8SRNblzyvGBE=
|
||||
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo=
|
||||
github.com/smartystreets/assertions v0.0.0-20180607162144-eb5b59917fa2/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
@@ -840,6 +867,7 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY
|
||||
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
|
||||
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
@@ -879,6 +907,8 @@ github.com/zexi/influxql-to-metricsql v0.1.1 h1:dXnVzlxVLuo88zGkDca7erEnmvprGWjz
|
||||
github.com/zexi/influxql-to-metricsql v0.1.1/go.mod h1:JlC5FY+6De9ZPxG47G5DOgva8P9X1VaKS4ExzCmhSCc=
|
||||
github.com/zexi/promql/v2 v2.12.1 h1:crHKpULdLLsBZ9b78Rg6qQkugzlk6BHeCj93tw/F5RU=
|
||||
github.com/zexi/promql/v2 v2.12.1/go.mod h1:2UtzWZGmth95n2qdIZWpJ5yQ0cE5hEvz0dGsajI1Sqg=
|
||||
go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ=
|
||||
go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
||||
go.etcd.io/etcd/api/v3 v3.5.0 h1:GsV3S+OfZEOCNXdtNkBSR7kgLobAa/SO6tCxRa0GAYw=
|
||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0 h1:2aQv6F436YnN7I4VbI8PPYrBhu+SmrTaADcf8Mi/6PU=
|
||||
@@ -984,6 +1014,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
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-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/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=
|
||||
@@ -1032,8 +1063,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180724212812-e072cadbbdc8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -1059,6 +1090,7 @@ golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
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-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -1089,6 +1121,7 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201110211018-35f3e6cf4a65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/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=
|
||||
@@ -1107,8 +1140,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -1201,7 +1234,6 @@ google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEt
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.10.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/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
@@ -1220,7 +1252,6 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
|
||||
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.4/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
@@ -1269,6 +1300,7 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
@@ -1294,8 +1326,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
|
||||
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/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
@@ -1376,13 +1408,13 @@ sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250427071042-3ec467b38f4d h1:RnK6jhPwXRkQUDRL96YV7qeKbGq5zSZ2SQ/T6Jur574=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250427071042-3ec467b38f4d/go.mod h1:FXxAEbdNfWXX9gjME3K2nJhkydHY5EKEUZb+RLEzVwQ=
|
||||
yunion.io/x/executor v0.0.0-20241205080005-48f5b1212256 h1:kLKQ6zbgPDQflRwoHFAjxNChcbhXIFgsUVLkJwiXu/8=
|
||||
yunion.io/x/executor v0.0.0-20241205080005-48f5b1212256/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250820024120-20f73c47b078 h1:KaAEKjdAcpRrJlrJfOtcXCz5IUgPdv7dqeZnLswxLXE=
|
||||
yunion.io/x/cloudmux v0.3.10-0-alpha.1.0.20250820024120-20f73c47b078/go.mod h1:FXxAEbdNfWXX9gjME3K2nJhkydHY5EKEUZb+RLEzVwQ=
|
||||
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0 h1:msG4SiDSVU7CrXH06WuHlNEZXIooTcmNbfrIGHuIHBU=
|
||||
yunion.io/x/executor v0.0.0-20250518005516-5402e9e0bed0/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
|
||||
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
|
||||
yunion.io/x/jsonutils v1.0.1-0.20250406102002-98c9140a9edd h1:FWwB4CXiyIrh2YvxPliC9ZmrzXcFv+nuG3lhpipR4Sk=
|
||||
yunion.io/x/jsonutils v1.0.1-0.20250406102002-98c9140a9edd/go.mod h1:VK4Z93dgiKgAijcSqbMKmGaBMJuHulR16Hz4K015ZPo=
|
||||
yunion.io/x/jsonutils v1.0.1-0.20250507052344-1abcf4f443b1 h1:/+THlvf/MvgCW+7KeCDCr33e81KSRa5JmdZ1IIyLOXQ=
|
||||
yunion.io/x/jsonutils v1.0.1-0.20250507052344-1abcf4f443b1/go.mod h1:VK4Z93dgiKgAijcSqbMKmGaBMJuHulR16Hz4K015ZPo=
|
||||
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 v1.0.1-0.20240305175729-7cf2d6cd5a91 h1:inY5o3LDa/zgsIZuPN0HmpzKIsu/lLgsBmMttuDPGj4=
|
||||
@@ -1391,11 +1423,11 @@ yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900 h1:Hu/4ERvoWaN6aiFs4h4/yvVB
|
||||
yunion.io/x/ovsdb v0.0.0-20230306173834-f164f413a900/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 v1.10.4-0.20250403114914-586e94d39281 h1:P22/MaBc9bqE9DyHvS3oQjc4XsaIEbIVGMLdTSroDew=
|
||||
yunion.io/x/pkg v1.10.4-0.20250403114914-586e94d39281/go.mod h1:0Bwxqd9MA3ACi119/l02FprY/o9gHahmYC2bsSbnVpM=
|
||||
yunion.io/x/pkg v1.10.4-0.20250814065738-8df5d9d07297 h1:rnU78gHJ+2nEgjpwWN+FclED/nFeuMkrrBWgnTz0ykc=
|
||||
yunion.io/x/pkg v1.10.4-0.20250814065738-8df5d9d07297/go.mod h1:0Bwxqd9MA3ACi119/l02FprY/o9gHahmYC2bsSbnVpM=
|
||||
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1 h1:1KJ3YYinydPHpDEQRXdr/T8SYcKZ5Er+m489H+PnaQ4=
|
||||
yunion.io/x/s3cli v0.0.0-20241221171442-1c11599d28e1/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo=
|
||||
yunion.io/x/sqlchemy v1.1.3-0.20250420094945-40f40c75a31f h1:xuy9a8Hg0d8dfD8j13f687eKPCxEvttgpLQWb4NvKpI=
|
||||
yunion.io/x/sqlchemy v1.1.3-0.20250420094945-40f40c75a31f/go.mod h1:vCIZpqhZ5Jzaq3tFyrti/vv8BijQKtkzSgNT/uH4H5A=
|
||||
yunion.io/x/sqlchemy v1.1.3-0.20250806073422-e37f5197cec0 h1:Eha/ywh4foMJm7VJ8ibFOi+WPHacuTWtosAGpOld5vo=
|
||||
yunion.io/x/sqlchemy v1.1.3-0.20250806073422-e37f5197cec0/go.mod h1:vCIZpqhZ5Jzaq3tFyrti/vv8BijQKtkzSgNT/uH4H5A=
|
||||
yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c h1:QuLab2kSRECZRxo4Lo2KcYn6XjQFDGaZ1+x0pYDVVwQ=
|
||||
yunion.io/x/structarg v0.0.0-20231017124457-df4d5009457c/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng=
|
||||
|
||||
@@ -15,28 +15,5 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/ansible"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/cloudevent"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/cloudid"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/cloudnet"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/cloudproxy"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/devtool"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/etcd"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/identity"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/image"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/logger"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/monitor"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/notify"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/quota"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/scheduledtask"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/scheduler"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/webconsole"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/yunionconf"
|
||||
_ "yunion.io/x/onecloud/pkg/mcclient/modules/loader"
|
||||
)
|
||||
|
||||
func init() {
|
||||
modules.InitUsages()
|
||||
modules.Usages.RegisterManager(modules.UsageManagerK8s, k8s.Usages)
|
||||
}
|
||||
|
||||
47
pkg/apis/compute/ai_gateway.go
Normal file
47
pkg/apis/compute/ai_gateway.go
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
)
|
||||
|
||||
type AiGatewayCreateInput struct {
|
||||
apis.VirtualResourceCreateInput
|
||||
CloudproviderResourceInput
|
||||
|
||||
Authentication bool `json:"authentication"`
|
||||
CacheInvalidateOnUpdate bool `json:"cache_invalidate_on_update"`
|
||||
CacheTTL int `json:"cache_ttl"`
|
||||
CollectLogs bool `json:"collect_logs"`
|
||||
RateLimitingInterval int `json:"rate_limiting_interval"`
|
||||
RateLimitingLimit int `json:"rate_limiting_limit"`
|
||||
RateLimitingTechnique string `json:"rate_limiting_technique"`
|
||||
}
|
||||
|
||||
type AiGatewayListInput struct {
|
||||
apis.VirtualResourceListInput
|
||||
apis.ExternalizedResourceBaseListInput
|
||||
ManagedResourceListInput
|
||||
}
|
||||
|
||||
type AiGatewayDetails struct {
|
||||
apis.VirtualResourceDetails
|
||||
ManagedResourceInfo
|
||||
}
|
||||
|
||||
type AiGatewayUpdateInput struct {
|
||||
apis.VirtualResourceBaseUpdateInput
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
@@ -88,6 +90,10 @@ type NetworkConfig struct {
|
||||
// required: false
|
||||
RequireIPv6 bool `json:"require_ipv6"`
|
||||
|
||||
// 只分配IPv6地址,禁用IPv4
|
||||
// required: false
|
||||
StrictIPv6 bool `json:"strict_ipv6"`
|
||||
|
||||
// 驱动方式
|
||||
// 若指定镜像的网络驱动方式,此参数会被覆盖
|
||||
Driver string `json:"driver"`
|
||||
@@ -648,6 +654,8 @@ type ServerCreateInput struct {
|
||||
BillingType string `json:"billing_type"`
|
||||
// swagger:ignore
|
||||
BillingCycle string `json:"billing_cycle"`
|
||||
// 到期释放时间
|
||||
ReleaseAt time.Time `json:"release_at"`
|
||||
|
||||
// swagger:ignore
|
||||
// Deprecated
|
||||
|
||||
@@ -17,6 +17,7 @@ package compute
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
@@ -53,6 +54,8 @@ type BucketCreateInput struct {
|
||||
CloudproviderResourceInput
|
||||
|
||||
StorageClass string `json:"storage_class"`
|
||||
|
||||
EnablePerfMon *bool `json:"enable_perf_mon"`
|
||||
}
|
||||
|
||||
type BucketDetails struct {
|
||||
@@ -66,28 +69,28 @@ type BucketDetails struct {
|
||||
AccessUrls []cloudprovider.SBucketAccessUrl `json:"access_urls"`
|
||||
}
|
||||
|
||||
func (self BucketDetails) GetMetricTags() map[string]string {
|
||||
func (bucket BucketDetails) GetMetricTags() map[string]string {
|
||||
ret := map[string]string{
|
||||
"id": self.Id,
|
||||
"brand": self.Brand,
|
||||
"cloudregion": self.Cloudregion,
|
||||
"cloudregion_id": self.CloudregionId,
|
||||
"domain_id": self.DomainId,
|
||||
"oss_id": self.Id,
|
||||
"oss_name": self.Name,
|
||||
"project_domain": self.ProjectDomain,
|
||||
"region_ext_id": self.RegionExtId,
|
||||
"status": self.Status,
|
||||
"tenant": self.Project,
|
||||
"tenant_id": self.ProjectId,
|
||||
"account": self.Account,
|
||||
"account_id": self.AccountId,
|
||||
"external_id": self.ExternalId,
|
||||
"id": bucket.Id,
|
||||
"brand": bucket.Brand,
|
||||
"cloudregion": bucket.Cloudregion,
|
||||
"cloudregion_id": bucket.CloudregionId,
|
||||
"domain_id": bucket.DomainId,
|
||||
"oss_id": bucket.Id,
|
||||
"oss_name": bucket.Name,
|
||||
"project_domain": bucket.ProjectDomain,
|
||||
"region_ext_id": bucket.RegionExtId,
|
||||
"status": bucket.Status,
|
||||
"tenant": bucket.Project,
|
||||
"tenant_id": bucket.ProjectId,
|
||||
"account": bucket.Account,
|
||||
"account_id": bucket.AccountId,
|
||||
"external_id": bucket.ExternalId,
|
||||
}
|
||||
return AppendMetricTags(ret, self.MetadataResourceInfo, self.ProjectizedResourceInfo)
|
||||
return AppendMetricTags(ret, bucket.MetadataResourceInfo, bucket.ProjectizedResourceInfo)
|
||||
}
|
||||
|
||||
func (self BucketDetails) GetMetricPairs() map[string]string {
|
||||
func (bucket BucketDetails) GetMetricPairs() map[string]string {
|
||||
ret := map[string]string{}
|
||||
return ret
|
||||
}
|
||||
@@ -150,6 +153,8 @@ type BucketSyncstatusInput struct {
|
||||
|
||||
type BucketUpdateInput struct {
|
||||
apis.SharableVirtualResourceBaseUpdateInput
|
||||
|
||||
EnablePerfMon *bool `json:"enable_perf_mon"`
|
||||
}
|
||||
|
||||
type BucketPerformTempUrlInput struct {
|
||||
@@ -370,3 +375,29 @@ func init() {
|
||||
return &SBackupStorageAccessInfo{}
|
||||
})
|
||||
}
|
||||
|
||||
type BucketProbeResult struct {
|
||||
UploadTime time.Duration
|
||||
DownloadTime time.Duration
|
||||
DeleteTime time.Duration
|
||||
}
|
||||
|
||||
func (result BucketProbeResult) UploadDelayMs() float64 {
|
||||
return float64(result.UploadTime) / float64(time.Millisecond)
|
||||
}
|
||||
|
||||
func (result BucketProbeResult) DownloadDelayMs() float64 {
|
||||
return float64(result.DownloadTime) / float64(time.Millisecond)
|
||||
}
|
||||
|
||||
func (result BucketProbeResult) DeleteDelayMs() float64 {
|
||||
return float64(result.DeleteTime) / float64(time.Millisecond)
|
||||
}
|
||||
|
||||
func (result BucketProbeResult) UploadThroughputMbps(sizeMBytes int) float64 {
|
||||
return float64(sizeMBytes) * 8 / float64(result.UploadTime.Seconds())
|
||||
}
|
||||
|
||||
func (result BucketProbeResult) DownloadThroughputMbps(sizeMBytes int) float64 {
|
||||
return float64(sizeMBytes) * 8 / float64(result.DownloadTime.Seconds())
|
||||
}
|
||||
|
||||
@@ -95,3 +95,11 @@ type CDNDomainListInput struct {
|
||||
|
||||
ManagedResourceListInput
|
||||
}
|
||||
|
||||
type CDNCustomHostnameOutput struct {
|
||||
Data []cloudprovider.CustomHostname
|
||||
}
|
||||
|
||||
type CDNDeleteCustomHostnameInput struct {
|
||||
Id string
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ const (
|
||||
CLOUD_PROVIDER_ZETTAKIT = compute.CLOUD_PROVIDER_ZETTAKIT
|
||||
CLOUD_PROVIDER_UIS = compute.CLOUD_PROVIDER_UIS
|
||||
CLOUD_PROVIDER_CAS = compute.CLOUD_PROVIDER_CAS
|
||||
CLOUD_PROVIDER_CLOUDFLARE = compute.CLOUD_PROVIDER_CLOUDFLARE
|
||||
|
||||
CLOUD_PROVIDER_GENERICS3 = compute.CLOUD_PROVIDER_GENERICS3
|
||||
CLOUD_PROVIDER_CEPH = compute.CLOUD_PROVIDER_CEPH
|
||||
@@ -143,6 +144,7 @@ var (
|
||||
CLOUD_PROVIDER_JDCLOUD,
|
||||
CLOUD_PROVIDER_VOLCENGINE,
|
||||
CLOUD_PROVIDER_ORACLE,
|
||||
CLOUD_PROVIDER_CLOUDFLARE,
|
||||
}
|
||||
|
||||
CLOUD_PROVIDERS = []string{
|
||||
@@ -181,6 +183,7 @@ var (
|
||||
CLOUD_PROVIDER_ZETTAKIT,
|
||||
CLOUD_PROVIDER_UIS,
|
||||
CLOUD_PROVIDER_CAS,
|
||||
CLOUD_PROVIDER_CLOUDFLARE,
|
||||
}
|
||||
|
||||
CLOUD_PROVIDER_HOST_TYPE_MAP = map[string][]string{
|
||||
|
||||
@@ -130,6 +130,7 @@ const (
|
||||
type ContainerSpec struct {
|
||||
apis.ContainerSpec
|
||||
// Volume mounts
|
||||
RootFs *apis.ContainerRootfs `json:"rootfs"`
|
||||
VolumeMounts []*apis.ContainerVolumeMount `json:"volume_mounts"`
|
||||
Devices []*ContainerDevice `json:"devices"`
|
||||
}
|
||||
@@ -207,6 +208,8 @@ type ContainerSaveVolumeMountToImageInput struct {
|
||||
Index int `json:"index"`
|
||||
Dirs []string `json:"dirs"`
|
||||
UsedByPostOverlay bool `json:"used_by_post_overlay"`
|
||||
|
||||
DirPrefix string `json:"dir_prefix"`
|
||||
}
|
||||
|
||||
type ContainerExecInfoOutput struct {
|
||||
|
||||
@@ -82,8 +82,8 @@ type DBInstanceCreateInput struct {
|
||||
// default: false
|
||||
AutoRenew bool `json:"auto_renew"`
|
||||
|
||||
// swagger:ignore
|
||||
ExpiredAt time.Time `json:"expired_at"`
|
||||
// 到期释放时间
|
||||
ReleaseAt time.Time `json:"release_at"`
|
||||
|
||||
// 计费方式
|
||||
// enum: ["postpaid", "prepaid"]
|
||||
|
||||
@@ -171,6 +171,9 @@ type DiskListInput struct {
|
||||
|
||||
// 根据虚拟机状态过滤
|
||||
GuestStatus string `json:"guest_status"`
|
||||
|
||||
// 根据是否绑定快照策略过滤
|
||||
BindingSnapshotpolicy *bool `json:"binding_snapshotpolicy"`
|
||||
}
|
||||
|
||||
type DiskResourceInput struct {
|
||||
@@ -213,6 +216,8 @@ type SimpleGuest struct {
|
||||
Iops int `json:"iops"`
|
||||
// 磁盘吞吐
|
||||
Bps int `json:"bps"`
|
||||
// 计费类型
|
||||
BillingType string `json:"billing_type"`
|
||||
}
|
||||
|
||||
type SimpleSnapshotPolicy struct {
|
||||
@@ -237,6 +242,8 @@ type DiskDetails struct {
|
||||
GuestCount int `json:"guest_count"`
|
||||
// 所挂载虚拟机状态
|
||||
GuestStatus string `json:"guest_status"`
|
||||
// 所挂载虚拟机计费类型
|
||||
GuestBillingType string `json:"guest_billing_type"`
|
||||
|
||||
// 自动清理时间
|
||||
AutoDeleteAt time.Time `json:"auto_delete_at"`
|
||||
@@ -376,3 +383,11 @@ func (d *DiskFsFeatures) IsZero() bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type DiskChangeBillingTypeInput struct {
|
||||
// 仅在磁盘挂载在虚拟机上时调用
|
||||
// 目前支持阿里云
|
||||
// enmu: [postpaid, prepaid]
|
||||
// required: true
|
||||
BillingType string `json:"billing_type"`
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ type DnsRecordCreateInput struct {
|
||||
DnsValue string `json:"dns_value"`
|
||||
TTL int64 `json:"ttl"`
|
||||
MxPriority int64 `json:"mx_priority"`
|
||||
Proxied *bool `json:"proxied"`
|
||||
|
||||
PolicyType string `json:"policy_type"`
|
||||
PolicyValue string `json:"policy_value"`
|
||||
@@ -48,6 +49,7 @@ type DnsRecordUpdateInput struct {
|
||||
DnsValue string `json:"dns_value"`
|
||||
TTL *int64 `json:"ttl"`
|
||||
MxPriority *int64 `json:"mx_priority"`
|
||||
Proxied *bool `json:"proxied"`
|
||||
}
|
||||
|
||||
type DnsRecordDetails struct {
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/gotypes"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
)
|
||||
@@ -97,3 +101,19 @@ type DnsZoneRemoveVpcsInput struct {
|
||||
|
||||
type DnsZonePurgeInput struct {
|
||||
}
|
||||
|
||||
type SNameServers []string
|
||||
|
||||
func (ns SNameServers) String() string {
|
||||
return jsonutils.Marshal(ns).String()
|
||||
}
|
||||
|
||||
func (ns SNameServers) IsZero() bool {
|
||||
return len(ns) == 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
gotypes.RegisterSerializable(reflect.TypeOf(&SNameServers{}), func() gotypes.ISerializable {
|
||||
return &SNameServers{}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -246,13 +246,13 @@ type ElasticcacheCreateInput struct {
|
||||
// 包年包月时间周期
|
||||
Duration string `json:"duration"`
|
||||
|
||||
// 到期释放时间
|
||||
ReleaseAt time.Time `json:"release_at"`
|
||||
|
||||
// 是否自动续费(仅包年包月时生效)
|
||||
// default: false
|
||||
AutoRenew bool `json:"auto_renew"`
|
||||
|
||||
// swagger:ignore
|
||||
ExpiredAt time.Time `json:"expired_at"`
|
||||
|
||||
// 计费方式
|
||||
// enum: ["postpaid", "prepaid"]
|
||||
BillingType string
|
||||
|
||||
@@ -94,6 +94,9 @@ type ElasticipDetails struct {
|
||||
|
||||
// 绑定资源名称
|
||||
AssociateName string `json:"associate_name"`
|
||||
|
||||
// 虚拟机内网IP
|
||||
ServerPrivateIp string `json:"server_private_ip"`
|
||||
}
|
||||
|
||||
func (self ElasticipDetails) GetMetricTags() map[string]string {
|
||||
|
||||
@@ -87,8 +87,8 @@ type FileSystemCreateInput struct {
|
||||
// default: false
|
||||
AutoRenew bool `json:"auto_renew"`
|
||||
|
||||
// 到期释放时间,仅后付费支持
|
||||
ExpiredAt time.Time `json:"expired_at"`
|
||||
// 到期释放时间
|
||||
ReleaseAt time.Time `json:"release_at"`
|
||||
|
||||
// 计费方式
|
||||
// enum: ["postpaid", "prepaid"]
|
||||
|
||||
@@ -180,10 +180,6 @@ const (
|
||||
VM_QGA_SET_NETWORK = "qga_set_network"
|
||||
VM_QGA_SET_NETWORK_FAILED = "qga_set_network_failed"
|
||||
|
||||
// 更改计费模式
|
||||
VM_CHANGE_BILLING_TYPE = "change_billing_type"
|
||||
VM_CHANGE_BILLING_TYPE_FAILED = "change_billing_type_failed"
|
||||
|
||||
SHUTDOWN_STOP = "stop"
|
||||
SHUTDOWN_TERMINATE = "terminate"
|
||||
SHUTDOWN_STOP_RELEASE_GPU = "stop_release_gpu"
|
||||
@@ -265,6 +261,9 @@ const (
|
||||
VM_VIDEO_STANDARD = "std"
|
||||
VM_VIDEO_QXL = "qxl"
|
||||
VM_VIDEO_VIRTIO = "virtio"
|
||||
|
||||
VM_BOOT_MODE_BIOS = "BIOS"
|
||||
VM_BOOT_MODE_UEFI = "UEFI"
|
||||
)
|
||||
|
||||
var VM_RUNNING_STATUS = []string{VM_START_START, VM_STARTING, VM_RUNNING, VM_BLOCK_STREAM, VM_BLOCK_STREAM_FAIL}
|
||||
@@ -317,22 +316,23 @@ const (
|
||||
VM_AZURE_DEFAULT_LOGIN_USER = compute.VM_AZURE_DEFAULT_LOGIN_USER
|
||||
VM_ZSTACK_DEFAULT_LOGIN_USER = compute.VM_ZSTACK_DEFAULT_LOGIN_USER
|
||||
|
||||
VM_METADATA_APP_TAGS = "app_tags"
|
||||
VM_METADATA_CREATE_PARAMS = "create_params"
|
||||
VM_METADATA_LOGIN_ACCOUNT = "login_account"
|
||||
VM_METADATA_LOGIN_KEY = "login_key"
|
||||
VM_METADATA_LAST_LOGIN_KEY = "last_login_key"
|
||||
VM_METADATA_LOGIN_KEY_TIMESTAMP = "login_key_timestamp"
|
||||
VM_METADATA_OS_ARCH = "os_arch"
|
||||
VM_METADATA_OS_DISTRO = "os_distribution"
|
||||
VM_METADATA_OS_NAME = "os_name"
|
||||
VM_METADATA_OS_VERSION = "os_version"
|
||||
VM_METADATA_CGROUP_CPUSET = "cgroup_cpuset"
|
||||
VM_METADATA_ENABLE_MEMCLEAN = "enable_memclean"
|
||||
VM_METADATA_HOTPLUG_CPU_MEM = "hotplug_cpu_mem"
|
||||
VM_METADATA_HOT_REMOVE_NIC = "hot_remove_nic"
|
||||
VM_METADATA_START_VMEM_MB = "start_vmem_mb"
|
||||
VM_METADATA_START_VCPU_COUNT = "start_vcpu_count"
|
||||
VM_METADATA_APP_TAGS = "app_tags"
|
||||
VM_METADATA_CREATE_PARAMS = "create_params"
|
||||
VM_METADATA_LOGIN_ACCOUNT = "login_account"
|
||||
VM_METADATA_LOGIN_KEY = "login_key"
|
||||
VM_METADATA_LAST_LOGIN_KEY = "last_login_key"
|
||||
VM_METADATA_LOGIN_KEY_TIMESTAMP = "login_key_timestamp"
|
||||
VM_METADATA_OS_ARCH = "os_arch"
|
||||
VM_METADATA_OS_DISTRO = "os_distribution"
|
||||
VM_METADATA_OS_NAME = "os_name"
|
||||
VM_METADATA_OS_VERSION = "os_version"
|
||||
VM_METADATA_CGROUP_CPUSET = "cgroup_cpuset"
|
||||
VM_METADATA_ENABLE_MEMCLEAN = "enable_memclean"
|
||||
VM_METADATA_HOTPLUG_CPU_MEM = "hotplug_cpu_mem"
|
||||
VM_METADATA_HOT_REMOVE_NIC = "hot_remove_nic"
|
||||
VM_METADATA_START_VMEM_MB = "start_vmem_mb"
|
||||
VM_METADATA_START_VCPU_COUNT = "start_vcpu_count"
|
||||
VM_METADATA_DISABLE_AUTO_MERGE_SNAPSHOT = "disable_auto_merge_snapshot"
|
||||
|
||||
VM_METADATA_RELEASED_DEVICES = "released_devices"
|
||||
|
||||
|
||||
@@ -36,6 +36,14 @@ type GuestnetworkDetails struct {
|
||||
EipAddr string `json:"eip_addr"`
|
||||
|
||||
NetworkAddresses []NetworkAddrConf `json:"network_addresses"`
|
||||
|
||||
GuestIpMask int8 `json:"guest_ip_mask"`
|
||||
// 网关地址
|
||||
GuestGateway string `json:"guest_gateway"`
|
||||
|
||||
GuestIp6Mask uint8 `json:"guest_ip6_mask"`
|
||||
// 网关地址
|
||||
GuestGateway6 string `json:"guest_gateway6"`
|
||||
}
|
||||
|
||||
type GuestnetworkShortDesc struct {
|
||||
@@ -58,6 +66,8 @@ type GuestnetworkShortDesc struct {
|
||||
SubIps string `json:"sub_ips"`
|
||||
// 端口映射
|
||||
PortMappings GuestPortMappings `json:"port_mappings"`
|
||||
|
||||
IsDefault bool `json:"is_default"`
|
||||
}
|
||||
|
||||
type GuestnetworkListInput struct {
|
||||
@@ -127,6 +137,8 @@ type GuestnetworkBaseDesc struct {
|
||||
Id string `json:"id"`
|
||||
Provider string `json:"provider"`
|
||||
MappedIpAddr string `json:"mapped_ip_addr"`
|
||||
|
||||
MappedIp6Addr string `json:"mapped_ip6_addr"`
|
||||
} `json:"vpc"`
|
||||
|
||||
Networkaddresses jsonutils.JSONObject `json:"networkaddresses"`
|
||||
@@ -180,14 +192,33 @@ type GuestPortMappingPortRange struct {
|
||||
End int `json:"end"`
|
||||
}
|
||||
|
||||
type GuestPortMappingEnvValueFrom string
|
||||
|
||||
const (
|
||||
GuestPortMappingEnvValueFromPort GuestPortMappingEnvValueFrom = "port"
|
||||
GuestPortMappingEnvValueFromHostPort GuestPortMappingEnvValueFrom = "host_port"
|
||||
)
|
||||
|
||||
type GuestPortMappingEnv struct {
|
||||
Key string `json:"key"`
|
||||
ValueFrom GuestPortMappingEnvValueFrom `json:"value_from"`
|
||||
}
|
||||
|
||||
type GuestPortMapping struct {
|
||||
Protocol GuestPortMappingProtocol `json:"protocol"`
|
||||
Protocol GuestPortMappingProtocol `json:"protocol"`
|
||||
// 容器内部 Port 端口范围 1-65535,-1表示由宿主机自动分配和 HostPort 相同的端口
|
||||
Port int `json:"port"`
|
||||
HostPort *int `json:"host_port,omitempty"`
|
||||
HostIp string `json:"host_ip"`
|
||||
HostPortRange *GuestPortMappingPortRange `json:"host_port_range,omitempty"`
|
||||
// whitelist for remote ips
|
||||
RemoteIps []string `json:"remote_ips"`
|
||||
RemoteIps []string `json:"remote_ips"`
|
||||
Rule *GuestPortMappingRule `json:"rule,omitempty"`
|
||||
Envs []GuestPortMappingEnv `json:"envs,omitempty"`
|
||||
}
|
||||
|
||||
type GuestPortMappingRule struct {
|
||||
FirstPortOffset *int `json:"first_port_offset"`
|
||||
}
|
||||
|
||||
type GuestPortMappings []*GuestPortMapping
|
||||
|
||||
@@ -128,8 +128,13 @@ type ServerListInput struct {
|
||||
// 根据镜像发行版排序
|
||||
OrderByOsDist string `json:"order_by_os_dist"`
|
||||
|
||||
SnapshotpolicyId string `json:"snapshotpolicy_id"`
|
||||
|
||||
// 是否调度到宿主机上
|
||||
WithHost *bool `json:"with_host"`
|
||||
|
||||
// 根据是否绑定快照策略过滤
|
||||
BindingSnapshotpolicy *bool `json:"binding_snapshotpolicy"`
|
||||
}
|
||||
|
||||
func (input *ServerListInput) AfterUnmarshal() {
|
||||
@@ -324,6 +329,8 @@ func (self ServerDetails) GetMetricTags() map[string]string {
|
||||
"paltform": self.Hypervisor,
|
||||
"host": self.Host,
|
||||
"host_id": self.HostId,
|
||||
"ips": self.IPs,
|
||||
"vm_ip": self.IPs,
|
||||
"vm_id": self.Id,
|
||||
"vm_name": self.Name,
|
||||
"zone": self.Zone,
|
||||
@@ -377,6 +384,7 @@ type GuestDiskInfo struct {
|
||||
MediumType string `json:"medium_type"`
|
||||
StorageType string `json:"storage_type"`
|
||||
Iops int `json:"iops"`
|
||||
Throughput int `json:"throughput"`
|
||||
Bps int `json:"bps"`
|
||||
ImageId string `json:"image_id,omitempty"`
|
||||
Image string `json:"image,omitemtpy"`
|
||||
@@ -706,6 +714,8 @@ type ServerDetachnetworkInput struct {
|
||||
NetId string `json:"net_id"`
|
||||
// 通过IP解绑网卡, 优先级高于mac
|
||||
IpAddr string `json:"ip_addr"`
|
||||
// 通过IP6 addr解绑网卡, 优先级高于mac
|
||||
Ip6Addr string `json:"ip6_addr"`
|
||||
// 通过Mac解绑网卡, 优先级低于ip_addr
|
||||
Mac string `json:"mac"`
|
||||
// 解绑后不立即同步配置
|
||||
@@ -1192,16 +1202,18 @@ type ServerQgaGuestInfoTaskInput struct {
|
||||
|
||||
type ServerQgaSetNetworkInput struct {
|
||||
ServerQgaTimeoutInput
|
||||
Device string
|
||||
Ipmask string
|
||||
Gateway string
|
||||
Device string
|
||||
Ipmask string
|
||||
Gateway string
|
||||
Ip6mask string
|
||||
Gateway6 string
|
||||
}
|
||||
|
||||
type ServerQgaGetNetworkInput struct {
|
||||
}
|
||||
|
||||
type ServerQgaTimeoutInput struct {
|
||||
// qga execute timeout millisecond
|
||||
// qga execute timeout second
|
||||
Timeout int
|
||||
}
|
||||
|
||||
@@ -1421,3 +1433,8 @@ type ServerChangeBillingTypeInput struct {
|
||||
// required: true
|
||||
BillingType string `json:"billing_type"`
|
||||
}
|
||||
|
||||
type ServerPerformStatusInput struct {
|
||||
apis.PerformStatusInput
|
||||
Containers map[string]*ContainerPerformStatusInput `json:"containers"`
|
||||
}
|
||||
|
||||
@@ -96,6 +96,8 @@ type HostListInput struct {
|
||||
AccessMac []string `json:"access_mac"`
|
||||
// 管理口Ip地址
|
||||
AccessIp []string `json:"access_ip"`
|
||||
// 公网IP地址
|
||||
PublicIp []string `json:"public_ip"`
|
||||
// 物理机序列号信息
|
||||
SN []string `json:"sn"`
|
||||
// CPU大小
|
||||
@@ -163,6 +165,30 @@ type HostListInput struct {
|
||||
// 按内存分配大小排序
|
||||
// enmu: asc,desc
|
||||
OrderByMemCommit string `json:"order_by_mem_commit"`
|
||||
|
||||
// 按物理cpu使用率排序
|
||||
// enmu: asc,desc
|
||||
OrderByCpuUsage string `json:"order_by_cpu_usage"`
|
||||
|
||||
// 按物理内存使用率排序
|
||||
// enmu: asc,desc
|
||||
OrderByMemUsage string `json:"order_by_mem_usage"`
|
||||
|
||||
// 按物理存储使用率排序
|
||||
// enmu: asc,desc
|
||||
OrderByStorageUsage string `json:"order_by_storage_usage"`
|
||||
|
||||
// 按虚拟内存使用率排序
|
||||
// enmu: asc,desc
|
||||
OrderByVirtualMemUsage string `json:"order_by_virtual_mem_usage"`
|
||||
|
||||
// 按虚拟cpu使用率排序
|
||||
// enmu: asc,desc
|
||||
OrderByVirtualCpuUsage string `json:"order_by_virtual_cpu_usage"`
|
||||
|
||||
// 按虚拟存储使用率排序
|
||||
// enmu: asc,desc
|
||||
OrderByVirtualStorageUsage string `json:"order_by_virtual_storage_usage"`
|
||||
}
|
||||
|
||||
type HostDetails struct {
|
||||
@@ -250,6 +276,8 @@ type HostDetails struct {
|
||||
SysWarn string `json:"sys_warn"`
|
||||
// host init error info
|
||||
SysError string `json:"sys_error"`
|
||||
|
||||
HostFiles []string `json:"host_files"`
|
||||
}
|
||||
|
||||
func (self HostDetails) GetMetricTags() map[string]string {
|
||||
@@ -646,6 +674,12 @@ type HostAddNetifInput struct {
|
||||
Reserve *bool `json:"reserve"`
|
||||
|
||||
RequireDesignatedIp *bool `json:"require_designated_ip"`
|
||||
|
||||
Ip6Addr string `json:"ip6_addr"`
|
||||
|
||||
RequireIpv6 *bool `json:"require_ipv6"`
|
||||
|
||||
StrictIpv6 *bool `json:"strict_ipv6"`
|
||||
}
|
||||
|
||||
type HostEnableNetifInput struct {
|
||||
@@ -664,6 +698,12 @@ type HostEnableNetifInput struct {
|
||||
Reserve *bool `json:"reserve"`
|
||||
|
||||
RequireDesignatedIp *bool `json:"require_designated_ip"`
|
||||
|
||||
Ip6Addr string `json:"ip6_addr"`
|
||||
|
||||
RequireIpv6 *bool `json:"require_ipv6"`
|
||||
|
||||
StrictIpv6 *bool `json:"strict_ipv6"`
|
||||
}
|
||||
|
||||
type HostDisableNetifInput struct {
|
||||
@@ -711,13 +751,13 @@ type HostUploadGuestsStatusRequest struct {
|
||||
GuestIds []string `json:"guest_ids"`
|
||||
}
|
||||
|
||||
type HostUploadGuestStatusResponse struct {
|
||||
type HostUploadGuestStatusInput struct {
|
||||
apis.PerformStatusInput
|
||||
Containers map[string]*ContainerPerformStatusInput `json:"containers"`
|
||||
}
|
||||
|
||||
type HostUploadGuestsStatusResponse struct {
|
||||
Guests map[string]*HostUploadGuestStatusResponse `json:"guests"`
|
||||
type HostUploadGuestsStatusInput struct {
|
||||
Guests map[string]*HostUploadGuestStatusInput `json:"guests"`
|
||||
}
|
||||
|
||||
type GuestUploadContainerStatusResponse struct {
|
||||
|
||||
@@ -123,6 +123,11 @@ const (
|
||||
HostResourceTypeDedicated = "dedicated"
|
||||
)
|
||||
|
||||
const (
|
||||
HOST_METADATA_CPU_USAGE_PERCENT = "cpu_usage_percent"
|
||||
HOST_METADATA_MEMORY_USED_MB = "memory_used_mb"
|
||||
)
|
||||
|
||||
var HOST_TYPES = []string{
|
||||
HOST_TYPE_BAREMETAL,
|
||||
HOST_TYPE_HYPERVISOR,
|
||||
|
||||
62
pkg/apis/compute/hostfile.go
Normal file
62
pkg/apis/compute/hostfile.go
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
)
|
||||
|
||||
type HostFileType string
|
||||
|
||||
const (
|
||||
PlainFile HostFileType = "plain"
|
||||
ScriptFile HostFileType = "script"
|
||||
TelegrafConf HostFileType = "telegraf"
|
||||
ApparmorProfile HostFileType = "apparmor"
|
||||
)
|
||||
|
||||
type HostFileCreateInput struct {
|
||||
apis.InfrasResourceBaseCreateInput
|
||||
|
||||
Path string `json:"path" help:"Path of the host file"`
|
||||
Content string `json:"content" help:"Content of the host file"`
|
||||
Type HostFileType `json:"type" help:"Type of the host file"`
|
||||
}
|
||||
|
||||
type HostFileUpdateInput struct {
|
||||
apis.InfrasResourceBaseUpdateInput
|
||||
|
||||
Path string `json:"path"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type HostFileListInput struct {
|
||||
apis.InfrasResourceBaseListInput
|
||||
|
||||
Type []string `json:"type"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
type HostSetHostFilesInput struct {
|
||||
HostFiles []string `json:"host_files"`
|
||||
}
|
||||
|
||||
type HostFileDetails struct {
|
||||
apis.InfrasResourceBaseDetails
|
||||
|
||||
Hosts []string `json:"hosts"`
|
||||
|
||||
SHostFile
|
||||
}
|
||||
@@ -147,6 +147,8 @@ type SnapshotPolicyListInput struct {
|
||||
// 按绑定的磁盘数量排序
|
||||
// pattern:asc|desc
|
||||
OrderByBindDiskCount string `json:"order_by_bind_disk_count"`
|
||||
// 按类型过滤
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type HostnameInput struct {
|
||||
|
||||
@@ -78,6 +78,11 @@ type IsolatedDeviceListInput struct {
|
||||
|
||||
// 列出虚拟机上挂载的设备
|
||||
GuestId string `json:"guest_id"`
|
||||
|
||||
// GPU index
|
||||
Index *int `json:"index"`
|
||||
// Nvidia GPU minor number, parsing from /proc/driver/nvidia/gpus/*/information
|
||||
DeviceMinor *int `json:"device_minor"`
|
||||
}
|
||||
|
||||
type IsolatedDeviceCreateInput struct {
|
||||
@@ -127,7 +132,9 @@ type IsolatedDeviceUpdateInput struct {
|
||||
// PCIE information
|
||||
PCIEInfo *IsolatedDevicePCIEInfo `json:"pcie_info"`
|
||||
// Host device path
|
||||
DevicePath string `json:"device_path"`
|
||||
DevicePath string `json:"device_path"`
|
||||
Index int `json:"index"`
|
||||
DeviceMinor int `json:"device_minor"`
|
||||
}
|
||||
|
||||
type IsolatedDeviceJsonDesc struct {
|
||||
|
||||
@@ -67,6 +67,17 @@ type LoadbalancerListInput struct {
|
||||
UsableLoadbalancerForEip string `json:"usable_loadbalancer_for_eip"`
|
||||
}
|
||||
|
||||
type LbEip struct {
|
||||
// 公网IP地址
|
||||
Eip string `json:"eip"`
|
||||
|
||||
EipId string `json:"eip_id"`
|
||||
|
||||
// 公网IP地址类型: 弹性、非弹性
|
||||
// example: public_ip
|
||||
EipMode string `json:"eip_mode"`
|
||||
}
|
||||
|
||||
type LoadbalancerDetails struct {
|
||||
apis.VirtualResourceDetails
|
||||
|
||||
@@ -82,14 +93,9 @@ type LoadbalancerDetails struct {
|
||||
|
||||
SLoadbalancer
|
||||
|
||||
// 公网IP地址
|
||||
Eip string `json:"eip"`
|
||||
LbEip
|
||||
|
||||
EipId string `json:"eip_id"`
|
||||
|
||||
// 公网IP地址类型: 弹性、非弹性
|
||||
// example: public_ip
|
||||
EipMode string `json:"eip_mode"`
|
||||
Eips []LbEip `json:"eips"`
|
||||
|
||||
// 后端服务器组名称
|
||||
BackendGroup string `json:"backend_group"`
|
||||
|
||||
@@ -381,9 +381,10 @@ var LB_ALIYUN_COMMON_SCHEDULER_TYPES = choices.NewChoices(
|
||||
|
||||
// TODO raw type
|
||||
const (
|
||||
LB_BACKEND_GUEST = compute.LB_BACKEND_GUEST
|
||||
LB_BACKEND_HOST = compute.LB_BACKEND_HOST
|
||||
LB_BACKEND_IP = compute.LB_BACKEND_IP
|
||||
LB_BACKEND_GUEST = compute.LB_BACKEND_GUEST
|
||||
LB_BACKEND_HOST = compute.LB_BACKEND_HOST
|
||||
LB_BACKEND_IP = compute.LB_BACKEND_IP
|
||||
LB_BACKEND_ADDRESS = compute.LB_BACKEND_ADDRESS
|
||||
)
|
||||
|
||||
var LB_BACKEND_TYPES = []string{
|
||||
|
||||
61
pkg/apis/compute/loadbalancer_health_check.go
Normal file
61
pkg/apis/compute/loadbalancer_health_check.go
Normal file
@@ -0,0 +1,61 @@
|
||||
// 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 compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
)
|
||||
|
||||
type LoadbalancerHealthCheckDetails struct {
|
||||
apis.VirtualResourceDetails
|
||||
|
||||
ManagedResourceInfo
|
||||
CloudregionResourceInfo
|
||||
}
|
||||
|
||||
type LoadbalancerHealthCheckListInput struct {
|
||||
apis.VirtualResourceListInput
|
||||
apis.ExternalizedResourceBaseListInput
|
||||
|
||||
ManagedResourceListInput
|
||||
RegionalFilterListInput
|
||||
}
|
||||
|
||||
type SLoadbalancerHealthCheckCreateInput struct {
|
||||
apis.VirtualResourceCreateInput
|
||||
|
||||
CloudregionResourceInput
|
||||
CloudproviderResourceInput
|
||||
|
||||
HealthCheckType string
|
||||
|
||||
HealthCheckDomain string
|
||||
HealthCheckURI string
|
||||
HealthCheckHttpCode string
|
||||
HealthCheckMethod string
|
||||
HealthCheckPort int
|
||||
|
||||
HealthCheckRise int
|
||||
HealthCheckFall int
|
||||
HealthCheckTimeout int
|
||||
HealthCheckInterval int
|
||||
|
||||
HealthCheckReq string
|
||||
HealthCheckExp string
|
||||
}
|
||||
|
||||
type SLoadbalancerHealthCheckUpdateInput struct {
|
||||
apis.VirtualResourceBaseUpdateInput
|
||||
}
|
||||
@@ -14,7 +14,14 @@
|
||||
|
||||
package compute
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/apis"
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/gotypes"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
)
|
||||
|
||||
type LoadbalancerBackendGroupDetails struct {
|
||||
apis.StatusStandaloneResourceDetails
|
||||
@@ -22,6 +29,8 @@ type LoadbalancerBackendGroupDetails struct {
|
||||
|
||||
SLoadbalancerBackendGroup
|
||||
|
||||
LoadbalancerHealthCheck string `json:"loadbalancer_health_check"`
|
||||
|
||||
LbListenerCount int `json:"lb_listener_count"`
|
||||
|
||||
IsDefault bool `json:"is_default"`
|
||||
@@ -62,7 +71,9 @@ type LoadbalancerBackendGroupCreateInput struct {
|
||||
//swagger: ignore
|
||||
Loadbalancer string `json:"loadbalancer" yunion-deprecated-by:"loadbalancer_id"`
|
||||
// 负载均衡ID
|
||||
LoadbalancerId string `json:"loadbalancer_id"`
|
||||
LoadbalancerId string `json:"loadbalancer_id"`
|
||||
Scheduler string `json:"scheduler"`
|
||||
LoadbalancerHealthCheckId string `json:"loadbalancer_health_check_id"`
|
||||
|
||||
Type string `json:"type"`
|
||||
|
||||
@@ -92,3 +103,45 @@ type LoadbalancerBackendGroupListInput struct {
|
||||
|
||||
Type []string `json:"type"`
|
||||
}
|
||||
|
||||
type ListenerRuleBackendGroup struct {
|
||||
// 后端服务器组组ID
|
||||
Id string
|
||||
// swagger:ignore
|
||||
Name string
|
||||
// swagger:ignore
|
||||
ExternalId string
|
||||
}
|
||||
|
||||
type ListenerRuleBackendGroups []ListenerRuleBackendGroup
|
||||
|
||||
func (groups ListenerRuleBackendGroups) String() string {
|
||||
return jsonutils.Marshal(groups).String()
|
||||
}
|
||||
|
||||
func (groups ListenerRuleBackendGroups) IsZero() bool {
|
||||
return len(groups) == 0
|
||||
}
|
||||
|
||||
type ListenerRuleRedirectPool struct {
|
||||
RegionPools map[string]ListenerRuleBackendGroups
|
||||
CountryPools map[string]ListenerRuleBackendGroups
|
||||
}
|
||||
|
||||
func (pool ListenerRuleRedirectPool) String() string {
|
||||
return jsonutils.Marshal(pool).String()
|
||||
}
|
||||
|
||||
func (pool ListenerRuleRedirectPool) IsZero() bool {
|
||||
return len(pool.RegionPools) == 0 && len(pool.CountryPools) == 0
|
||||
}
|
||||
|
||||
func init() {
|
||||
gotypes.RegisterSerializable(reflect.TypeOf(&ListenerRuleBackendGroups{}), func() gotypes.ISerializable {
|
||||
return &ListenerRuleBackendGroups{}
|
||||
})
|
||||
|
||||
gotypes.RegisterSerializable(reflect.TypeOf(&ListenerRuleRedirectPool{}), func() gotypes.ISerializable {
|
||||
return &ListenerRuleRedirectPool{}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ type LoadbalancerListenerRuleDetails struct {
|
||||
LoadbalancerListenerResourceInfo
|
||||
|
||||
SLoadbalancerListenerRule
|
||||
LoadbalancerCertificateResourceInfo
|
||||
|
||||
BackendGroup string `json:"backend_group"`
|
||||
|
||||
@@ -57,9 +58,18 @@ type LoadbalancerListenerRuleCreateInput struct {
|
||||
Listener string `json:"listener" yunion-deprecated-by:"listener_id"`
|
||||
ListenerId string `json:"listener_id"`
|
||||
|
||||
BackendGroup string `json:"backend_group" yunion-deprecated-by:"backend_group_id"`
|
||||
CertificateId string `json:"certificate_id"`
|
||||
|
||||
// swagger:ignore
|
||||
BackendGroup string `json:"backend_group" yunion-deprecated-by:"backend_group_id"`
|
||||
// 默认后端服务器组ID
|
||||
BackendGroupId string `json:"backend_group_id"`
|
||||
|
||||
// 后端服务器组列表
|
||||
BackendGroups ListenerRuleBackendGroups `json:"backend_groups"`
|
||||
|
||||
RedirectPool ListenerRuleRedirectPool `json:"redirect_pool"`
|
||||
|
||||
Domain string `json:"domain"`
|
||||
Path string `json:"path"`
|
||||
HttpRequstRate int `json:"http_request_rate"`
|
||||
|
||||
@@ -117,8 +117,8 @@ type NatgatewayCreateInput struct {
|
||||
// default: false
|
||||
AutoRenew bool `json:"auto_renew"`
|
||||
|
||||
// 到期释放时间,仅后付费支持
|
||||
ExpiredAt time.Time `json:"expired_at"`
|
||||
// 到期释放时间
|
||||
ReleaseAt time.Time `json:"release_at"`
|
||||
|
||||
// 计费方式
|
||||
// enum: ["postpaid", "prepaid"]
|
||||
|
||||
@@ -36,9 +36,10 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
POD_METADATA_CRI_ID = "cri_id"
|
||||
POD_METADATA_CRI_CONFIG = "cri_config"
|
||||
POD_METADATA_PORT_MAPPINGS = "port_mappings"
|
||||
POD_METADATA_CRI_ID = "cri_id"
|
||||
POD_METADATA_CRI_CONFIG = "cri_config"
|
||||
POD_METADATA_PORT_MAPPINGS = "port_mappings"
|
||||
POD_METADATA_POST_STOP_CLEANUP_CONFIG = "post_stop_cleanup_config"
|
||||
)
|
||||
|
||||
type PodContainerCreateInput struct {
|
||||
@@ -164,3 +165,7 @@ func ValidatePodLogOptions(opts *PodLogOptions) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type PodPostStopCleanupConfig struct {
|
||||
Dirs []string `json:"dirs"`
|
||||
}
|
||||
|
||||
@@ -255,6 +255,8 @@ type SecgroupResourceInput struct {
|
||||
|
||||
type SecgroupFilterListInput struct {
|
||||
SecgroupResourceInput
|
||||
RegionalFilterListInput
|
||||
ManagedResourceListInput
|
||||
|
||||
// 以安全组排序
|
||||
OrderBySecgroup string `json:"order_by_secgroup"`
|
||||
@@ -291,6 +293,16 @@ type SecgroupDetails struct {
|
||||
type SecurityGroupResourceInfo struct {
|
||||
// 安全组名称
|
||||
Secgroup string `json:"secgroup"`
|
||||
|
||||
// VPC归属区域ID
|
||||
CloudregionId string `json:"cloudregion_id"`
|
||||
|
||||
CloudregionResourceInfo
|
||||
|
||||
// VPC归属云订阅ID
|
||||
ManagerId string `json:"manager_id"`
|
||||
|
||||
ManagedResourceInfo
|
||||
}
|
||||
|
||||
type GuestsecgroupListInput struct {
|
||||
|
||||
@@ -77,6 +77,9 @@ type SnapshotListInput struct {
|
||||
// 未关联任何磁盘
|
||||
Unused bool `json:"unused"`
|
||||
|
||||
// 按存储过滤
|
||||
StorageId string `json:"storage_id"`
|
||||
|
||||
// 按虚拟机名称排序
|
||||
// pattern:asc|desc
|
||||
OrderByGuest string `json:"order_by_guest"`
|
||||
|
||||
@@ -30,6 +30,9 @@ const (
|
||||
SNAPSHOT_POLICY_APPLY_FAILED = "apply_failed"
|
||||
SNAPSHOT_POLICY_CANCEL = "canceling"
|
||||
SNAPSHOT_POLICY_CANCEL_FAILED = "cancel_failed"
|
||||
|
||||
SNAPSHOT_POLICY_TYPE_DISK = "disk"
|
||||
SNAPSHOT_POLICY_TYPE_SERVER = "server"
|
||||
)
|
||||
|
||||
type SnapshotPolicyDetails struct {
|
||||
@@ -41,7 +44,8 @@ type SnapshotPolicyDetails struct {
|
||||
|
||||
RetentionDays int `json:"retention_days"`
|
||||
|
||||
BindingDiskCount int `json:"binding_disk_count"`
|
||||
BindingDiskCount int `json:"binding_disk_count"`
|
||||
BindingResourceCount int `json:"binding_resource_count"`
|
||||
}
|
||||
|
||||
type SSnapshotPolicyCreateInput struct {
|
||||
@@ -49,7 +53,10 @@ type SSnapshotPolicyCreateInput struct {
|
||||
CloudproviderResourceInput
|
||||
CloudregionResourceInput
|
||||
|
||||
RetentionDays int `json:"retention_days"`
|
||||
RetentionDays int `json:"retention_days"`
|
||||
RetentionCount int `json:"retention_count"`
|
||||
// 快照类型, 目前支持 disk, server
|
||||
Type string `json:"type"`
|
||||
|
||||
RepeatWeekdays []int `json:"repeat_weekdays"`
|
||||
|
||||
@@ -92,7 +99,8 @@ func (self *SSnapshotPolicyCreateInput) Validate() error {
|
||||
type SSnapshotPolicyUpdateInput struct {
|
||||
apis.VirtualResourceBaseUpdateInput
|
||||
|
||||
RetentionDays *int
|
||||
RetentionDays *int
|
||||
RegentionCount *int
|
||||
|
||||
RepeatWeekdays *[]int `json:"repeat_weekdays"`
|
||||
TimePoints *[]int `json:"time_points"`
|
||||
@@ -131,6 +139,13 @@ type SnapshotPolicyDisksInput struct {
|
||||
Disks []string `json:"disk"`
|
||||
}
|
||||
|
||||
type SnapshotPolicyResourcesInput struct {
|
||||
Resources []struct {
|
||||
Id string `json:"id"`
|
||||
Type string `json:"type"`
|
||||
} `json:"resources"`
|
||||
}
|
||||
|
||||
type RepeatWeekdays []int
|
||||
|
||||
func (days RepeatWeekdays) String() string {
|
||||
|
||||
@@ -14,20 +14,42 @@
|
||||
|
||||
package compute
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/apis"
|
||||
import (
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
)
|
||||
|
||||
const (
|
||||
SSL_ISSUER_LETSENCRYPT = cloudprovider.SSL_ISSUER_LETSENCRYPT
|
||||
SSL_ISSUER_ZEROSSL = cloudprovider.SSL_ISSUER_ZEROSSL
|
||||
)
|
||||
|
||||
// 资源创建参数, 目前仅占位
|
||||
type SSLCertificateCreateInput struct {
|
||||
apis.VirtualResourceCreateInput
|
||||
|
||||
Issuer string `json:"issuer"`
|
||||
DnsZoneId string `json:"dns_zone_id"`
|
||||
Sans string `json:"sans"`
|
||||
|
||||
Province string
|
||||
Common string
|
||||
Country string
|
||||
City string
|
||||
OrgName string
|
||||
Certificate string
|
||||
PrivateKey string
|
||||
}
|
||||
|
||||
// 资源返回详情
|
||||
type SSLCertificateDetails struct {
|
||||
apis.VirtualResourceDetails
|
||||
ManagedResourceInfo
|
||||
CloudregionResourceInfo
|
||||
|
||||
// 是否过期
|
||||
IsExpired bool `json:"is_expired"`
|
||||
}
|
||||
|
||||
// 资源列表请求参数
|
||||
type SSLCertificateListInput struct {
|
||||
apis.VirtualResourceListInput
|
||||
apis.ExternalizedResourceBaseListInput
|
||||
@@ -35,4 +57,7 @@ type SSLCertificateListInput struct {
|
||||
|
||||
RegionalFilterListInput
|
||||
ManagedResourceListInput
|
||||
DnsZoneFilterListBase
|
||||
|
||||
IsExpired *bool `json:"is_expired"`
|
||||
}
|
||||
|
||||
@@ -74,6 +74,8 @@ const (
|
||||
STORAGE_CLOUD_BASIC = compute.STORAGE_CLOUD_BASIC
|
||||
STORAGE_CLOUD_PREMIUM = compute.STORAGE_CLOUD_PREMIUM //高性能云硬盘
|
||||
STORAGE_CLOUD_HSSD = compute.STORAGE_CLOUD_HSSD //增强型SSD云硬盘
|
||||
STORAGE_CLOUD_BSSD = compute.STORAGE_CLOUD_BSSD //增强型SSD云硬盘
|
||||
STORAGE_CLOUD_TSSD = compute.STORAGE_CLOUD_TSSD //极速型SSD云硬盘
|
||||
|
||||
// huawei storage type
|
||||
STORAGE_HUAWEI_SSD = compute.STORAGE_HUAWEI_SSD // 超高IO云硬盘
|
||||
|
||||
@@ -168,6 +168,7 @@ type NetworkTopologyOutput struct {
|
||||
|
||||
type HostnetworkTopologyOutput struct {
|
||||
IpAddr string `json:"ip_addr"`
|
||||
Ip6Addr string `json:"ip6_addr"`
|
||||
MacAddr string `json:"mac_addr"`
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ package compute
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
@@ -51,12 +52,22 @@ const (
|
||||
sVpcInterExtIP2 = "100.65.0.2"
|
||||
VpcInterExtMac1 = "ee:ee:ee:ee:ee:f0"
|
||||
VpcInterExtMac2 = "ee:ee:ee:ee:ee:f1"
|
||||
|
||||
sVpcInterCidr6 = "fc00::fffe:100:65:0:0/100"
|
||||
sVpcInterExtCidr6 = "fc00::fffe:100:65:0:0/112"
|
||||
VpcInterExtMask6 = 112
|
||||
sVpcInterExtIP16 = "fc00::fffe:100:65:0:1"
|
||||
sVpcInterExtIP26 = "fc00::fffe:100:65:0:2"
|
||||
)
|
||||
|
||||
var (
|
||||
vpcInterCidr netutils.IPV4Prefix
|
||||
vpcInterExtIP1 netutils.IPV4Addr
|
||||
vpcInterExtIP2 netutils.IPV4Addr
|
||||
|
||||
vpcInterCidr6 netutils.IPV6Prefix
|
||||
vpcInterExtIP16 netutils.IPV6Addr
|
||||
vpcInterExtIP26 netutils.IPV6Addr
|
||||
)
|
||||
|
||||
func VpcInterCidr() netutils.IPV4Prefix {
|
||||
@@ -71,12 +82,28 @@ func VpcInterExtIP2() netutils.IPV4Addr {
|
||||
return vpcInterExtIP2
|
||||
}
|
||||
|
||||
func VpcInterCidr6() netutils.IPV6Prefix {
|
||||
return vpcInterCidr6
|
||||
}
|
||||
|
||||
func VpcInterExtIP16() netutils.IPV6Addr {
|
||||
return vpcInterExtIP16
|
||||
}
|
||||
|
||||
func VpcInterExtIP26() netutils.IPV6Addr {
|
||||
return vpcInterExtIP26
|
||||
}
|
||||
|
||||
const (
|
||||
sVpcMappedCidr = "100.64.0.0/17"
|
||||
VpcMappedIPMask = 17
|
||||
sVpcMappedGatewayIP = "100.64.0.1"
|
||||
VpcMappedGatewayMac = "ee:ee:ee:ee:ee:ee"
|
||||
|
||||
sVpcMappedCidr6 = "fc00::fffe:100:64:0:0/100"
|
||||
VpcMappedIPMask6 = 100
|
||||
sVpcMappedGatewayIP6 = "fc00::fffe:100:64:0:1"
|
||||
|
||||
// reserved: [100.64.0.2, 100.64.0.127]
|
||||
|
||||
// [128, 2176 (128+2048)]
|
||||
@@ -98,18 +125,31 @@ const (
|
||||
sVpcEipGatewayIP = "100.64.128.2"
|
||||
VpcEipGatewayMac = "ee:ee:ee:ee:ee:ef"
|
||||
|
||||
sVpcEipGatewayCidr6 = "fc00::fffe:100:64:f000:0/100"
|
||||
VpcEipGatewayIPMask6 = 100
|
||||
sVpcEipGatewayIP6 = "fc00::fffe:100:64:f000:2"
|
||||
|
||||
sVpcEipGatewayIP3 = "100.64.128.3"
|
||||
VpcEipGatewayMac3 = "ee:ee:ee:ee:ee:f0"
|
||||
|
||||
sVpcEipGatewayIP63 = "fc00::fffe:100:64:f000:3"
|
||||
)
|
||||
|
||||
var (
|
||||
vpcMappedCidr netutils.IPV4Prefix
|
||||
vpcMappedGatewayIP netutils.IPV4Addr
|
||||
|
||||
vpcMappedCidr6 netutils.IPV6Prefix
|
||||
vpcMappedGatewayIP6 netutils.IPV6Addr
|
||||
|
||||
vpcEipGatewayCidr netutils.IPV4Prefix
|
||||
vpcEipGatewayIP netutils.IPV4Addr
|
||||
vpcEipGatewayIP3 netutils.IPV4Addr
|
||||
|
||||
vpcEipGatewayCidr6 netutils.IPV6Prefix
|
||||
vpcEipGatewayIP6 netutils.IPV6Addr
|
||||
vpcEipGatewayIP63 netutils.IPV6Addr
|
||||
|
||||
vpcMappedHostIPStart netutils.IPV4Addr
|
||||
vpcMappedHostIPEnd netutils.IPV4Addr
|
||||
|
||||
@@ -131,17 +171,41 @@ func init() {
|
||||
return v
|
||||
}
|
||||
|
||||
mi6 := func(v netutils.IPV6Addr, err error) netutils.IPV6Addr {
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
return v
|
||||
}
|
||||
mp6 := func(v netutils.IPV6Prefix, err error) netutils.IPV6Prefix {
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
vpcInterCidr = mp(netutils.NewIPV4Prefix(sVpcInterCidr))
|
||||
vpcInterExtIP1 = mi(netutils.NewIPV4Addr(sVpcInterExtIP1))
|
||||
vpcInterExtIP2 = mi(netutils.NewIPV4Addr(sVpcInterExtIP2))
|
||||
|
||||
vpcInterCidr6 = mp6(netutils.NewIPV6Prefix(sVpcInterCidr6))
|
||||
vpcInterExtIP16 = mi6(netutils.NewIPV6Addr(sVpcInterExtIP16))
|
||||
vpcInterExtIP26 = mi6(netutils.NewIPV6Addr(sVpcInterExtIP26))
|
||||
|
||||
vpcMappedCidr = mp(netutils.NewIPV4Prefix(sVpcMappedCidr))
|
||||
vpcMappedGatewayIP = mi(netutils.NewIPV4Addr(sVpcMappedGatewayIP))
|
||||
|
||||
vpcMappedCidr6 = mp6(netutils.NewIPV6Prefix(sVpcMappedCidr6))
|
||||
vpcMappedGatewayIP6 = mi6(netutils.NewIPV6Addr(sVpcMappedGatewayIP6))
|
||||
|
||||
vpcEipGatewayCidr = mp(netutils.NewIPV4Prefix(sVpcEipGatewayCidr))
|
||||
vpcEipGatewayIP = mi(netutils.NewIPV4Addr(sVpcEipGatewayIP))
|
||||
vpcEipGatewayIP3 = mi(netutils.NewIPV4Addr(sVpcEipGatewayIP3))
|
||||
|
||||
vpcEipGatewayCidr6 = mp6(netutils.NewIPV6Prefix(sVpcEipGatewayCidr6))
|
||||
vpcEipGatewayIP6 = mi6(netutils.NewIPV6Addr(sVpcEipGatewayIP6))
|
||||
vpcEipGatewayIP63 = mi6(netutils.NewIPV6Addr(sVpcEipGatewayIP63))
|
||||
|
||||
vpcMappedHostIPStart = mi(netutils.NewIPV4Addr(sVpcMappedHostIPStart))
|
||||
vpcMappedHostIPEnd = mi(netutils.NewIPV4Addr(sVpcMappedHostIPEnd))
|
||||
|
||||
@@ -153,22 +217,42 @@ func VpcMappedCidr() netutils.IPV4Prefix {
|
||||
return vpcMappedCidr
|
||||
}
|
||||
|
||||
func VpcMappedCidr6() netutils.IPV6Prefix {
|
||||
return vpcMappedCidr6
|
||||
}
|
||||
|
||||
func VpcMappedGatewayIP() netutils.IPV4Addr {
|
||||
return vpcMappedGatewayIP
|
||||
}
|
||||
|
||||
func VpcMappedGatewayIP6() netutils.IPV6Addr {
|
||||
return vpcMappedGatewayIP6
|
||||
}
|
||||
|
||||
func VpcEipGatewayCidr() netutils.IPV4Prefix {
|
||||
return vpcEipGatewayCidr
|
||||
}
|
||||
|
||||
func VpcEipGatewayCidr6() netutils.IPV6Prefix {
|
||||
return vpcEipGatewayCidr6
|
||||
}
|
||||
|
||||
func VpcEipGatewayIP() netutils.IPV4Addr {
|
||||
return vpcEipGatewayIP
|
||||
}
|
||||
|
||||
func VpcEipGatewayIP6() netutils.IPV6Addr {
|
||||
return vpcEipGatewayIP6
|
||||
}
|
||||
|
||||
func VpcEipGatewayIP3() netutils.IPV4Addr {
|
||||
return vpcEipGatewayIP3
|
||||
}
|
||||
|
||||
func VpcEipGatewayIP63() netutils.IPV6Addr {
|
||||
return vpcEipGatewayIP63
|
||||
}
|
||||
|
||||
func VpcMappedHostIPStart() netutils.IPV4Addr {
|
||||
return vpcMappedHostIPStart
|
||||
}
|
||||
@@ -188,3 +272,8 @@ func VpcMappedIPEnd() netutils.IPV4Addr {
|
||||
func VpcOvnEncapCostStr() string {
|
||||
return fmt.Sprintf("%d", VPC_OVN_ENCAP_COST)
|
||||
}
|
||||
|
||||
func GenVpcMappedIP6(ip string) string {
|
||||
segs := strings.Split(ip, ".")
|
||||
return fmt.Sprintf("fc00::fffe:100:64:%s:%s", segs[2], segs[3])
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/cloudmux/pkg/cloudprovider"
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
)
|
||||
@@ -32,7 +33,7 @@ const (
|
||||
)
|
||||
|
||||
type WafRuleListInput struct {
|
||||
apis.StatusStandaloneResourceListInput
|
||||
apis.EnabledStatusStandaloneResourceListInput
|
||||
apis.ExternalizedResourceBaseListInput
|
||||
|
||||
// WAF实例Id
|
||||
@@ -40,13 +41,21 @@ type WafRuleListInput struct {
|
||||
|
||||
// WAF规则组Id
|
||||
WafRuleGroupId string `json:"waf_rule_group_id"`
|
||||
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type WafRuleCreateInput struct {
|
||||
apis.StatusStandaloneResourceCreateInput
|
||||
apis.EnabledStatusStandaloneResourceCreateInput
|
||||
|
||||
// WAF实例Id
|
||||
WafInstanceId string `json:"waf_instance_id"`
|
||||
// 规则类型
|
||||
Type string `json:"type"`
|
||||
// 规则表达式
|
||||
Expression string `json:"expression"`
|
||||
// 规则配置
|
||||
Config jsonutils.JSONObject `json:"config"`
|
||||
|
||||
// 优先级,不可重复
|
||||
// Azure优先级范围1-100
|
||||
@@ -65,14 +74,31 @@ type WafRuleCreateInput struct {
|
||||
}
|
||||
|
||||
type WafRuleDetails struct {
|
||||
apis.StatusStandaloneResourceDetails
|
||||
apis.EnabledStatusStandaloneResourceDetails
|
||||
SWafRule
|
||||
|
||||
Statements []cloudprovider.SWafStatement
|
||||
}
|
||||
|
||||
type WafRuleUpdateInput struct {
|
||||
apis.StatusStandaloneResourceBaseUpdateInput
|
||||
apis.EnabledStatusStandaloneResourceBaseUpdateInput
|
||||
// 规则表达式
|
||||
Expression string `json:"expression"`
|
||||
// 规则配置
|
||||
Config jsonutils.JSONObject `json:"config"`
|
||||
// 匹配后默认行为
|
||||
Action *cloudprovider.DefaultAction `json:"action"`
|
||||
// 优先级
|
||||
Priority *int `json:"priority"`
|
||||
|
||||
// 条件表达式
|
||||
Statements []cloudprovider.SWafStatement
|
||||
}
|
||||
|
||||
type WafRuleEnableInput struct {
|
||||
apis.PerformEnableInput
|
||||
}
|
||||
|
||||
type WafRuleDisableInput struct {
|
||||
apis.PerformDisableInput
|
||||
}
|
||||
|
||||
@@ -247,7 +247,6 @@ type SCloudaccount struct {
|
||||
// 云系统信息
|
||||
Sysinfo jsonutils.JSONObject `json:"sysinfo"`
|
||||
// 品牌信息, 一般和provider相同
|
||||
// example: DStack
|
||||
Brand string `json:"brand"`
|
||||
// 额外信息
|
||||
Options *jsonutils.JSONDict `json:"options"`
|
||||
@@ -568,6 +567,8 @@ type SDisk struct {
|
||||
Preallocation string `json:"preallocation"`
|
||||
// # is persistent
|
||||
Nonpersistent bool `json:"nonpersistent"`
|
||||
// auto reset disk after guest shutdown
|
||||
AutoReset bool `json:"auto_reset"`
|
||||
// 是否标记为SSD磁盘
|
||||
IsSsd bool `json:"is_ssd"`
|
||||
// 最大连接数
|
||||
@@ -1014,6 +1015,8 @@ type SGuest struct {
|
||||
VmemSize int `json:"vmem_size"`
|
||||
// CPU 内存绑定信息
|
||||
CpuNumaPin jsonutils.JSONObject `json:"cpu_numa_pin"`
|
||||
// 额外分配的 CPU 数量
|
||||
ExtraCpuCount int `json:"extra_cpu_count"`
|
||||
// 启动顺序
|
||||
BootOrder string `json:"boot_order"`
|
||||
// 关机操作类型
|
||||
@@ -1266,6 +1269,21 @@ type SHostBackupstorage struct {
|
||||
BackupstorageId string `json:"backupstorage_id"`
|
||||
}
|
||||
|
||||
// SHostFile is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SHostFile.
|
||||
type SHostFile struct {
|
||||
apis.SInfrasResourceBase
|
||||
Type string `json:"type"`
|
||||
Path string `json:"path"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// SHostFileJoint is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SHostFileJoint.
|
||||
type SHostFileJoint struct {
|
||||
HostId string `json:"host_id"`
|
||||
HostFileId string `json:"host_file_id"`
|
||||
Deleted bool `json:"deleted"`
|
||||
}
|
||||
|
||||
// SHostJointsBase is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SHostJointsBase.
|
||||
type SHostJointsBase struct {
|
||||
apis.SJointResourceBase
|
||||
@@ -1449,6 +1467,8 @@ type SInterVpcNetworkVpc struct {
|
||||
// SIsolatedDevice is an autogenerated struct via yunion.io/x/onecloud/pkg/compute/models.SIsolatedDevice.
|
||||
type SIsolatedDevice struct {
|
||||
apis.SStandaloneResourceBase
|
||||
apis.SExternalizedResourceBase
|
||||
apis.SSharableBaseResource
|
||||
SHostResourceBase
|
||||
// # PCI / GPU-HPC / GPU-VGA / USB / NIC
|
||||
// 设备类型
|
||||
|
||||
@@ -53,11 +53,16 @@ const (
|
||||
STATUS_SYNC_STATUS = "sync_status"
|
||||
STATUS_DELETING = "deleting"
|
||||
STATUS_DELETE_FAILED = "delete_failed"
|
||||
STATUS_CHANGE_CONFIG = "change_config"
|
||||
STATUS_UNKNOWN = "unknown"
|
||||
STATUS_CREATING = "creating"
|
||||
STATUS_AVAILABLE = "available"
|
||||
STATUS_CREATE_FAILED = "create_failed"
|
||||
|
||||
// 更改计费模式
|
||||
STATUS_CHANGE_BILLING_TYPE = "change_billing_type"
|
||||
STATUS_CHANGE_BILLING_TYPE_FAILED = "change_billing_type_failed"
|
||||
|
||||
CLOUD_TAG_PREFIX = "ext:"
|
||||
USER_TAG_PREFIX = "user:"
|
||||
SYS_CLOUD_TAG_PREFIX = "sys:"
|
||||
@@ -69,7 +74,7 @@ const (
|
||||
SKU_STATUS_AVAILABLE = "available"
|
||||
SKU_STATUS_SOLDOUT = "soldout"
|
||||
|
||||
MetaServiceMonitorAgentUrl = "http://169.254.169.254/monitor"
|
||||
MetaServiceMonitorAgentUrl = "http://%s/monitor"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -86,6 +91,7 @@ var (
|
||||
SERVICE_TYPE_CLOUDEVENT,
|
||||
SERVICE_TYPE_ANSIBLE,
|
||||
SERVICE_TYPE_INFLUXDB,
|
||||
SERVICE_TYPE_VICTORIA_METRICS,
|
||||
SERVICE_TYPE_APIMAP,
|
||||
SERVICE_TYPE_LOG,
|
||||
"autoupdate",
|
||||
@@ -108,6 +114,30 @@ var (
|
||||
SERVICE_TYPE_ETCD,
|
||||
"itsm",
|
||||
SERVICE_TYPE_NTP,
|
||||
"kafka",
|
||||
}
|
||||
|
||||
EXTERNAL_SERVICES = []string{
|
||||
SERVICE_TYPE_OFFLINE_CLOUDMETA,
|
||||
SERVICE_TYPE_CLOUDMETA,
|
||||
SERVICE_TYPE_SCHEDULER,
|
||||
SERVICE_TYPE_VNCPROXY,
|
||||
SERVICE_TYPE_ETCD,
|
||||
SERVICE_TYPE_INFLUXDB,
|
||||
SERVICE_TYPE_INFLUXDB,
|
||||
SERVICE_TYPE_VICTORIA_METRICS,
|
||||
SERVICE_TYPE_LOG,
|
||||
"s3gateway",
|
||||
"common",
|
||||
"websocket",
|
||||
"echarts-ssr",
|
||||
"cloudwatcher",
|
||||
"cloudnet",
|
||||
"repo",
|
||||
SERVICE_TYPE_ETCD,
|
||||
"itsm",
|
||||
SERVICE_TYPE_NTP,
|
||||
"kafka",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -90,8 +90,10 @@ const (
|
||||
)
|
||||
|
||||
type ContainerIsolatedDeviceOnlyEnv struct {
|
||||
Key string `json:"key"`
|
||||
FromRenderPath bool `json:"from_render_path"`
|
||||
Key string `json:"key"`
|
||||
FromRenderPath bool `json:"from_render_path"`
|
||||
FromIndex bool `json:"from_index"`
|
||||
FromDeviceMinor bool `json:"from_device_minor"`
|
||||
}
|
||||
|
||||
type ContainerSpec struct {
|
||||
@@ -275,6 +277,8 @@ type ContainerVolumeMountDiskPostOverlay struct {
|
||||
// 合并后要挂载到容器的目录
|
||||
ContainerTargetDir string `json:"container_target_dir"`
|
||||
Image *ContainerVolumeMountDiskPostImageOverlay `json:"image"`
|
||||
FsUser *int64 `json:"fs_user,omitempty"`
|
||||
FsGroup *int64 `json:"fs_group,omitempty"`
|
||||
}
|
||||
|
||||
func (o ContainerVolumeMountDiskPostOverlay) IsEqual(input ContainerVolumeMountDiskPostOverlay) bool {
|
||||
@@ -320,9 +324,17 @@ const (
|
||||
CONTAINER_VOLUME_MOUNT_HOST_PATH_TYPE_FILE ContainerVolumeMountHostPathType = "file"
|
||||
)
|
||||
|
||||
type ContainerVolumeMountHostPathAutoCreateConfig struct {
|
||||
Uid uint `json:"uid"`
|
||||
Gid uint `json:"gid"`
|
||||
Permissions string `json:"permissions"`
|
||||
}
|
||||
|
||||
type ContainerVolumeMountHostPath struct {
|
||||
Type ContainerVolumeMountHostPathType `json:"type"`
|
||||
Path string `json:"path"`
|
||||
Type ContainerVolumeMountHostPathType `json:"type"`
|
||||
Path string `json:"path"`
|
||||
AutoCreate bool `json:"auto_create"`
|
||||
AutoCreateConfig *ContainerVolumeMountHostPathAutoCreateConfig `json:"auto_create_config,omitempty"`
|
||||
}
|
||||
|
||||
type ContainerVolumeMountText struct {
|
||||
@@ -344,3 +356,9 @@ type ContainerPullImageAuthConfig struct {
|
||||
// RegistryToken is a bearer token to be sent to a registry
|
||||
RegistryToken string `json:"registry_token,omitempty"`
|
||||
}
|
||||
|
||||
type ContainerRootfs struct {
|
||||
Type ContainerVolumeMountType `json:"type"`
|
||||
Disk *ContainerVolumeMountDisk `json:"disk"`
|
||||
//CephFS *ContainerVolumeMountCephFS `json:"ceph_fs"`
|
||||
}
|
||||
|
||||
@@ -41,6 +41,12 @@ type ContainerVolumeMountCephFS struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type ContainerRootfs struct {
|
||||
Type apis.ContainerVolumeMountType `json:"type"`
|
||||
Disk *ContainerVolumeMountDisk `json:"disk"`
|
||||
// CephFS *ContainerVolumeMountCephFS `json:"ceph_fs"`
|
||||
}
|
||||
|
||||
type ContainerVolumeMount struct {
|
||||
// 用于标识当前 pod volume mount 的唯一性
|
||||
UniqueName string `json:"unique_name"`
|
||||
@@ -65,6 +71,7 @@ type ContainerVolumeMount struct {
|
||||
type ContainerSpec struct {
|
||||
apis.ContainerSpec
|
||||
ImageCredentialToken string `json:"image_credential_token"`
|
||||
Rootfs *ContainerRootfs `json:"rootfs"`
|
||||
VolumeMounts []*ContainerVolumeMount `json:"volume_mounts"`
|
||||
Devices []*ContainerDevice `json:"devices"`
|
||||
}
|
||||
@@ -79,13 +86,15 @@ type ContainerDevice struct {
|
||||
}
|
||||
|
||||
type ContainerIsolatedDevice struct {
|
||||
Id string `json:"id"`
|
||||
Addr string `json:"addr"`
|
||||
Path string `json:"path"`
|
||||
DeviceType string `json:"device_type"`
|
||||
CardPath string `json:"card_path"`
|
||||
RenderPath string `json:"render_path"`
|
||||
OnlyEnv []*apis.ContainerIsolatedDeviceOnlyEnv `json:"only_env"`
|
||||
Id string `json:"id"`
|
||||
Addr string `json:"addr"`
|
||||
Path string `json:"path"`
|
||||
DeviceType string `json:"device_type"`
|
||||
CardPath string `json:"card_path"`
|
||||
RenderPath string `json:"render_path"`
|
||||
Index int `json:"index"`
|
||||
DeviceMinor int `json:"device_minor"`
|
||||
OnlyEnv []*apis.ContainerIsolatedDeviceOnlyEnv `json:"only_env"`
|
||||
}
|
||||
|
||||
type ContainerHostDevice struct {
|
||||
@@ -130,6 +139,8 @@ type ContainerSaveVolumeMountToImageInput struct {
|
||||
VolumeMountIndex int `json:"volume_mount_index"`
|
||||
VolumeMount *ContainerVolumeMount `json:"volume_mount"`
|
||||
VolumeMountDirs []string `json:"volume_mount_dirs"`
|
||||
|
||||
VolumeMountPrefix string `json:"volume_mount_prefix"`
|
||||
}
|
||||
|
||||
type ContainerCommitInput struct {
|
||||
|
||||
@@ -119,6 +119,8 @@ var (
|
||||
"platform_names",
|
||||
"enable_change_owner_auto_rename",
|
||||
"default_handlers_whitelist_user_agents",
|
||||
"metadata_server_ip4s",
|
||||
"metadata_server_ip6s",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,13 @@
|
||||
|
||||
package apis
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/pkg/util/billing"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
)
|
||||
|
||||
type DomainizedResourceInput struct {
|
||||
// 指定项目归属域名称或ID
|
||||
@@ -390,8 +396,25 @@ type DistinctFieldsInput struct {
|
||||
}
|
||||
|
||||
type PostpaidExpireInput struct {
|
||||
Duration string `json:"duration"`
|
||||
ExpireTime time.Time `json:"expire_time"`
|
||||
Duration string `json:"duration"`
|
||||
// swagger:ignore
|
||||
ExpireTime time.Time `json:"expire_time" yunion-deprecated-by:"release_at"`
|
||||
// 到期释放时间
|
||||
ReleaseAt time.Time `json:"release_at"`
|
||||
}
|
||||
|
||||
func (input *PostpaidExpireInput) GetReleaseAt() (time.Time, error) {
|
||||
if !input.ReleaseAt.IsZero() {
|
||||
return input.ReleaseAt, nil
|
||||
}
|
||||
if len(input.Duration) == 0 {
|
||||
return time.Time{}, httperrors.NewInputParameterError("missing duration/expire_time")
|
||||
}
|
||||
bc, err := billing.ParseBillingCycle(input.Duration)
|
||||
if err != nil {
|
||||
return time.Time{}, httperrors.NewInputParameterError("invalid duration: %s", input.Duration)
|
||||
}
|
||||
return bc.EndAt(time.Now()), nil
|
||||
}
|
||||
|
||||
type AutoRenewInput struct {
|
||||
|
||||
@@ -14,7 +14,11 @@
|
||||
|
||||
package monitor
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/apis"
|
||||
import (
|
||||
"yunion.io/x/pkg/util/sets"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
)
|
||||
|
||||
const EXT_PREFIX = "ext"
|
||||
|
||||
@@ -59,19 +63,33 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
MetricCloudResTypes = sets.NewString(
|
||||
METRIC_RES_TYPE_HOST,
|
||||
METRIC_RES_TYPE_AGENT,
|
||||
METRIC_RES_TYPE_GUEST,
|
||||
METRIC_RES_TYPE_CONTAINER,
|
||||
METRIC_RES_TYPE_OSS,
|
||||
METRIC_RES_TYPE_RDS,
|
||||
METRIC_RES_TYPE_REDIS,
|
||||
METRIC_RES_TYPE_TENANT,
|
||||
METRIC_RES_TYPE_DOMAIN,
|
||||
METRIC_RES_TYPE_STORAGE,
|
||||
METRIC_RES_TYPE_CLOUDACCOUNT)
|
||||
|
||||
MetricResType = []string{METRIC_RES_TYPE_GUEST, METRIC_RES_TYPE_HOST, METRIC_RES_TYPE_REDIS, METRIC_RES_TYPE_OSS,
|
||||
METRIC_RES_TYPE_RDS, METRIC_RES_TYPE_CLOUDACCOUNT}
|
||||
MetricUnit = []string{METRIC_UNIT_PERCENT, METRIC_UNIT_BPS, METRIC_UNIT_MBPS, METRIC_UNIT_BYTEPS, "count/s",
|
||||
METRIC_UNIT_COUNT, METRIC_UNIT_MS, METRIC_UNIT_BYTE, METRIC_UNIT_NULL}
|
||||
ResTypeScoreMap = map[string]float64{
|
||||
METRIC_RES_TYPE_GUEST: 1,
|
||||
METRIC_RES_TYPE_AGENT: 1.1,
|
||||
METRIC_RES_TYPE_HOST: 2,
|
||||
METRIC_RES_TYPE_OSS: 3,
|
||||
METRIC_RES_TYPE_RDS: 4,
|
||||
METRIC_RES_TYPE_REDIS: 5,
|
||||
METRIC_RES_TYPE_CLOUDACCOUNT: 6,
|
||||
METRIC_RES_TYPE_STORAGE: 7,
|
||||
METRIC_RES_TYPE_HOST: -100,
|
||||
METRIC_RES_TYPE_GUEST: -99,
|
||||
METRIC_RES_TYPE_AGENT: -98,
|
||||
METRIC_RES_TYPE_CONTAINER: -97,
|
||||
METRIC_RES_TYPE_SYSTEM: -96,
|
||||
METRIC_RES_TYPE_K8S: -95,
|
||||
METRIC_RES_TYPE_ELB: -94,
|
||||
METRIC_RES_TYPE_CLOUDACCOUNT: -93,
|
||||
METRIC_RES_TYPE_STORAGE: -93,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -108,6 +108,9 @@ type SimpleQueryInput struct {
|
||||
EndTime time.Time `json:"end_time"`
|
||||
// 指定标签
|
||||
Tags map[string]string `json:"tag_pairs"`
|
||||
// 间隔周期
|
||||
// default: 5m
|
||||
Interval string `json:"interval"`
|
||||
}
|
||||
|
||||
type CdfQueryInput struct {
|
||||
|
||||
@@ -80,7 +80,7 @@ type SAlertPanel struct {
|
||||
type SAlertRecord struct {
|
||||
// db.SVirtualResourceBase
|
||||
apis.SEnabledResourceBase
|
||||
apis.SStatusStandaloneResourceBase
|
||||
apis.SStandaloneAnonResourceBase
|
||||
SMonitorScopedResource
|
||||
AlertId string `json:"alert_id"`
|
||||
Level string `json:"level"`
|
||||
@@ -89,6 +89,7 @@ type SAlertRecord struct {
|
||||
EvalData jsonutils.JSONObject `json:"eval_data"`
|
||||
AlertRule jsonutils.JSONObject `json:"alert_rule"`
|
||||
ResType string `json:"res_type"`
|
||||
ResIds string `json:"res_ids"`
|
||||
}
|
||||
|
||||
// SAlertRecordShield is an autogenerated struct via yunion.io/x/onecloud/pkg/monitor/models.SAlertRecordShield.
|
||||
|
||||
@@ -102,6 +102,8 @@ type NotificationManagerEventNotifyInput struct {
|
||||
// description: direct contact, admin privileges required
|
||||
// required: false
|
||||
Contacts []SContact `json:"contacts"`
|
||||
// 消息机器人列表
|
||||
RobotIds []string `json:"robot_ids"`
|
||||
// description: contact types
|
||||
// required: false
|
||||
// example: email
|
||||
|
||||
@@ -123,16 +123,6 @@ type SNotificationLog struct {
|
||||
SendTimes int `json:"send_times"`
|
||||
}
|
||||
|
||||
// SNotifyAction is an autogenerated struct via yunion.io/x/onecloud/pkg/notify/models.SNotifyAction.
|
||||
type SNotifyAction struct {
|
||||
apis.SEnabledStatusStandaloneResourceBase
|
||||
}
|
||||
|
||||
// SNotifyResource is an autogenerated struct via yunion.io/x/onecloud/pkg/notify/models.SNotifyResource.
|
||||
type SNotifyResource struct {
|
||||
apis.SEnabledStatusStandaloneResourceBase
|
||||
}
|
||||
|
||||
// SReceiver is an autogenerated struct via yunion.io/x/onecloud/pkg/notify/models.SReceiver.
|
||||
type SReceiver struct {
|
||||
apis.SVirtualResourceBase
|
||||
@@ -216,14 +206,14 @@ type STopic struct {
|
||||
|
||||
// STopicAction is an autogenerated struct via yunion.io/x/onecloud/pkg/notify/models.STopicAction.
|
||||
type STopicAction struct {
|
||||
apis.SJointResourceBase
|
||||
apis.SResourceBase
|
||||
ActionId string `json:"action_id"`
|
||||
TopicId string `json:"topic_id"`
|
||||
}
|
||||
|
||||
// STopicResource is an autogenerated struct via yunion.io/x/onecloud/pkg/notify/models.STopicResource.
|
||||
type STopicResource struct {
|
||||
apis.SJointResourceBase
|
||||
apis.SResourceBase
|
||||
ResourceId string `json:"resource_id"`
|
||||
TopicId string `json:"topic_id"`
|
||||
}
|
||||
|
||||
@@ -93,13 +93,13 @@ const (
|
||||
|
||||
var quitHandlerRegisted bool
|
||||
|
||||
func NewApplication(name string, connMax int, db bool) *Application {
|
||||
func NewApplication(name string, connMax int, queueSize int, db bool) *Application {
|
||||
app := Application{name: name,
|
||||
context: ctx.CtxWithTime(),
|
||||
connMax: connMax,
|
||||
session: NewWorkerManager("HttpRequestWorkerManager", connMax, DEFAULT_BACKLOG, db),
|
||||
readSession: NewWorkerManager("HttpGetRequestWorkerManager", connMax, DEFAULT_BACKLOG, db),
|
||||
systemSession: NewWorkerManager("InternalHttpRequestWorkerManager", 1, DEFAULT_BACKLOG, false),
|
||||
session: NewWorkerManager("HttpRequestWorkerManager", connMax, connMax*queueSize, db),
|
||||
readSession: NewWorkerManager("HttpGetRequestWorkerManager", connMax, connMax*queueSize, db),
|
||||
systemSession: NewWorkerManager("InternalHttpRequestWorkerManager", 1, queueSize, false),
|
||||
roots: make(map[string]*RadixNode),
|
||||
rootLock: &sync.RWMutex{},
|
||||
idleTimeout: DEFAULT_IDLE_TIMEOUT,
|
||||
@@ -424,7 +424,7 @@ func (app *Application) defaultHandle(w http.ResponseWriter, r *http.Request, ri
|
||||
task.appParams.Body, _ = jsonutils.Parse(data)
|
||||
r.Body = io.NopCloser(bytes.NewBuffer(data))
|
||||
}
|
||||
session.Run(
|
||||
inqueue := session.Run(
|
||||
task,
|
||||
currentWorker,
|
||||
func(err error) {
|
||||
@@ -432,13 +432,17 @@ func (app *Application) defaultHandle(w http.ResponseWriter, r *http.Request, ri
|
||||
task.fw.closeChannels()
|
||||
},
|
||||
)
|
||||
runErr := task.fw.wait(task.ctx, currentWorker)
|
||||
if runErr != nil {
|
||||
switch je := runErr.(type) {
|
||||
case *httputils.JSONClientError:
|
||||
httperrors.GeneralServerError(task.ctx, w, je)
|
||||
default:
|
||||
httperrors.InternalServerError(task.ctx, w, "Internal server error")
|
||||
if !inqueue {
|
||||
httperrors.TooManyRequestsError(task.ctx, w, "Request queue is full")
|
||||
} else {
|
||||
runErr := task.fw.wait(task.ctx, currentWorker)
|
||||
if runErr != nil {
|
||||
switch je := runErr.(type) {
|
||||
case *httputils.JSONClientError:
|
||||
httperrors.GeneralServerError(task.ctx, w, je)
|
||||
default:
|
||||
httperrors.InternalServerError(task.ctx, w, "Internal server error")
|
||||
}
|
||||
}
|
||||
}
|
||||
task.fw.closeChannels()
|
||||
|
||||
@@ -49,7 +49,7 @@ type ApplicationTestSuit struct {
|
||||
}
|
||||
|
||||
func (suite *ApplicationTestSuit) SetupTest() {
|
||||
suite.app = NewApplication("test", 4, false)
|
||||
suite.app = NewApplication("test", 4, 10, false)
|
||||
suite.app.AddHandler("GET", "/delay", func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
|
||||
time.Sleep(time.Second * 1)
|
||||
Send(w, "delay pong")
|
||||
|
||||
@@ -191,6 +191,12 @@ func NewWorkerManager(name string, workerCount int, backlog int, dbWorker bool)
|
||||
}
|
||||
|
||||
func NewWorkerManagerIgnoreOverflow(name string, workerCount int, backlog int, dbWorker bool, ignoreOverflow bool) *SWorkerManager {
|
||||
if workerCount <= 0 {
|
||||
workerCount = 1
|
||||
}
|
||||
if backlog <= 0 {
|
||||
backlog = 128
|
||||
}
|
||||
manager := SWorkerManager{name: name,
|
||||
queue: NewRing(workerCount * backlog),
|
||||
workerCount: workerCount,
|
||||
|
||||
@@ -1040,20 +1040,22 @@ func (b *SBaremetalInstance) GetIPMINicIPAddr() string {
|
||||
func (b *SBaremetalInstance) GetDHCPConfig(cliMac net.HardwareAddr) (*dhcp.ResponseConfig, error) {
|
||||
var nic *types.SNic
|
||||
var hostname string
|
||||
var osName string
|
||||
if b.GetServer() != nil && (b.GetTask() == nil || !b.GetTask().NeedPXEBoot()) {
|
||||
nic = b.GetServer().GetNicByMac(cliMac)
|
||||
hostname = b.GetServer().GetName()
|
||||
hostname = b.GetServer().GetHostName()
|
||||
osName = b.GetServer().GetOsName()
|
||||
} else {
|
||||
nic = b.GetNicByMac(cliMac)
|
||||
}
|
||||
if nic == nil {
|
||||
return nil, fmt.Errorf("GetNicDHCPConfig no nic found by mac: %s", cliMac)
|
||||
}
|
||||
return b.getDHCPConfig(nic, hostname, false, 0)
|
||||
return b.getDHCPConfig(nic, hostname, false, 0, osName)
|
||||
}
|
||||
|
||||
func (b *SBaremetalInstance) GetPXEDHCPConfig(arch uint16) (*dhcp.ResponseConfig, error) {
|
||||
return b.getDHCPConfig(b.GetAdminNic(), "", true, arch)
|
||||
return b.getDHCPConfig(b.GetAdminNic(), "", true, arch, "Linux")
|
||||
}
|
||||
|
||||
func (b *SBaremetalInstance) getDHCPConfig(
|
||||
@@ -1061,10 +1063,14 @@ func (b *SBaremetalInstance) getDHCPConfig(
|
||||
hostName string,
|
||||
isPxe bool,
|
||||
arch uint16,
|
||||
osName string,
|
||||
) (*dhcp.ResponseConfig, error) {
|
||||
if hostName == "" {
|
||||
hostName = b.GetName()
|
||||
}
|
||||
if osName == "" {
|
||||
osName = "Linux"
|
||||
}
|
||||
serverIP, err := b.manager.Agent.GetDHCPServerIP()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1078,7 +1084,7 @@ func (b *SBaremetalInstance) getDHCPConfig(
|
||||
return nil, errors.Errorf("Baremetal %s not need UEFI PXE boot", b.GetName())
|
||||
}
|
||||
}
|
||||
return GetNicDHCPConfig(nic, serverIP.String(), hostName, isPxe, arch)
|
||||
return GetNicDHCPConfig(nic, serverIP, b.manager.Agent.ListenInterface.HardwareAddr, hostName, isPxe, arch, osName)
|
||||
}
|
||||
|
||||
func (b *SBaremetalInstance) GetNotifyUrl() string {
|
||||
@@ -2550,6 +2556,22 @@ func (server *SBaremetalServer) GetName() string {
|
||||
return id
|
||||
}
|
||||
|
||||
func (server *SBaremetalServer) GetHostName() string {
|
||||
hostname, err := server.desc.GetString("hostname")
|
||||
if err != nil {
|
||||
log.Errorf("Get hostname from desc %s error: %v", server.desc.String(), err)
|
||||
}
|
||||
return hostname
|
||||
}
|
||||
|
||||
func (server *SBaremetalServer) GetOsName() string {
|
||||
osName, err := server.desc.GetString("os_name")
|
||||
if err != nil {
|
||||
log.Errorf("Get os name from desc %s error: %v", server.desc.String(), err)
|
||||
}
|
||||
return osName
|
||||
}
|
||||
|
||||
func (server *SBaremetalServer) SaveDesc(desc jsonutils.JSONObject) error {
|
||||
if desc != nil {
|
||||
server.desc = desc.(*jsonutils.JSONDict)
|
||||
|
||||
@@ -15,84 +15,155 @@
|
||||
package baremetal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
|
||||
o "yunion.io/x/onecloud/pkg/baremetal/options"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/types"
|
||||
"yunion.io/x/onecloud/pkg/util/dhcp"
|
||||
"yunion.io/x/onecloud/pkg/util/netutils2"
|
||||
)
|
||||
|
||||
func GetNicDHCPConfig(
|
||||
n *types.SNic,
|
||||
serverIP string,
|
||||
serverIP net.IP,
|
||||
serverMac net.HardwareAddr,
|
||||
hostName string,
|
||||
isPxe bool,
|
||||
arch uint16,
|
||||
osName string,
|
||||
) (*dhcp.ResponseConfig, error) {
|
||||
if n == nil {
|
||||
return nil, fmt.Errorf("Nic is nil")
|
||||
return nil, errors.Wrap(errors.ErrEmpty, "Nic is nil")
|
||||
}
|
||||
if n.IpAddr == "" {
|
||||
return nil, fmt.Errorf("Nic no ip address")
|
||||
}
|
||||
ipAddr, err := netutils.NewIPV4Addr(n.IpAddr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Parse IP address error: %q", n.IpAddr)
|
||||
if n.IpAddr == "" && n.Ip6Addr == "" {
|
||||
return nil, errors.Wrap(errors.ErrEmpty, "Nic no ip or ip6 address")
|
||||
}
|
||||
|
||||
subnetMask := net.ParseIP(netutils.Masklen2Mask(n.Masklen).String())
|
||||
|
||||
routes := make([][]string, 0)
|
||||
routes4 := make([]netutils2.SRouteInfo, 0)
|
||||
routes6 := make([]netutils2.SRouteInfo, 0)
|
||||
for _, route := range n.Routes {
|
||||
routes = append(routes, []string{route[0], route[1]})
|
||||
routeInfo, err := netutils2.ParseRouteInfo([]string{route[0], route[1]})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Parse route %s error: %q", route, err)
|
||||
}
|
||||
if regutils.MatchCIDR6(route[0]) {
|
||||
routes6 = append(routes6, *routeInfo)
|
||||
} else {
|
||||
routes4 = append(routes4, *routeInfo)
|
||||
}
|
||||
}
|
||||
|
||||
parseIPs := func(ips string) []net.IP {
|
||||
ret := make([]net.IP, 0)
|
||||
iplist := strings.Split(ips, ",")
|
||||
for _, ip := range iplist {
|
||||
ret = append(ret, net.ParseIP(ip))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
isDefaultGW := false
|
||||
if n.IsDefault == nil || *n.IsDefault {
|
||||
isDefaultGW = true
|
||||
|
||||
parseDomains := func(domains string) []net.IP {
|
||||
ret := make([]net.IP, 0)
|
||||
domainlist := strings.Split(domains, ",")
|
||||
for _, domain := range domainlist {
|
||||
addrs, _ := net.LookupHost(domain)
|
||||
for _, addr := range addrs {
|
||||
ret = append(ret, net.ParseIP(addr))
|
||||
}
|
||||
if n.Gateway != "" && !strings.HasPrefix(strings.ToLower(osName), "win") {
|
||||
routes4 = append(routes4, netutils2.SRouteInfo{
|
||||
SPrefixInfo: netutils2.SPrefixInfo{
|
||||
Prefix: net.ParseIP("0.0.0.0"),
|
||||
PrefixLen: 0,
|
||||
},
|
||||
Gateway: net.ParseIP(n.Gateway),
|
||||
})
|
||||
}
|
||||
if n.Gateway6 != "" {
|
||||
routes6 = append(routes6, netutils2.SRouteInfo{
|
||||
SPrefixInfo: netutils2.SPrefixInfo{
|
||||
Prefix: net.ParseIP("::"),
|
||||
PrefixLen: 0,
|
||||
},
|
||||
Gateway: net.ParseIP(n.Gateway6),
|
||||
})
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
conf := &dhcp.ResponseConfig{
|
||||
ServerIP: net.ParseIP(serverIP),
|
||||
ClientIP: net.ParseIP(ipAddr.String()),
|
||||
Gateway: net.ParseIP(n.Gateway),
|
||||
SubnetMask: subnetMask,
|
||||
BroadcastAddr: net.ParseIP(ipAddr.BroadcastAddr(n.Masklen).String()),
|
||||
DNSServers: parseIPs(n.Dns),
|
||||
NTPServers: parseDomains(n.Ntp),
|
||||
Domain: n.Domain,
|
||||
OsName: "Linux",
|
||||
Hostname: hostName,
|
||||
Routes: routes,
|
||||
LeaseTime: time.Duration(o.Options.DhcpLeaseTime) * time.Second,
|
||||
RenewalTime: time.Duration(o.Options.DhcpRenewalTime) * time.Second,
|
||||
InterfaceMac: serverMac,
|
||||
VlanId: uint16(n.VlanId),
|
||||
|
||||
ServerIP: serverIP,
|
||||
Domain: n.Domain,
|
||||
OsName: osName,
|
||||
Hostname: strings.ToLower(hostName),
|
||||
Routes: routes4,
|
||||
Routes6: routes6,
|
||||
LeaseTime: time.Duration(o.Options.DhcpLeaseTime) * time.Second,
|
||||
RenewalTime: time.Duration(o.Options.DhcpRenewalTime) * time.Second,
|
||||
|
||||
IsDefaultGW: isDefaultGW,
|
||||
}
|
||||
|
||||
if n.IpAddr != "" {
|
||||
ipAddr, err := netutils.NewIPV4Addr(n.IpAddr)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Parse IP address error: %q", n.IpAddr)
|
||||
}
|
||||
|
||||
subnetMask := net.ParseIP(netutils.Masklen2Mask(n.Masklen).String())
|
||||
|
||||
conf.ClientIP = net.ParseIP(ipAddr.String())
|
||||
conf.SubnetMask = subnetMask
|
||||
conf.BroadcastAddr = net.ParseIP(ipAddr.BroadcastAddr(n.Masklen).String())
|
||||
conf.Gateway = net.ParseIP(n.Gateway)
|
||||
}
|
||||
if n.Ip6Addr != "" {
|
||||
ip6Addr, err := netutils.NewIPV6Addr(n.Ip6Addr)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Parse IPv6 address error: %q", n.Ip6Addr)
|
||||
}
|
||||
|
||||
conf.ClientIP6 = net.ParseIP(ip6Addr.String())
|
||||
conf.PrefixLen6 = n.Masklen6
|
||||
conf.Gateway6 = net.ParseIP(n.Gateway6)
|
||||
}
|
||||
|
||||
if len(n.Dns) > 0 {
|
||||
conf.DNSServers = make([]net.IP, 0)
|
||||
conf.DNSServers6 = make([]net.IP, 0)
|
||||
for _, dns := range strings.Split(n.Dns, ",") {
|
||||
if regutils.MatchIP4Addr(dns) {
|
||||
conf.DNSServers = append(conf.DNSServers, net.ParseIP(dns))
|
||||
} else if regutils.MatchIP6Addr(dns) {
|
||||
conf.DNSServers6 = append(conf.DNSServers6, net.ParseIP(dns))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(n.Ntp) > 0 {
|
||||
conf.NTPServers = make([]net.IP, 0)
|
||||
conf.NTPServers6 = make([]net.IP, 0)
|
||||
for _, ntp := range strings.Split(n.Ntp, ",") {
|
||||
if regutils.MatchIP4Addr(ntp) {
|
||||
conf.NTPServers = append(conf.NTPServers, net.ParseIP(ntp))
|
||||
} else if regutils.MatchIP6Addr(ntp) {
|
||||
conf.NTPServers6 = append(conf.NTPServers6, net.ParseIP(ntp))
|
||||
} else if regutils.MatchDomainName(ntp) {
|
||||
ntpAddrs, _ := net.LookupHost(ntp)
|
||||
for _, ntpAddr := range ntpAddrs {
|
||||
if regutils.MatchIP4Addr(ntpAddr) {
|
||||
conf.NTPServers = append(conf.NTPServers, net.ParseIP(ntpAddr))
|
||||
} else if regutils.MatchIP6Addr(ntpAddr) {
|
||||
conf.NTPServers6 = append(conf.NTPServers6, net.ParseIP(ntpAddr))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if n.Mtu > 0 {
|
||||
conf.MTU = uint16(n.Mtu)
|
||||
}
|
||||
|
||||
if isPxe {
|
||||
conf.BootServer = serverIP
|
||||
conf.BootServer = serverIP.String()
|
||||
if len(o.Options.TftpBootServer) > 0 {
|
||||
conf.BootServer = o.Options.TftpBootServer
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
"yunion.io/x/onecloud/pkg/util/ctx"
|
||||
"yunion.io/x/onecloud/pkg/util/dhcp"
|
||||
)
|
||||
|
||||
@@ -70,7 +71,7 @@ type dhcpRequest struct {
|
||||
netConfig *types.SNetworkConfig
|
||||
}
|
||||
|
||||
func (h *DHCPHandler) ServeDHCP(ctx context.Context, pkt dhcp.Packet, _ *net.UDPAddr, _ *net.Interface) (dhcp.Packet, []string, error) {
|
||||
func (h *DHCPHandler) ServeDHCP(pkt dhcp.Packet, _ net.HardwareAddr, _ *net.UDPAddr) (dhcp.Packet, []string, error) {
|
||||
req, err := h.newRequest(pkt, h.baremetalManager)
|
||||
if err != nil {
|
||||
log.Errorf("[DHCP] new request by packet error: %v", err)
|
||||
@@ -82,7 +83,7 @@ func (h *DHCPHandler) ServeDHCP(ctx context.Context, pkt dhcp.Packet, _ *net.UDP
|
||||
return nil, nil, fmt.Errorf("Request not from a DHCP relay, ignore mac: %s", req.ClientMac)
|
||||
}
|
||||
log.Infof("[DHCP] from relay %s packet, mac: %s", req.RelayAddr, req.ClientMac)
|
||||
conf, targets, err := req.fetchConfig(ctx, h.baremetalManager.GetClientSession())
|
||||
conf, targets, err := req.fetchConfig(ctx.CtxWithTime(), h.baremetalManager.GetClientSession())
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "fetchConfig for %s", req.ClientMac.String())
|
||||
}
|
||||
|
||||
@@ -41,4 +41,7 @@ type IBaremetalServer interface {
|
||||
GetNicByMac(mac net.HardwareAddr) *types.SNic
|
||||
|
||||
GetRootTemplateId() string
|
||||
|
||||
GetHostName() string
|
||||
GetOsName() string
|
||||
}
|
||||
|
||||
@@ -40,7 +40,13 @@ menuentry 'YunionOS for PXE' --class os {
|
||||
`, sleepTime, kernel, kernel, kernelArgs, initrd, initrd)
|
||||
}
|
||||
|
||||
// REF: https://github.com/bluebanquise/infrastructure/blob/master/packages/ipxe-bluebanquise/grub2-efi-autofind.cfg
|
||||
var (
|
||||
BOOT_EFI_MATCHER = "(hd*,gpt*)/EFI/BOOT/BOOTX64.EFI (hd*,msdos*)/EFI/BOOT/BOOTX64.EFI (hd*,gpt*)/EFI/BOOT/BOOTAA64.EFI (hd*,msdos*)/EFI/BOOT/BOOTAA64.EFI"
|
||||
GRUB_EFI_MATCHER = "(md*)/EFI/*/shimx64.efi (md*)/EFI/*/grubx64.efi (hd*,gpt*)/EFI/*/shimx64.efi (hd*,msdos*)/EFI/*/shimx64.efi (hd*,gpt*)/EFI/*/grubx64.efi (hd*,mosdos*)/EFI/*/grubx64.efi (hd*,gpt*)/EFI/*/shimaa64.efi (hd*,msdos*)/EFI/*/shimaa64.efi (hd*,gpt*)/EFI/*/grubaa64.efi (hd*,mosdos*)/EFI/*/grubaa64.efi"
|
||||
GRUB_CFG_MATCHER = "(md*)/boot/*/grub.cfg (md*)/*/grub.cfg (md*)/grub.cfg (md*)/EFI/*/grub.cfg (md*)/EFI/*/*/grub.cfg (hd*,gpt*)/boot/*/grub.cfg (hd*,gpt*)/*/grub.cfg (hd*,gpt*)/grub.cfg (hd*,gpt*)/EFI/*/grub.cfg (hd*,gpt*)/EFI/*/*/grub.cfg (hd*,mosdos*)/boot/*/grub.cfg (hd*,mosdos*)/*/grub.cfg (hd*,mosdos*)/grub.cfg (hd*,mosdos*)/EFI/*/grub.cfg (hd*,mosdos*)/EFI/*/*/grub.cfg"
|
||||
)
|
||||
|
||||
// REF: https://github.com/bluebanquise/infrastructure/blob/master/packages/bluebanquise-ipxe/grub2-efi-autofind.cfg
|
||||
const autoFindCfg = `
|
||||
echo "Loading modules..."
|
||||
insmod part_gpt
|
||||
@@ -48,34 +54,114 @@ insmod fat
|
||||
insmod chain
|
||||
insmod part_msdos
|
||||
insmod ext2
|
||||
insmod regexp
|
||||
insmod xfs
|
||||
insmod mdraid1x
|
||||
insmod mdraid09
|
||||
|
||||
echo
|
||||
echo "Scanning, first pass..."
|
||||
for cfg in (*,gpt*)/efi/*/grub.cfg (*,gpt*)/efi/*/*/grub.cfg (*,gpt*)/grub.cfg (*,gpt*)/*/grub.cfg (*,gpt*)/*/*/grub.cfg (*,msdos*)/grub.cfg (*,msdos*)/*/grub.cfg (*,mosdos*)/*/*/grub.cfg; do
|
||||
regexp --set=1:cfg_device '^\((.*)\)/' "${cfg}"
|
||||
echo "======================= lsmod ======================================="
|
||||
lsmod
|
||||
|
||||
echo
|
||||
echo "======================= devices ====================================="
|
||||
ls
|
||||
|
||||
echo
|
||||
echo "======================= Searching for the BOOT EFI executable ======="
|
||||
echo "Scanning, 1st pass"
|
||||
for efi in %s; do
|
||||
regexp --set=1:root '^\(([^)]+)\)/' "${efi}"
|
||||
echo "- Scanning: $efi"
|
||||
if [ -e "$efi" ] ; then
|
||||
echo " Found: $efi"
|
||||
else
|
||||
echo " $efi does not exist"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Scanning, second pass..."
|
||||
for cfg in (*,gpt*)/efi/*/grub.cfg (*,gpt*)/efi/*/*/grub.cfg (*,gpt*)/grub.cfg (*,gpt*)/*/grub.cfg (*,gpt*)/*/*/grub.cfg (*,msdos*)/grub.cfg (*,msdos*)/*/grub.cfg (*,mosdos*)/*/*/grub.cfg; do
|
||||
regexp --set=1:cfg_device '^\((.*)\)/' "${cfg}"
|
||||
echo "Try configfile ${cfg}"
|
||||
if [ -e "${cfg}" ]; then
|
||||
cfg_found=true
|
||||
echo " >> Found operating system grub config! <<"
|
||||
echo " Path: ${cfg}"
|
||||
echo " Booting in 5s..."
|
||||
sleep --interruptible --verbose 5
|
||||
configfile "${cfg}"
|
||||
echo
|
||||
echo "Scanning, 2nd pass..."
|
||||
for efi in %s; do
|
||||
echo "- Scanning: $efi"
|
||||
if [ -e "$efi" ] ; then
|
||||
regexp --set 1:root '^\(([^)]+)\)/' "${efi}"
|
||||
echo " Found: $efi"
|
||||
echo " Root: $root"
|
||||
echo " Chainloading $efi"
|
||||
chainloader "$efi"
|
||||
boot
|
||||
fi
|
||||
done
|
||||
|
||||
echo "No grub.cfg known OS found. Fall back on shell after 5s."
|
||||
sleep 5s
|
||||
echo
|
||||
echo " Found no BOOT EFI executable. Falling back to shell..."
|
||||
|
||||
echo
|
||||
echo "======================= Searching for Grub EFI executables =========="
|
||||
echo "Scanning, 1st pass"
|
||||
for efi in %s ; do
|
||||
regexp --set=1:root '^\(([^)]+)\)/' "${efi}"
|
||||
echo "- Scanning: $efi"
|
||||
if [ -e "$efi" ] ; then
|
||||
echo " Found: $efi"
|
||||
else
|
||||
echo " $efi does not exist"
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
echo "Scanning, 2nd pass..."
|
||||
for efi in %s ; do
|
||||
echo "- Scanning: $efi"
|
||||
if [ -e "$efi" ] ; then
|
||||
regexp --set 1:root '^\(([^)]+)\)/' "${efi}"
|
||||
echo " Found: $efi"
|
||||
echo " Root: $root"
|
||||
echo " Chainloading $efi"
|
||||
chainloader "$efi"
|
||||
boot
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
echo " Found no Grub EFI executable to load an OS."
|
||||
|
||||
echo
|
||||
echo "======================= Searching for grub.cfg on local disks ======="
|
||||
echo "Scanning, 1st pass..."
|
||||
for grubcfg in %s ; do
|
||||
regexp --set=1:root '^\(([^)]+)\)/' "${grubcfg}"
|
||||
if [ -e "$grubcfg" ] ; then
|
||||
echo " Found: $grubcfg"
|
||||
else
|
||||
echo " $grubcfg does not exist"
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
echo "Scanning, 2nd pass..."
|
||||
for grubcfg in %s ; do
|
||||
echo "- Scanning: $grubcfg"
|
||||
if [ -e "${grubcfg}" ]; then
|
||||
regexp --set=1:root '^\(([^)]+)\)/' "${grubcfg}"
|
||||
echo " Found: $grubcfg"
|
||||
echo " Root: $root"
|
||||
# echo " Contents:"
|
||||
# cat "$grubcfg"
|
||||
configfile "${grubcfg}"
|
||||
boot
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
echo " Found no grub.cfg configuration file to load."
|
||||
|
||||
sleep 4s
|
||||
`
|
||||
|
||||
func GetAutoFindConfig() string {
|
||||
return autoFindCfg
|
||||
return fmt.Sprintf(autoFindCfg, BOOT_EFI_MATCHER, BOOT_EFI_MATCHER, GRUB_EFI_MATCHER, GRUB_EFI_MATCHER, GRUB_CFG_MATCHER, GRUB_CFG_MATCHER)
|
||||
}
|
||||
|
||||
// REF: https://archived.forum.manjaro.org/t/detecting-efi-files-and-booting-them-from-grub/38083
|
||||
|
||||
@@ -445,13 +445,13 @@ func (adapter *MegaRaidAdaptor) GetDevices() []*baremetal.BaremetalStorage {
|
||||
|
||||
func (adapter *MegaRaidAdaptor) GetLogicVolumes() ([]*raiddrivers.RaidLogicalVolume, error) {
|
||||
errs := make([]error, 0)
|
||||
megaLvs, err := adapter.getMegacliLogicVolumes()
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
megaLvs, megacliErr := adapter.getMegacliLogicVolumes()
|
||||
if megacliErr != nil {
|
||||
errs = append(errs, megacliErr)
|
||||
}
|
||||
storeLvs, err := adapter.getStorcliLogicVolums()
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
storeLvs, storcliErr := adapter.getStorcliLogicVolums()
|
||||
if storcliErr != nil {
|
||||
errs = append(errs, storcliErr)
|
||||
}
|
||||
if len(megaLvs) > 0 {
|
||||
return megaLvs, nil
|
||||
@@ -459,7 +459,7 @@ func (adapter *MegaRaidAdaptor) GetLogicVolumes() ([]*raiddrivers.RaidLogicalVol
|
||||
if len(storeLvs) > 0 {
|
||||
return storeLvs, nil
|
||||
}
|
||||
if len(errs) == 0 {
|
||||
if len(errs) == 0 || megacliErr == nil || storcliErr == nil {
|
||||
// no error, no volume
|
||||
return []*raiddrivers.RaidLogicalVolume{}, nil
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/workmanager"
|
||||
"yunion.io/x/onecloud/pkg/hostman/hostutils"
|
||||
@@ -48,12 +49,13 @@ func performImageCache(
|
||||
) {
|
||||
_, _, body := appsrv.FetchEnv(ctx, w, r)
|
||||
|
||||
disk, err := body.Get("disk")
|
||||
input := compute.CacheImageInput{}
|
||||
err := body.Unmarshal(&input, "disk")
|
||||
if err != nil {
|
||||
httperrors.MissingParameterError(ctx, w, "disk")
|
||||
httperrors.BadRequestError(ctx, w, "unmarshal disk %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
hostutils.DelayImageCacheTask(ctx, performTask, disk)
|
||||
hostutils.DelayImageCacheTask(ctx, performTask, input)
|
||||
hostutils.ResponseOk(ctx, w)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
func InitApp(options *common_options.BaseOptions, dbAccess bool) *appsrv.Application {
|
||||
// cache := appsrv.NewCache(options.AuthTokenCacheSize)
|
||||
log.Infof("RequestWorkerCount: %d", options.RequestWorkerCount)
|
||||
app := appsrv.NewApplication(options.ApplicationID, options.RequestWorkerCount, dbAccess)
|
||||
app := appsrv.NewApplication(options.ApplicationID, options.RequestWorkerCount, options.RequestWorkerQueueSize, dbAccess)
|
||||
app.CORSAllowHosts(options.CorsHosts)
|
||||
app.SetDefaultTimeout(time.Duration(options.DefaultProcessTimeoutSeconds) * time.Second)
|
||||
// app.SetContext(appsrv.APP_CONTEXT_KEY_CACHE, cache)
|
||||
|
||||
@@ -336,6 +336,9 @@ func ParseNetworkConfig(desc string, idx int) (*compute.NetworkConfig, error) {
|
||||
netConfig.IsDefault = true
|
||||
} else if p == "ipv6" {
|
||||
netConfig.RequireIPv6 = true
|
||||
} else if p == "strict-ipv6" {
|
||||
netConfig.RequireIPv6 = true
|
||||
netConfig.StrictIPv6 = true
|
||||
} else if strings.HasPrefix(p, "standby-port=") {
|
||||
netConfig.StandbyPortCount, _ = strconv.Atoi(p[len("standby-port="):])
|
||||
} else if strings.HasPrefix(p, "standby-addr=") {
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/identity"
|
||||
"yunion.io/x/onecloud/pkg/util/ctx"
|
||||
)
|
||||
|
||||
type tenantCacheSyncWorker struct {
|
||||
@@ -34,7 +35,7 @@ type tenantCacheSyncWorker struct {
|
||||
|
||||
func (w *tenantCacheSyncWorker) Run() {
|
||||
log.Debugf("[tenantCacheSyncWorker] Run project cache sync worker ...")
|
||||
err := syncProjects(context.Background(), w.ids)
|
||||
err := syncProjects(ctx.CtxWithTime(), w.ids)
|
||||
if err != nil {
|
||||
log.Errorf("fail to syncProjects %s", err)
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
modules "yunion.io/x/onecloud/pkg/mcclient/modules/identity"
|
||||
"yunion.io/x/onecloud/pkg/util/ctx"
|
||||
)
|
||||
|
||||
type userCacheSyncWorker struct {
|
||||
@@ -34,7 +35,7 @@ type userCacheSyncWorker struct {
|
||||
|
||||
func (w *userCacheSyncWorker) Run() {
|
||||
log.Debugf("[userCacheSyncWorker] Run project cache sync worker ...")
|
||||
err := syncUsers(context.Background(), w.ids)
|
||||
err := syncUsers(ctx.CtxWithTime(), w.ids)
|
||||
if err != nil {
|
||||
log.Errorf("fail to syncUsers %s", err)
|
||||
}
|
||||
|
||||
@@ -281,6 +281,11 @@ func listItemQueryFiltersRaw(
|
||||
}
|
||||
}
|
||||
|
||||
q, err = ListItemFilter(manager, ctx, q, userCred, query)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "ListItemFilter")
|
||||
}
|
||||
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
// TURN ON automatic filter by column name, ONLY if query key starts with @!!!!
|
||||
// example: @name=abc&@city=111
|
||||
@@ -312,10 +317,6 @@ func listItemQueryFiltersRaw(
|
||||
return nil, errors.Wrap(err, "applyListItemsGeneralJointFilters")
|
||||
}
|
||||
}
|
||||
q, err = ListItemFilter(manager, ctx, q, userCred, query)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "ListItemFilter")
|
||||
}
|
||||
|
||||
if !useRawQuery {
|
||||
// Specifically for joint resource, these filters will exclude
|
||||
|
||||
@@ -19,10 +19,12 @@ import (
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
|
||||
"github.com/petermattis/goid"
|
||||
|
||||
"yunion.io/x/log"
|
||||
)
|
||||
|
||||
const (
|
||||
var (
|
||||
debug_log = false
|
||||
)
|
||||
|
||||
@@ -34,15 +36,15 @@ type SInMemoryLockRecord struct {
|
||||
key string
|
||||
lock *sync.Mutex
|
||||
cond *sync.Cond
|
||||
holder context.Context
|
||||
holder int64
|
||||
depth int
|
||||
waiter *FIFO
|
||||
}
|
||||
|
||||
func newInMemoryLockRecord(ctx context.Context) *SInMemoryLockRecord {
|
||||
func newInMemoryLockRecord(ctxDummy context.Context) *SInMemoryLockRecord {
|
||||
lock := &sync.Mutex{}
|
||||
cond := sync.NewCond(lock)
|
||||
rec := SInMemoryLockRecord{lock: lock, cond: cond, holder: ctx, depth: 0, waiter: NewFIFO()}
|
||||
rec := SInMemoryLockRecord{lock: lock, cond: cond, holder: -1, depth: 0, waiter: NewFIFO()}
|
||||
return &rec
|
||||
}
|
||||
|
||||
@@ -51,24 +53,29 @@ func (rec *SInMemoryLockRecord) fatalf(fmtStr string, args ...interface{}) {
|
||||
log.Fatalf(fmtStr, args...)
|
||||
}
|
||||
|
||||
func (rec *SInMemoryLockRecord) lockContext(ctx context.Context) {
|
||||
func (rec *SInMemoryLockRecord) lockContext(ctxDummy context.Context) {
|
||||
rec.lock.Lock()
|
||||
defer rec.lock.Unlock()
|
||||
|
||||
if rec.holder == nil {
|
||||
rec.holder = ctx
|
||||
curGoid := goid.Get()
|
||||
|
||||
if rec.holder < 0 {
|
||||
if debug_log {
|
||||
log.Debugf("lockContext: curGoid=[%d] key=[%s] create new record", curGoid, rec.key)
|
||||
}
|
||||
rec.holder = curGoid
|
||||
rec.depth = 1
|
||||
return
|
||||
}
|
||||
|
||||
if debug_log {
|
||||
log.Debugf("rec.hold=[%p] ctx=[%p] %v key=[%s]", rec.holder, ctx, rec.holder == ctx, rec.key)
|
||||
log.Debugf("rec.hold=[%d] ctx=[%d] %v key=[%s]", rec.holder, curGoid, rec.holder == curGoid, rec.key)
|
||||
}
|
||||
|
||||
if rec.holder == ctx {
|
||||
if rec.holder == curGoid {
|
||||
rec.depth += 1
|
||||
if debug_log {
|
||||
log.Infof("lockContext: same ctx, depth: %d [%p] key=[%s]", rec.depth, rec.holder, rec.key)
|
||||
log.Infof("lockContext: same ctx, depth: %d holder=[%d] ctx=[%d] key=[%s]", rec.depth, rec.holder, curGoid, rec.key)
|
||||
}
|
||||
if rec.depth > 32 {
|
||||
// XXX MUST BE BUG ???
|
||||
@@ -79,57 +86,59 @@ func (rec *SInMemoryLockRecord) lockContext(ctx context.Context) {
|
||||
|
||||
// check
|
||||
rec.waiter.Enum(func(ele interface{}) {
|
||||
electx := ele.(context.Context)
|
||||
if electx == ctx {
|
||||
rec.fatalf("try to lock from a waiter context???? key=[%s]", rec.key)
|
||||
electx := ele.(int64)
|
||||
if electx == curGoid {
|
||||
rec.fatalf("try to lock from a waiter context???? curGoid=[%d] waiterGoid=[%d] key=[%s]", curGoid, electx, rec.key)
|
||||
}
|
||||
})
|
||||
|
||||
rec.waiter.Push(ctx)
|
||||
rec.waiter.Push(curGoid)
|
||||
|
||||
if debug_log {
|
||||
log.Debugf("waiter size %d after push", rec.waiter.Len())
|
||||
log.Debugf("Start to wait ... [%p] key=[%s]", ctx, rec.key)
|
||||
log.Debugf("waiter size %d after push curGoid=[%d]", rec.waiter.Len(), curGoid)
|
||||
log.Debugf("Start to wait ... holder=[%d] curGoid [%d] key=[%s]", rec.holder, curGoid, rec.key)
|
||||
}
|
||||
|
||||
for rec.holder != nil {
|
||||
for rec.holder >= 0 {
|
||||
rec.cond.Wait()
|
||||
}
|
||||
|
||||
if debug_log {
|
||||
log.Debugf("End of wait ... [%p] key=[%s]", ctx, rec.key)
|
||||
log.Debugf("End of wait ... holder=[%d] curGoid [%d] key=[%s]", rec.holder, curGoid, rec.key)
|
||||
}
|
||||
|
||||
rec.waiter.Pop(ctx)
|
||||
rec.waiter.Pop(curGoid)
|
||||
|
||||
if debug_log {
|
||||
log.Debugf("waiter size %d after pop key=[%s]", rec.waiter.Len(), rec.key)
|
||||
log.Debugf("waiter size %d after pop curGoid=[%d] key=[%s]", rec.waiter.Len(), curGoid, rec.key)
|
||||
}
|
||||
|
||||
rec.holder = ctx
|
||||
rec.holder = curGoid
|
||||
rec.depth = 1
|
||||
}
|
||||
|
||||
func (rec *SInMemoryLockRecord) unlockContext(ctx context.Context) (needClean bool) {
|
||||
func (rec *SInMemoryLockRecord) unlockContext(ctxDummy context.Context) (needClean bool) {
|
||||
rec.lock.Lock()
|
||||
defer rec.lock.Unlock()
|
||||
|
||||
if rec.holder != ctx {
|
||||
rec.fatalf("try to unlock a wait context??? key=[%s]", rec.key)
|
||||
curGoid := goid.Get()
|
||||
|
||||
if rec.holder != curGoid {
|
||||
rec.fatalf("try to unlock a wait context??? key=[%s] holder=[%d] curGoid=[%d]", rec.key, rec.holder, curGoid)
|
||||
}
|
||||
|
||||
if debug_log {
|
||||
log.Debugf("unlockContext depth %d [%p] key=[%s]", rec.depth, ctx, rec.key)
|
||||
log.Debugf("unlockContext depth %d curGoid=[%d] key=[%s]", rec.depth, curGoid, rec.key)
|
||||
}
|
||||
|
||||
rec.depth -= 1
|
||||
|
||||
if rec.depth <= 0 {
|
||||
if debug_log {
|
||||
log.Debugf("depth 0, to release lock for context [%p] key=[%s]", ctx, rec.key)
|
||||
log.Debugf("depth 0, to release lock for context curGoid=[%d] key=[%s]", curGoid, rec.key)
|
||||
}
|
||||
|
||||
rec.holder = nil
|
||||
rec.holder = -1
|
||||
if rec.waiter.Len() == 0 {
|
||||
return true
|
||||
}
|
||||
@@ -154,11 +163,11 @@ func NewInMemoryLockManager() ILockManager {
|
||||
return &lockMan
|
||||
}
|
||||
|
||||
func (lockman *SInMemoryLockManager) getRecordWithLock(ctx context.Context, key string) *SInMemoryLockRecord {
|
||||
func (lockman *SInMemoryLockManager) getRecordWithLock(ctx context.Context, key string, new bool) *SInMemoryLockRecord {
|
||||
lockman.tableLock.Lock()
|
||||
defer lockman.tableLock.Unlock()
|
||||
|
||||
return lockman.getRecord(ctx, key, true)
|
||||
return lockman.getRecord(ctx, key, new)
|
||||
}
|
||||
|
||||
func (lockman *SInMemoryLockManager) getRecord(ctx context.Context, key string, new bool) *SInMemoryLockRecord {
|
||||
@@ -175,23 +184,16 @@ func (lockman *SInMemoryLockManager) getRecord(ctx context.Context, key string,
|
||||
}
|
||||
|
||||
func (lockman *SInMemoryLockManager) LockKey(ctx context.Context, key string) {
|
||||
record := lockman.getRecordWithLock(ctx, key)
|
||||
|
||||
record := lockman.getRecordWithLock(ctx, key, true)
|
||||
record.lockContext(ctx)
|
||||
}
|
||||
|
||||
func (lockman *SInMemoryLockManager) UnlockKey(ctx context.Context, key string) {
|
||||
lockman.tableLock.Lock()
|
||||
defer lockman.tableLock.Unlock()
|
||||
|
||||
record := lockman.getRecord(ctx, key, false)
|
||||
record := lockman.getRecordWithLock(ctx, key, false)
|
||||
if record == nil {
|
||||
log.Errorf("BUG: unlock an non-existent lock\n%s", debug.Stack())
|
||||
log.Errorf("BUG: unlock an non-existent lock ctx: %p key: %s\n%s", ctx, key, debug.Stack())
|
||||
return
|
||||
}
|
||||
|
||||
needClean := record.unlockContext(ctx)
|
||||
if needClean {
|
||||
delete(lockman.lockTable, key)
|
||||
}
|
||||
record.unlockContext(ctx)
|
||||
}
|
||||
|
||||
@@ -16,9 +16,17 @@ package lockman
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/petermattis/goid"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/utils"
|
||||
)
|
||||
|
||||
func TestInMemoryLockManager(t *testing.T) {
|
||||
@@ -56,3 +64,74 @@ func TestRunManu(t *testing.T) {
|
||||
}
|
||||
t.Logf("complete")
|
||||
}
|
||||
|
||||
type app struct {
|
||||
ctx context.Context
|
||||
key string
|
||||
lockman ILockManager
|
||||
}
|
||||
|
||||
func (app *app) run() {
|
||||
app.lockman.LockKey(app.ctx, app.key)
|
||||
defer app.lockman.UnlockKey(app.ctx, app.key)
|
||||
|
||||
fmt.Printf("run for goid: %d key %s\n", goid.Get(), app.key)
|
||||
}
|
||||
|
||||
type emptyKey struct{}
|
||||
|
||||
func TestRunManu3(t *testing.T) {
|
||||
for i := 0; i < 100; i++ {
|
||||
TestRunManu2(t)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunManu2(t *testing.T) {
|
||||
rand.Seed(100)
|
||||
lockman := NewInMemoryLockManager()
|
||||
|
||||
debug_log = true
|
||||
|
||||
// 使用 WaitGroup 来等待所有 goroutine 完成
|
||||
var wg sync.WaitGroup
|
||||
MAX_GOROUTINE := 4096
|
||||
MAX_KEY := 4
|
||||
|
||||
complete := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case <-time.After(time.Second):
|
||||
t.Logf("timeout")
|
||||
utils.DumpAllGoroutineStack(os.Stdout)
|
||||
case <-complete:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
bgCtx := context.Background()
|
||||
|
||||
// 为每个 goroutine 创建独立的 context
|
||||
for i := 0; i < MAX_GOROUTINE; i++ {
|
||||
wg.Add(1)
|
||||
go func(id int) {
|
||||
defer wg.Done()
|
||||
// 为每个 goroutine 创建新的 context
|
||||
ctx := context.WithValue(bgCtx, emptyKey{}, id)
|
||||
log.Infof("ctx for id %d: %p", id, ctx)
|
||||
app := &app{
|
||||
ctx: ctx,
|
||||
key: fmt.Sprintf("test-%d", id%MAX_KEY),
|
||||
lockman: lockman,
|
||||
}
|
||||
app.run()
|
||||
}(i)
|
||||
}
|
||||
|
||||
// 等待所有 goroutine 完成
|
||||
wg.Wait()
|
||||
close(complete)
|
||||
t.Logf("complete")
|
||||
}
|
||||
|
||||
@@ -66,13 +66,12 @@ func ObjectIdQueryWithTagFiltersOptimized(ctx context.Context, q *sqlchemy.SQuer
|
||||
if len(filters.Filters) > 0 || len(filters.NoFilters) > 0 {
|
||||
idSubQ := q.Copy().SubQuery().Query()
|
||||
idSubQ.AppendField(sqlchemy.DISTINCT(idField, idSubQ.Field(idField)))
|
||||
subQ := idSubQ.SubQuery()
|
||||
if len(filters.Filters) > 0 {
|
||||
if GetMetadaManagerInContext(ctx) == Metadata {
|
||||
sq := tenantIdQueryWithTags(ctx, modelName, filters.Filters)
|
||||
q = q.In(idField, sq.SubQuery())
|
||||
} else { // clickhouse
|
||||
ids := objIdQueryWithTagsOptimized(ctx, subQ, idField, modelName, filters.Filters)
|
||||
ids := tenantIdQueryWithTagsWithCache(ctx, modelName, filters.Filters)
|
||||
if len(ids) > 0 {
|
||||
q = q.In(idField, ids)
|
||||
}
|
||||
@@ -83,7 +82,7 @@ func ObjectIdQueryWithTagFiltersOptimized(ctx context.Context, q *sqlchemy.SQuer
|
||||
sq := tenantIdQueryWithTags(ctx, modelName, filters.Filters)
|
||||
q = q.NotIn(idField, sq.SubQuery())
|
||||
} else { // clickhouse
|
||||
ids := objIdQueryWithTagsOptimized(ctx, subQ, idField, modelName, filters.NoFilters)
|
||||
ids := tenantIdQueryWithTagsWithCache(ctx, modelName, filters.NoFilters)
|
||||
if len(ids) > 0 {
|
||||
q = q.NotIn(idField, ids)
|
||||
}
|
||||
@@ -153,6 +152,50 @@ func tenantIdQueryWithTags(ctx context.Context, modelName string, tagsList []map
|
||||
return sq.Filter(sqlchemy.OR(conditions...)).Distinct()
|
||||
}
|
||||
|
||||
var (
|
||||
tagsCache = hashcache.NewCache(1024, time.Minute*15)
|
||||
)
|
||||
|
||||
func tenantIdQueryWithTagsWithCache(ctx context.Context, modelName string, tagsList []map[string][]string) []string {
|
||||
manager := Metadata
|
||||
|
||||
ret := []string{}
|
||||
sq := manager.Query("obj_id")
|
||||
for _, tags := range tagsList {
|
||||
if len(tags) == 0 {
|
||||
continue
|
||||
}
|
||||
hashKeys := []string{modelName, jsonutils.Marshal(tags).String()}
|
||||
hash := fmt.Sprintf("%x", md5.Sum([]byte(jsonutils.Marshal(hashKeys).String())))
|
||||
cache := tagsCache.Get(hash)
|
||||
if cache != nil {
|
||||
ids := cache.([]string)
|
||||
ret = append(ret, ids...)
|
||||
log.Debugf("cache hit %s %s %s", hash, hashKeys, ids)
|
||||
continue
|
||||
}
|
||||
conditions := []sqlchemy.ICondition{}
|
||||
for key, val := range tags {
|
||||
if len(val) > 0 {
|
||||
sqq := sq.Copy().Equals("obj_type", modelName).Equals("key", key).In("value", val)
|
||||
conditions = append(conditions, sqlchemy.In(sq.Field("obj_id"), sqq.SubQuery()))
|
||||
} else {
|
||||
sqq := sq.Copy().Equals("obj_type", modelName).Equals("key", key)
|
||||
conditions = append(conditions, sqlchemy.In(sq.Field("obj_id"), sqq.SubQuery()))
|
||||
}
|
||||
}
|
||||
ids, err := FetchIds(sq.Copy().Filter(sqlchemy.AND(conditions...)).Distinct())
|
||||
if err != nil {
|
||||
log.Errorf("FetchIds %s %v", sq.String(), err)
|
||||
continue
|
||||
}
|
||||
ret = append(ret, ids...)
|
||||
log.Debugf("cache miss %s %s %s", hash, hashKeys, ids)
|
||||
tagsCache.AtomicSet(hash, ids)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func objIdQueryWithTags(ctx context.Context, objIdSubQ *sqlchemy.SSubQuery, idField string, modelName string, tagsList []map[string][]string) *sqlchemy.SQuery {
|
||||
manager := GetMetadaManagerInContext(ctx)
|
||||
|
||||
@@ -192,53 +235,6 @@ func objIdQueryWithTags(ctx context.Context, objIdSubQ *sqlchemy.SSubQuery, idFi
|
||||
return query
|
||||
}
|
||||
|
||||
var (
|
||||
tagsCache = hashcache.NewCache(1024, time.Minute*15)
|
||||
)
|
||||
|
||||
func objIdQueryWithTagsOptimized(ctx context.Context, objIdSubQ *sqlchemy.SSubQuery, idField string, modelName string, tagsList []map[string][]string) []string {
|
||||
manager := GetMetadaManagerInContext(ctx)
|
||||
|
||||
ret := []string{}
|
||||
for _, tags := range tagsList {
|
||||
if len(tags) == 0 {
|
||||
continue
|
||||
}
|
||||
objIdQ := objIdSubQ.Query()
|
||||
objIdQ = objIdQ.AppendField(objIdQ.Field(idField))
|
||||
for key, val := range tags {
|
||||
hashKeys := []string{idField, key, modelName}
|
||||
hashKeys = append(hashKeys, val...)
|
||||
hash := fmt.Sprintf("%x", md5.Sum([]byte(jsonutils.Marshal(hashKeys).String())))
|
||||
cache := tagsCache.Get(hash)
|
||||
if cache != nil {
|
||||
ids := cache.([]string)
|
||||
ret = append(ret, ids...)
|
||||
continue
|
||||
}
|
||||
sq := manager.Query("obj_id").Equals("obj_type", modelName).Equals("key", key)
|
||||
if len(val) > 0 {
|
||||
ssq := sq.In("value", val).SubQuery()
|
||||
if utils.IsInArray(tagutils.NoValue, val) {
|
||||
objIdQ = objIdQ.LeftJoin(ssq, sqlchemy.Equals(objIdQ.Field(idField), ssq.Field("obj_id")))
|
||||
} else {
|
||||
objIdQ = objIdQ.Join(ssq, sqlchemy.Equals(objIdQ.Field(idField), ssq.Field("obj_id")))
|
||||
}
|
||||
} else {
|
||||
ssq := sq.SubQuery()
|
||||
objIdQ = objIdQ.Join(ssq, sqlchemy.Equals(objIdQ.Field(idField), ssq.Field("obj_id")))
|
||||
}
|
||||
ids, err := FetchIds(objIdQ)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
ret = append(ret, ids...)
|
||||
tagsCache.AtomicSet(hash, ids)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (meta *SMetadataResourceBaseModelManager) ListItemFilter(
|
||||
ctx context.Context,
|
||||
manager IModelManager,
|
||||
|
||||
@@ -51,6 +51,8 @@ const (
|
||||
ACT_BACKUP_START = "backup_start"
|
||||
ACT_BACKUP_START_FAILED = "backup_start_fail"
|
||||
|
||||
ACT_SET_RELEASE_TIME = "set_release_time"
|
||||
|
||||
ACT_FREEZE = "freeze"
|
||||
ACT_FREEZE_FAIL = "freeze_fail"
|
||||
ACT_UNFREEZE = "unfreeze"
|
||||
|
||||
@@ -31,10 +31,10 @@ type STaskBase struct {
|
||||
// 完成任务时间
|
||||
EndAt time.Time `nullable:"true" list:"user" json:"end_at"`
|
||||
|
||||
ObjType string `old_name:"obj_name" json:"obj_type" width:"128" charset:"utf8" nullable:"true" list:"user"`
|
||||
Object string `json:"object" width:"128" charset:"utf8" nullable:"true" list:"user"` // Column(VARCHAR(128, charset='utf8'), nullable=False)
|
||||
ObjId string `width:"128" charset:"ascii" nullable:"false" list:"user" index:"true"` // Column(VARCHAR(ID_LENGTH, charset='ascii'), nullable=False)
|
||||
TaskName string `width:"64" charset:"ascii" nullable:"false" list:"user" index:"true"` // Column(VARCHAR(64, charset='ascii'), nullable=False)
|
||||
ObjType string `old_name:"obj_name" json:"obj_type" width:"128" charset:"utf8" nullable:"false" default:"" list:"user"`
|
||||
Object string `json:"object" width:"128" charset:"utf8" nullable:"false" default:"" list:"user"` // Column(VARCHAR(128, charset='utf8'), nullable=False)
|
||||
ObjId string `width:"128" charset:"ascii" nullable:"false" list:"user" index:"true"` // Column(VARCHAR(ID_LENGTH, charset='ascii'), nullable=False)
|
||||
TaskName string `width:"64" charset:"ascii" nullable:"false" list:"user" index:"true"` // Column(VARCHAR(64, charset='ascii'), nullable=False)
|
||||
|
||||
UserCred mcclient.TokenCredential `width:"1024" charset:"utf8" nullable:"false" get:"user"` // Column(VARCHAR(1024, charset='ascii'), nullable=False)
|
||||
// OwnerCred string `width:"512" charset:"ascii" nullable:"true"` // Column(VARCHAR(512, charset='ascii'), nullable=True)
|
||||
|
||||
@@ -173,7 +173,7 @@ func (manager *STaskManager) FilterByOwner(ctx context.Context, q *sqlchemy.SQue
|
||||
taskQ = taskQ.Snapshot()
|
||||
taskQ = manager.SProjectizedResourceBaseManager.FilterByOwner(ctx, taskQ, man, userCred, owner, scope)
|
||||
if taskQ.IsAltered() {
|
||||
taskSubQ := taskQ.Distinct().SubQuery()
|
||||
taskSubQ := taskQ.SubQuery()
|
||||
q = q.Join(taskSubQ, sqlchemy.Equals(q.Field("id"), taskSubQ.Field("task_id")))
|
||||
}
|
||||
|
||||
|
||||
@@ -182,13 +182,18 @@ func lang(ctx context.Context, contactType npk.TNotifyChannel, reIds []string, c
|
||||
return langMap, nil
|
||||
}
|
||||
|
||||
func isEmptyRecipients(recipientId []string) bool {
|
||||
func isEmptyRecipients(recipientId, robots []string) bool {
|
||||
var recvs []string
|
||||
for _, c := range recipientId {
|
||||
if len(c) > 0 {
|
||||
recvs = append(recvs, c)
|
||||
}
|
||||
}
|
||||
for _, robot := range robots {
|
||||
if len(robot) > 0 {
|
||||
recvs = append(recvs, robot)
|
||||
}
|
||||
}
|
||||
return len(recvs) == 0
|
||||
}
|
||||
|
||||
@@ -216,7 +221,7 @@ func genMsgViaLang(ctx context.Context, p sNotifyParams) ([]npk.SNotifyMessage,
|
||||
reIds = p.recipientId
|
||||
}
|
||||
|
||||
if isEmptyRecipients(p.recipientId) {
|
||||
if isEmptyRecipients(p.recipientId, p.robots) {
|
||||
return nil, errors.Wrap(errors.ErrEmpty, "empty receipients")
|
||||
}
|
||||
|
||||
@@ -414,10 +419,10 @@ func (t *notifyTask) Run() {
|
||||
}
|
||||
|
||||
func intelliNotify(ctx context.Context, p sNotifyParams) {
|
||||
if isEmptyRecipients(p.recipientId) {
|
||||
if isEmptyRecipients(p.recipientId, p.robots) {
|
||||
return
|
||||
}
|
||||
log.Infof("recipientId: %v, contacts: %v, event %s priority %s", p.recipientId, p.contacts, p.event, p.priority)
|
||||
log.Infof("recipientId: %v, robots: %v, contacts: %v, event %s priority %s", p.recipientId, p.robots, p.contacts, p.event, p.priority)
|
||||
msgs, err := genMsgViaLang(ctx, p)
|
||||
if err != nil {
|
||||
log.Errorf("unable send notification: %v", err)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package options
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"yunion.io/x/log"
|
||||
@@ -22,6 +23,7 @@ import (
|
||||
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
||||
"yunion.io/x/onecloud/pkg/util/netutils2"
|
||||
)
|
||||
|
||||
func OnBaseOptionsChange(oOpts, nOpts interface{}) bool {
|
||||
@@ -63,6 +65,14 @@ func OnBaseOptionsChange(oOpts, nOpts interface{}) bool {
|
||||
if oldOpts.ApiServer != newOpts.ApiServer {
|
||||
log.Debugf("api_server changed from %s to %s", oldOpts.ApiServer, newOpts.ApiServer)
|
||||
}
|
||||
if !reflect.DeepEqual(oldOpts.MetadataServerIp4s, newOpts.MetadataServerIp4s) {
|
||||
netutils2.SetIp4MetadataServers(newOpts.MetadataServerIp4s)
|
||||
log.Debugf("Metadata server IPv4 address changed to %s", newOpts.MetadataServerIp4s)
|
||||
}
|
||||
if !reflect.DeepEqual(oldOpts.MetadataServerIp6s, newOpts.MetadataServerIp6s) {
|
||||
netutils2.SetIp6MetadataServers(newOpts.MetadataServerIp6s)
|
||||
log.Debugf("Metadata server IPv6 address changed to %s", newOpts.MetadataServerIp6s)
|
||||
}
|
||||
if oldOpts.TaskWorkerCount != newOpts.TaskWorkerCount {
|
||||
consts.SetTaskWorkerCount(newOpts.TaskWorkerCount)
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/util/atexit"
|
||||
"yunion.io/x/onecloud/pkg/util/fileutils2"
|
||||
"yunion.io/x/onecloud/pkg/util/netutils2"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -71,6 +72,8 @@ type BaseOptions struct {
|
||||
ApplicationID string `help:"Application ID"`
|
||||
RequestWorkerCount int `default:"8" help:"Request worker thread count, default is 8"`
|
||||
|
||||
RequestWorkerQueueSize int `default:"10" help:"Request worker queue size, default is 10"`
|
||||
|
||||
TaskWorkerCount int `default:"4" help:"Task manager worker thread count, default is 4"`
|
||||
LocalTaskWorkerCount int `default:"4" help:"Worker thread count that runs local tasks, default is 4"`
|
||||
|
||||
@@ -114,6 +117,9 @@ type BaseOptions struct {
|
||||
|
||||
CustomizedPrivatePrefixes []string `help:"customized private prefixes"`
|
||||
|
||||
MetadataServerIp4s []string `help:"metadata server IPv4 addresses, default is 169.254.169.254" default:"169.254.169.254"`
|
||||
MetadataServerIp6s []string `help:"metadata server IPv6 addresses, default is fd00:ec2::254" default:"'fd00:ec2::254'"`
|
||||
|
||||
structarg.BaseOptions
|
||||
|
||||
GlobalHTTPProxy string `help:"Global http proxy"`
|
||||
@@ -166,6 +172,7 @@ type HostCommonOptions struct {
|
||||
ExecutorConnectTimeoutSeconds int `help:"executor client connection timeout in seconds, default is 30" default:"30"`
|
||||
ImageDeployDriver string `help:"Image deploy driver" default:"qemu-kvm" choices:"qemu-kvm|nbd|libguestfs"`
|
||||
DeployConcurrent int `help:"qemu-kvm deploy driver concurrent" default:"5"`
|
||||
Qcow2Preallocation string `help:"Qcow2 image create preallocation" default:"metadata" choices:"disable|metadata|falloc|full"`
|
||||
}
|
||||
|
||||
type DBOptions struct {
|
||||
@@ -362,6 +369,8 @@ func parseOptions(optStruct interface{}, args []string, configFileName string, s
|
||||
|
||||
consts.SetServiceName(optionsRef.ApplicationID)
|
||||
httperrors.SetTimeZone(optionsRef.TimeZone)
|
||||
netutils2.SetIp4MetadataServers(optionsRef.MetadataServerIp4s)
|
||||
netutils2.SetIp6MetadataServers(optionsRef.MetadataServerIp6s)
|
||||
|
||||
// log configuration
|
||||
log.SetVerboseLevel(int32(optionsRef.LogVerboseLevel))
|
||||
@@ -409,6 +418,10 @@ func parseOptions(optStruct interface{}, args []string, configFileName string, s
|
||||
consts.SetTaskWorkerCount(optionsRef.TaskWorkerCount)
|
||||
consts.SetLocalTaskWorkerCount(optionsRef.LocalTaskWorkerCount)
|
||||
consts.SetTaskArchiveThresholdHours(optionsRef.TaskArchiveThresholdHours)
|
||||
|
||||
if optionsRef.Address == "0.0.0.0" {
|
||||
optionsRef.Address = ""
|
||||
}
|
||||
}
|
||||
|
||||
func (self *BaseOptions) HttpTransportProxyFunc() httputils.TransportProxyFunc {
|
||||
|
||||
@@ -31,12 +31,12 @@ import (
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
identity_api "yunion.io/x/onecloud/pkg/apis/identity"
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/consts"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/identity"
|
||||
"yunion.io/x/onecloud/pkg/util/ctx"
|
||||
"yunion.io/x/onecloud/pkg/util/hashcache"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
"yunion.io/x/onecloud/pkg/util/tagutils"
|
||||
@@ -76,7 +76,7 @@ type SPolicyManager struct {
|
||||
policyCache *hashcache.Cache // policy cache
|
||||
permissionCache *hashcache.Cache // permission cache
|
||||
|
||||
fetchWorker *appsrv.SWorkerManager
|
||||
// fetchWorker *appsrv.SWorkerManager
|
||||
|
||||
lock *sync.Mutex
|
||||
}
|
||||
@@ -146,19 +146,19 @@ func (manager *SPolicyManager) init(refreshInterval time.Duration, workerCount i
|
||||
defaultFetcherFuncAddr := reflect.ValueOf(DefaultPolicyFetcher).Pointer()
|
||||
remoteFetcherFuncAddr := reflect.ValueOf(auth.FetchMatchPolicies).Pointer()
|
||||
log.Debugf("DefaultPolicyFetcher: %x RemotePolicyFetcher: %x", defaultFetcherFuncAddr, remoteFetcherFuncAddr)
|
||||
var isDB bool
|
||||
if defaultFetcherFuncAddr == remoteFetcherFuncAddr {
|
||||
// remote fetcher, so start watcher
|
||||
isDB = false
|
||||
} else {
|
||||
isDB = true
|
||||
}
|
||||
// var isDB bool
|
||||
// if defaultFetcherFuncAddr == remoteFetcherFuncAddr {
|
||||
// remote fetcher, so start watcher
|
||||
// isDB = false
|
||||
// } else {
|
||||
// isDB = true
|
||||
// }
|
||||
|
||||
if workerCount <= 0 {
|
||||
workerCount = 1
|
||||
}
|
||||
log.Infof("policy fetch worker count %d", workerCount)
|
||||
manager.fetchWorker = appsrv.NewWorkerManager("policyFetchWorker", workerCount, 2048, isDB)
|
||||
// if workerCount <= 0 {
|
||||
// workerCount = 1
|
||||
// }
|
||||
// log.Infof("policy fetch worker count %d", workerCount)
|
||||
// manager.fetchWorker = appsrv.NewWorkerManager("policyFetchWorker", workerCount, 2048, isDB)
|
||||
}
|
||||
|
||||
func getMaskedLoginIp(userCred mcclient.TokenCredential) string {
|
||||
@@ -255,53 +255,22 @@ func (manager *SPolicyManager) Allow(targetScope rbacscope.TRbacScope, userCred
|
||||
return rbacutils.PolicyDeny
|
||||
}
|
||||
|
||||
type fetchResult struct {
|
||||
output *mcclient.SFetchMatchPoliciesOutput
|
||||
err error
|
||||
}
|
||||
|
||||
type policyTask struct {
|
||||
manager *SPolicyManager
|
||||
key string
|
||||
userCred mcclient.TokenCredential
|
||||
resChan chan fetchResult
|
||||
}
|
||||
|
||||
func (t *policyTask) Run() {
|
||||
val := t.manager.policyCache.AtomicGet(t.key)
|
||||
result := fetchResult{}
|
||||
if gotypes.IsNil(val) {
|
||||
pg, err := DefaultPolicyFetcher(context.Background(), t.userCred)
|
||||
if err != nil {
|
||||
result.err = errors.Wrap(err, "DefaultPolicyFetcher")
|
||||
} else {
|
||||
t.manager.policyCache.AtomicSet(t.key, pg)
|
||||
result.output = pg
|
||||
}
|
||||
} else {
|
||||
result.output = val.(*mcclient.SFetchMatchPoliciesOutput)
|
||||
}
|
||||
t.resChan <- result
|
||||
}
|
||||
|
||||
func (t *policyTask) Dump() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (manager *SPolicyManager) fetchMatchedPolicies(userCred mcclient.TokenCredential) (*mcclient.SFetchMatchPoliciesOutput, error) {
|
||||
key := policyKey(userCred)
|
||||
|
||||
task := policyTask{
|
||||
manager: manager,
|
||||
key: key,
|
||||
userCred: userCred,
|
||||
val := manager.policyCache.AtomicGet(key)
|
||||
if !gotypes.IsNil(val) {
|
||||
// cache hit
|
||||
return val.(*mcclient.SFetchMatchPoliciesOutput), nil
|
||||
}
|
||||
task.resChan = make(chan fetchResult)
|
||||
|
||||
manager.fetchWorker.Run(&task, nil, nil)
|
||||
pg, err := DefaultPolicyFetcher(ctx.CtxWithTime(), userCred)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "DefaultPolicyFetcher")
|
||||
}
|
||||
|
||||
res := <-task.resChan
|
||||
return res.output, res.err
|
||||
manager.policyCache.AtomicSet(key, pg)
|
||||
return pg, nil
|
||||
}
|
||||
|
||||
func (manager *SPolicyManager) allow(scope rbacscope.TRbacScope, userCred mcclient.TokenCredential, service string, resource string, action string, extra ...string) rbacutils.SPolicyResult {
|
||||
|
||||
@@ -52,6 +52,8 @@ type SNic struct {
|
||||
Bandwidth int `json:"bandwidth"`
|
||||
|
||||
Index int `json:"index"`
|
||||
|
||||
IsDefault *bool `json:"is_default"`
|
||||
}
|
||||
|
||||
type SRoute []string
|
||||
@@ -65,28 +67,29 @@ func (n SNic) GetMac() net.HardwareAddr {
|
||||
}
|
||||
|
||||
type SServerNic struct {
|
||||
Name string `json:"name"`
|
||||
Index int `json:"index"`
|
||||
Bridge string `json:"bridge"`
|
||||
Domain string `json:"domain"`
|
||||
Ip string `json:"ip"`
|
||||
Vlan int `json:"vlan"`
|
||||
Driver string `json:"driver"`
|
||||
Masklen int `json:"masklen"`
|
||||
Virtual bool `json:"virtual"`
|
||||
Manual bool `json:"manual"`
|
||||
WireId string `json:"wire_id"`
|
||||
NetId string `json:"net_id"`
|
||||
Mac string `json:"mac"`
|
||||
BandWidth int `json:"bw"`
|
||||
Mtu int16 `json:"mtu,omitempty"`
|
||||
Dns string `json:"dns"`
|
||||
Ntp string `json:"ntp"`
|
||||
Net string `json:"net"`
|
||||
Interface string `json:"interface"`
|
||||
Gateway string `json:"gateway"`
|
||||
Ifname string `json:"ifname"`
|
||||
Routes []SRoute `json:"routes,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Index int `json:"index"`
|
||||
Bridge string `json:"bridge"`
|
||||
Domain string `json:"domain"`
|
||||
Ip string `json:"ip"`
|
||||
Vlan int `json:"vlan"`
|
||||
VlanInterface bool `json:"vlan_interface"`
|
||||
Driver string `json:"driver"`
|
||||
Masklen int `json:"masklen"`
|
||||
Virtual bool `json:"virtual"`
|
||||
Manual bool `json:"manual"`
|
||||
WireId string `json:"wire_id"`
|
||||
NetId string `json:"net_id"`
|
||||
Mac string `json:"mac"`
|
||||
BandWidth int `json:"bw"`
|
||||
Mtu int16 `json:"mtu,omitempty"`
|
||||
Dns string `json:"dns"`
|
||||
Ntp string `json:"ntp"`
|
||||
Net string `json:"net"`
|
||||
Interface string `json:"interface"`
|
||||
Gateway string `json:"gateway"`
|
||||
Ifname string `json:"ifname"`
|
||||
Routes []SRoute `json:"routes,omitempty"`
|
||||
|
||||
Ip6 string `json:"ip6"`
|
||||
Masklen6 int `json:"masklen6"`
|
||||
@@ -131,5 +134,7 @@ func (n SServerNic) ToNic() SNic {
|
||||
Ip6Addr: n.Ip6,
|
||||
Masklen6: uint8(n.Masklen6),
|
||||
Gateway6: n.Gateway6,
|
||||
|
||||
IsDefault: &n.IsDefault,
|
||||
}
|
||||
}
|
||||
|
||||
177
pkg/cloudmon/misc/bucketprobe.go
Normal file
177
pkg/cloudmon/misc/bucketprobe.go
Normal file
@@ -0,0 +1,177 @@
|
||||
// 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 (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
computeapi "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
computemodules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
|
||||
baseoptions "yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
func BucketProbe(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
if options.Options.EnableBucketProbeDebug {
|
||||
log.Debugf("BucketProbe start")
|
||||
}
|
||||
if !options.Options.EnableBucketProbe {
|
||||
if options.Options.EnableBucketProbeDebug {
|
||||
log.Debugf("BucketProbe is disabled")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
sess := auth.GetSession(ctx, userCred, options.Options.Region)
|
||||
|
||||
metrics, err := gatherBucketMetrics(ctx, sess)
|
||||
if err != nil {
|
||||
log.Errorf("BucketProbe gatherBucketMetrics failed: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = sendMetrics(sess, metrics, "telegraf")
|
||||
if err != nil {
|
||||
log.Errorf("StatusProbe SendMetrics error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func gatherBucketMetrics(ctx context.Context, sess *mcclient.ClientSession) ([]influxdb.SMetricData, error) {
|
||||
allMetrics := []influxdb.SMetricData{}
|
||||
|
||||
params := baseoptions.BaseListOptions{}
|
||||
params.Scope = "max"
|
||||
limit := 1000
|
||||
params.Limit = &limit
|
||||
params.Filter = []string{
|
||||
"enable_perf_mon.equals(1)",
|
||||
}
|
||||
boolTrue := true
|
||||
params.Details = &boolTrue
|
||||
|
||||
total := -1
|
||||
offset := 0
|
||||
for total < 0 || offset < total {
|
||||
params.Offset = &offset
|
||||
results, err := computemodules.Buckets.List(sess, jsonutils.Marshal(params))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "computemodules.Buckets.List")
|
||||
}
|
||||
total = results.Total
|
||||
offset = results.Offset + len(results.Data)
|
||||
|
||||
for _, bucket := range results.Data {
|
||||
bucketDetails := computeapi.BucketDetails{}
|
||||
err = bucket.Unmarshal(&bucketDetails)
|
||||
if err != nil {
|
||||
log.Errorf("BucketProbe failed: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
metrics, err := probeBucketStats(ctx, sess, &bucketDetails)
|
||||
if err != nil {
|
||||
log.Errorf("BucketProbe failed: %s", err)
|
||||
continue
|
||||
}
|
||||
allMetrics = append(allMetrics, metrics...)
|
||||
}
|
||||
}
|
||||
|
||||
return allMetrics, nil
|
||||
}
|
||||
|
||||
func probeBucketStats(ctx context.Context, sess *mcclient.ClientSession, bucketDetails *computeapi.BucketDetails) ([]influxdb.SMetricData, error) {
|
||||
bucket, err := computemodules.GetIBucket(ctx, sess, bucketDetails)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getIBucket")
|
||||
}
|
||||
|
||||
resultDelay, err := computemodules.ProbeBucketStats(ctx, bucket, options.Options.BucketProbeTestKey, 0)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "doProbeBucketStats zero")
|
||||
}
|
||||
|
||||
resultRate, err := computemodules.ProbeBucketStats(ctx, bucket, options.Options.BucketProbeTestKey, int64(options.Options.BucketProbeTestSizeMb)*1024*1024)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "doProbeBucketStats with payload")
|
||||
}
|
||||
|
||||
metricTags := []influxdb.SKeyValue{}
|
||||
for k, v := range bucketDetails.GetMetricTags() {
|
||||
if len(v) == 0 {
|
||||
continue
|
||||
}
|
||||
metricTags = append(metricTags, influxdb.SKeyValue{
|
||||
Key: k,
|
||||
Value: v,
|
||||
})
|
||||
}
|
||||
|
||||
metrics := []influxdb.SKeyValue{}
|
||||
for k, v := range bucketDetails.GetMetricTags() {
|
||||
if len(v) == 0 {
|
||||
continue
|
||||
}
|
||||
metrics = append(metrics, influxdb.SKeyValue{
|
||||
Key: k,
|
||||
Value: v,
|
||||
})
|
||||
}
|
||||
|
||||
metrics = append(metrics,
|
||||
influxdb.SKeyValue{
|
||||
Key: "upload_delay_ms",
|
||||
Value: fmt.Sprintf("%f", resultDelay.UploadDelayMs()),
|
||||
},
|
||||
influxdb.SKeyValue{
|
||||
Key: "download_delay_ms",
|
||||
Value: fmt.Sprintf("%f", resultDelay.DownloadDelayMs()),
|
||||
},
|
||||
influxdb.SKeyValue{
|
||||
Key: "delete_delay_ms",
|
||||
Value: fmt.Sprintf("%f", resultDelay.DeleteDelayMs()),
|
||||
},
|
||||
influxdb.SKeyValue{
|
||||
Key: "upload_rate_mbps",
|
||||
Value: fmt.Sprintf("%f", resultRate.UploadThroughputMbps(options.Options.BucketProbeTestSizeMb)),
|
||||
},
|
||||
influxdb.SKeyValue{
|
||||
Key: "download_rate_mbps",
|
||||
Value: fmt.Sprintf("%f", resultRate.DownloadThroughputMbps(options.Options.BucketProbeTestSizeMb)),
|
||||
},
|
||||
)
|
||||
|
||||
if options.Options.EnableBucketProbeDebug {
|
||||
log.Debugf("BucketProbe for bucket %s metrics: %s", bucketDetails.Name, jsonutils.Marshal(metrics))
|
||||
}
|
||||
|
||||
return []influxdb.SMetricData{
|
||||
{
|
||||
Name: "bucket_perf",
|
||||
Tags: metricTags,
|
||||
Metrics: metrics,
|
||||
Timestamp: time.Now(),
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
437
pkg/cloudmon/misc/httpstats.go
Normal file
437
pkg/cloudmon/misc/httpstats.go
Normal file
@@ -0,0 +1,437 @@
|
||||
// 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 (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
type SHttpStats struct {
|
||||
HttpCode2xx float64 `json:"duration.2XX"`
|
||||
HttpCode4xx float64 `json:"duration.4XX"`
|
||||
HttpCode5xx float64 `json:"duration.5XX"`
|
||||
HitHttpCode2xx int64 `json:"hit.2XX"`
|
||||
HitHttpCode4xx int64 `json:"hit.4XX"`
|
||||
HitHttpCode5xx int64 `json:"hit.5XX"`
|
||||
|
||||
Method string `json:"method"`
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
type sApiHttpStats struct {
|
||||
SHttpStats
|
||||
|
||||
Paths []SHttpStats `json:"paths"`
|
||||
}
|
||||
|
||||
func (apiStats *sApiHttpStats) convertSnapshot(now time.Time) *sHttpStatsSnapshot {
|
||||
snapshot := &sHttpStatsSnapshot{
|
||||
snapshotAt: now,
|
||||
stats: map[string]*SHttpStats{},
|
||||
}
|
||||
apiStats.SHttpStats.Method = "any"
|
||||
apiStats.SHttpStats.Path = "any"
|
||||
apiStats.SHttpStats.Name = "any"
|
||||
snapshot.stats[getStatsKey(apiStats.SHttpStats.Method, apiStats.SHttpStats.Path, apiStats.SHttpStats.Name)] = &apiStats.SHttpStats
|
||||
for i := range apiStats.Paths {
|
||||
pathStats := apiStats.Paths[i]
|
||||
snapshot.stats[getStatsKey(pathStats.Method, pathStats.Path, pathStats.Name)] = &pathStats
|
||||
}
|
||||
return snapshot
|
||||
}
|
||||
|
||||
type sHttpStatsExt struct {
|
||||
Duration2xx float64 `json:"duration_2xx"`
|
||||
Duration4xx float64 `json:"duration_4xx"`
|
||||
Duration5xx float64 `json:"duration_5xx"`
|
||||
Hit2xx int64 `json:"hit_2xx"`
|
||||
Hit4xx int64 `json:"hit_4xx"`
|
||||
Hit5xx int64 `json:"hit_5xx"`
|
||||
|
||||
Duration2xxDiff float64 `json:"duration_2xx_diff"`
|
||||
Duration4xxDiff float64 `json:"duration_4xx_diff"`
|
||||
Duration5xxDiff float64 `json:"duration_5xx_diff"`
|
||||
Hit2xxDiff int64 `json:"hit_2xx_diff"`
|
||||
Hit4xxDiff int64 `json:"hit_4xx_diff"`
|
||||
Hit5xxDiff int64 `json:"hit_5xx_diff"`
|
||||
|
||||
Method string `json:"method"`
|
||||
Path string `json:"path"`
|
||||
Name string `json:"name"`
|
||||
|
||||
HasDiff bool `json:"has_diff"`
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) DelayMs2xx() float64 {
|
||||
if v.Hit2xxDiff > 0 {
|
||||
return v.Duration2xxDiff / float64(v.Hit2xxDiff)
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) Qps2xx(interval time.Duration) float64 {
|
||||
if interval > 0 {
|
||||
return float64(v.Hit2xxDiff) / interval.Seconds()
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) DelayMs4xx() float64 {
|
||||
if v.Hit4xxDiff > 0 {
|
||||
return v.Duration4xxDiff / float64(v.Hit4xxDiff)
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) Qps4xx(interval time.Duration) float64 {
|
||||
if interval > 0 {
|
||||
return float64(v.Hit4xxDiff) / interval.Seconds()
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) DelayMs5xx() float64 {
|
||||
if v.Hit5xxDiff > 0 {
|
||||
return v.Duration5xxDiff / float64(v.Hit5xxDiff)
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) Qps5xx(interval time.Duration) float64 {
|
||||
if interval > 0 {
|
||||
return float64(v.Hit5xxDiff) / interval.Seconds()
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) Qps(interval time.Duration) float64 {
|
||||
if interval > 0 {
|
||||
return float64(v.Hit2xxDiff+v.Hit4xxDiff+v.Hit5xxDiff) / interval.Seconds()
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) DelayMs() float64 {
|
||||
if v.HitDiff() > 0 {
|
||||
return v.DurationMsDiff() / float64(v.HitDiff())
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) DurationMs() float64 {
|
||||
return v.Duration2xx + v.Duration4xx + v.Duration5xx
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) Hit() int64 {
|
||||
return v.Hit2xx + v.Hit4xx + v.Hit5xx
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) DurationMsDiff() float64 {
|
||||
return v.Duration2xxDiff + v.Duration4xxDiff + v.Duration5xxDiff
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) HitDiff() int64 {
|
||||
return v.Hit2xxDiff + v.Hit4xxDiff + v.Hit5xxDiff
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) Percent2xx() float64 {
|
||||
if v.DurationMsDiff() > 0 {
|
||||
return v.Duration2xxDiff * 100 / v.DurationMsDiff()
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) PercentHit2xx() float64 {
|
||||
if v.HitDiff() > 0 {
|
||||
return float64(v.Hit2xxDiff) * 100 / float64(v.HitDiff())
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) Percent4xx() float64 {
|
||||
if v.DurationMsDiff() > 0 {
|
||||
return v.Duration4xxDiff * 100 / v.DurationMsDiff()
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) PercentHit4xx() float64 {
|
||||
if v.HitDiff() > 0 {
|
||||
return float64(v.Hit4xxDiff) * 100 / float64(v.HitDiff())
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) Percent5xx() float64 {
|
||||
if v.DurationMsDiff() > 0 {
|
||||
return v.Duration5xxDiff * 100 / v.DurationMsDiff()
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (v sHttpStatsExt) PercentHit5xx() float64 {
|
||||
if v.HitDiff() > 0 {
|
||||
return float64(v.Hit5xxDiff) * 100 / float64(v.HitDiff())
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
type sHttpStatsSnapshot struct {
|
||||
snapshotAt time.Time
|
||||
stats map[string]*SHttpStats
|
||||
}
|
||||
|
||||
type sHttpStatsDiff struct {
|
||||
snapshotAt time.Time
|
||||
interval time.Duration
|
||||
stats map[string]*sHttpStatsExt
|
||||
}
|
||||
|
||||
func calculateHttpStatsDiff(prevSnap *sHttpStatsSnapshot, nowSnap *sHttpStatsSnapshot) *sHttpStatsDiff {
|
||||
diff := sHttpStatsDiff{
|
||||
snapshotAt: nowSnap.snapshotAt,
|
||||
stats: map[string]*sHttpStatsExt{},
|
||||
}
|
||||
if prevSnap != nil {
|
||||
rootKey := getStatsKey("any", "any", "any")
|
||||
prevRoot := prevSnap.stats[rootKey]
|
||||
nowRoot := nowSnap.stats[rootKey]
|
||||
|
||||
if prevRoot.HttpCode2xx > nowRoot.HttpCode2xx || prevRoot.HttpCode4xx > nowRoot.HttpCode4xx || prevRoot.HttpCode5xx > nowRoot.HttpCode5xx ||
|
||||
prevRoot.HitHttpCode2xx > nowRoot.HitHttpCode2xx || prevRoot.HitHttpCode4xx > nowRoot.HitHttpCode4xx || prevRoot.HitHttpCode5xx > nowRoot.HitHttpCode5xx {
|
||||
// detect a reset, skip this round
|
||||
prevSnap = nil
|
||||
}
|
||||
}
|
||||
if prevSnap != nil {
|
||||
diff.interval = nowSnap.snapshotAt.Sub(prevSnap.snapshotAt)
|
||||
} else {
|
||||
intvMin := options.Options.CollectServiceMetricIntervalMinute
|
||||
if intvMin <= 0 {
|
||||
intvMin = 1
|
||||
}
|
||||
diff.interval = time.Duration(intvMin) * time.Minute
|
||||
}
|
||||
|
||||
for k := range nowSnap.stats {
|
||||
v := nowSnap.stats[k]
|
||||
diffStats := sHttpStatsExt{
|
||||
Duration2xx: v.HttpCode2xx,
|
||||
Duration4xx: v.HttpCode4xx,
|
||||
Duration5xx: v.HttpCode5xx,
|
||||
Hit2xx: v.HitHttpCode2xx,
|
||||
Hit4xx: v.HitHttpCode4xx,
|
||||
Hit5xx: v.HitHttpCode5xx,
|
||||
|
||||
Method: v.Method,
|
||||
Path: v.Path,
|
||||
Name: v.Name,
|
||||
}
|
||||
if prevSnap != nil {
|
||||
if prevStats, ok := prevSnap.stats[k]; ok {
|
||||
diffStats.HasDiff = true
|
||||
diffStats.Duration2xxDiff = v.HttpCode2xx - prevStats.HttpCode2xx
|
||||
diffStats.Duration4xxDiff = v.HttpCode4xx - prevStats.HttpCode4xx
|
||||
diffStats.Duration5xxDiff = v.HttpCode5xx - prevStats.HttpCode5xx
|
||||
diffStats.Hit2xxDiff = v.HitHttpCode2xx - prevStats.HitHttpCode2xx
|
||||
diffStats.Hit4xxDiff = v.HitHttpCode4xx - prevStats.HitHttpCode4xx
|
||||
diffStats.Hit5xxDiff = v.HitHttpCode5xx - prevStats.HitHttpCode5xx
|
||||
}
|
||||
}
|
||||
|
||||
diff.stats[k] = &diffStats
|
||||
}
|
||||
return &diff
|
||||
}
|
||||
|
||||
var (
|
||||
httpStatsSnapshot = map[string]*sHttpStatsSnapshot{}
|
||||
)
|
||||
|
||||
func getStatsKey(method, path, name string) string {
|
||||
return fmt.Sprintf("%s.%s.%s", method, path, name)
|
||||
}
|
||||
|
||||
func getSnapshotKey(serviceName, url string) string {
|
||||
return fmt.Sprintf("%s.%s", serviceName, url)
|
||||
}
|
||||
|
||||
func updateHttpStatsSnapshot(serviceName string, url string, now time.Time, apiStats sApiHttpStats, serviceType, regionId, version string) []influxdb.SMetricData {
|
||||
snapshot := apiStats.convertSnapshot(now)
|
||||
|
||||
snapshotKey := getSnapshotKey(serviceName, url)
|
||||
var vdiffStats *sHttpStatsDiff
|
||||
if prevSnap, ok := httpStatsSnapshot[snapshotKey]; ok {
|
||||
vdiffStats = calculateHttpStatsDiff(prevSnap, snapshot)
|
||||
} else {
|
||||
// no prev records, just add
|
||||
vdiffStats = calculateHttpStatsDiff(nil, snapshot)
|
||||
}
|
||||
httpStatsSnapshot[snapshotKey] = snapshot
|
||||
|
||||
metrics := vdiffStats.metrics(serviceName, serviceType, regionId, version)
|
||||
|
||||
log.Debugf("updateHttpStatsSnapshot %s %s snapshotAt: %s diffAt: %s intval: %f metrics: %d", serviceName, url, snapshot.snapshotAt, vdiffStats.snapshotAt, vdiffStats.interval.Seconds(), len(metrics))
|
||||
|
||||
return metrics
|
||||
}
|
||||
|
||||
func appendMetric(metrics []influxdb.SKeyValue, key string, v float64) []influxdb.SKeyValue {
|
||||
if v >= 0 {
|
||||
metrics = append(metrics, influxdb.SKeyValue{
|
||||
Key: key,
|
||||
Value: fmt.Sprintf("%f", v),
|
||||
})
|
||||
}
|
||||
return metrics
|
||||
}
|
||||
|
||||
func (diff *sHttpStatsDiff) metrics(service, serviceType, regionId, version string) []influxdb.SMetricData {
|
||||
metrics := make([]influxdb.SMetricData, 0)
|
||||
genTags := func(v *sHttpStatsExt) []influxdb.SKeyValue {
|
||||
return []influxdb.SKeyValue{
|
||||
{
|
||||
Key: "service",
|
||||
Value: service,
|
||||
},
|
||||
{
|
||||
Key: "service_type",
|
||||
Value: serviceType,
|
||||
},
|
||||
{
|
||||
Key: "region",
|
||||
Value: regionId,
|
||||
},
|
||||
{
|
||||
Key: "version",
|
||||
Value: version,
|
||||
},
|
||||
{
|
||||
Key: "method",
|
||||
Value: v.Method,
|
||||
},
|
||||
{
|
||||
Key: "path",
|
||||
Value: v.Path,
|
||||
},
|
||||
{
|
||||
Key: "name",
|
||||
Value: v.Name,
|
||||
},
|
||||
{
|
||||
Key: "interval_secs",
|
||||
Value: fmt.Sprintf("%f", diff.interval.Seconds()),
|
||||
},
|
||||
}
|
||||
}
|
||||
for k := range diff.stats {
|
||||
v := diff.stats[k]
|
||||
|
||||
// ignore stats with no hit
|
||||
if v.Hit() <= 0 {
|
||||
continue
|
||||
}
|
||||
// ignore stats with no diff
|
||||
if v.HasDiff && v.HitDiff() <= 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
metric := influxdb.SMetricData{
|
||||
Name: METIRCY_TYPE_HTTP_REQUST,
|
||||
Timestamp: diff.snapshotAt,
|
||||
Tags: genTags(v),
|
||||
Metrics: []influxdb.SKeyValue{
|
||||
{
|
||||
Key: "duration_ms_any",
|
||||
Value: fmt.Sprintf("%f", v.DurationMs()),
|
||||
},
|
||||
{
|
||||
Key: "hit_any",
|
||||
Value: fmt.Sprintf("%d", v.Hit()),
|
||||
},
|
||||
},
|
||||
}
|
||||
if v.HasDiff {
|
||||
metric.Metrics = appendMetric(metric.Metrics, "dura_ms_delta_any", v.DurationMsDiff())
|
||||
metric.Metrics = appendMetric(metric.Metrics, "hit_delta_any", float64(v.HitDiff()))
|
||||
metric.Metrics = appendMetric(metric.Metrics, "delay_ms_any", v.DelayMs())
|
||||
metric.Metrics = appendMetric(metric.Metrics, "qps_any", v.Qps(diff.interval))
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, []influxdb.SKeyValue{
|
||||
{
|
||||
Key: "duration_ms_2xx",
|
||||
Value: fmt.Sprintf("%f", v.Duration2xx),
|
||||
},
|
||||
{
|
||||
Key: "hit_2xx",
|
||||
Value: fmt.Sprintf("%d", v.Hit2xx),
|
||||
},
|
||||
}...)
|
||||
if v.HasDiff {
|
||||
metric.Metrics = appendMetric(metric.Metrics, "dura_ms_delta_2xx", v.Duration2xxDiff)
|
||||
metric.Metrics = appendMetric(metric.Metrics, "hit_delta_2xx", float64(v.Hit2xxDiff))
|
||||
metric.Metrics = appendMetric(metric.Metrics, "delay_ms_2xx", v.DelayMs2xx())
|
||||
metric.Metrics = appendMetric(metric.Metrics, "percent_hit_2xx", v.PercentHit2xx())
|
||||
metric.Metrics = appendMetric(metric.Metrics, "percent_duration_2xx", v.Percent2xx())
|
||||
metric.Metrics = appendMetric(metric.Metrics, "qps_2xx", v.Qps2xx(diff.interval))
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, []influxdb.SKeyValue{
|
||||
{
|
||||
Key: "duration_ms_4xx",
|
||||
Value: fmt.Sprintf("%f", v.Duration4xx),
|
||||
},
|
||||
{
|
||||
Key: "hit_4xx",
|
||||
Value: fmt.Sprintf("%d", v.Hit4xx),
|
||||
},
|
||||
}...)
|
||||
if v.HasDiff {
|
||||
metric.Metrics = appendMetric(metric.Metrics, "dura_ms_delta_4xx", v.Duration4xxDiff)
|
||||
metric.Metrics = appendMetric(metric.Metrics, "hit_delta_4xx", float64(v.Hit4xxDiff))
|
||||
metric.Metrics = appendMetric(metric.Metrics, "delay_ms_4xx", v.DelayMs4xx())
|
||||
metric.Metrics = appendMetric(metric.Metrics, "percent_hit_4xx", v.PercentHit4xx())
|
||||
metric.Metrics = appendMetric(metric.Metrics, "percent_duration_4xx", v.Percent4xx())
|
||||
metric.Metrics = appendMetric(metric.Metrics, "qps_4xx", v.Qps4xx(diff.interval))
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, []influxdb.SKeyValue{
|
||||
{
|
||||
Key: "duration_ms_5xx",
|
||||
Value: fmt.Sprintf("%f", v.Duration5xx),
|
||||
},
|
||||
{
|
||||
Key: "hit_5xx",
|
||||
Value: fmt.Sprintf("%d", v.Hit5xx),
|
||||
},
|
||||
}...)
|
||||
if v.HasDiff {
|
||||
metric.Metrics = appendMetric(metric.Metrics, "dura_ms_delta_5xx", v.Duration5xxDiff)
|
||||
metric.Metrics = appendMetric(metric.Metrics, "hit_delta_5xx", float64(v.Hit5xxDiff))
|
||||
metric.Metrics = appendMetric(metric.Metrics, "delay_ms_5xx", v.DelayMs5xx())
|
||||
metric.Metrics = appendMetric(metric.Metrics, "percent_hit_5xx", v.PercentHit5xx())
|
||||
metric.Metrics = appendMetric(metric.Metrics, "percent_duration_5xx", v.Percent5xx())
|
||||
metric.Metrics = appendMetric(metric.Metrics, "qps_5xx", v.Qps5xx(diff.interval))
|
||||
}
|
||||
|
||||
metrics = append(metrics, metric)
|
||||
}
|
||||
return metrics
|
||||
}
|
||||
215
pkg/cloudmon/misc/httpstats_test.go
Normal file
215
pkg/cloudmon/misc/httpstats_test.go
Normal file
@@ -0,0 +1,215 @@
|
||||
// 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 (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/util/timeutils"
|
||||
)
|
||||
|
||||
func TestUnmarshalHttpStats(t *testing.T) {
|
||||
input := `{"duration.2XX":4532188.710192006, "duration.4XX":196870.22898800002, "duration.5XX":32787.14909299999, "hit.2XX":88678, "hit.4XX":1748, "hit.5XX":179, "paths":[{"duration.2XX":150, "duration.4XX":250, "duration.5XX":310, "hit.2XX":1500, "hit.4XX":2500, "hit.5XX":3500, "method":"GET", "path":"/servers", "name":"list_servers"}, {"duration.2XX":150, "duration.4XX":250, "duration.5XX":350, "hit.2XX":1500, "hit.4XX":2500, "hit.5XX":3500, "method":"POST", "path":"/servers", "name":"create_servers"}]}`
|
||||
inputJson, err := jsonutils.ParseString(input)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Logf("json: %s", inputJson.PrettyString())
|
||||
var stats sApiHttpStats
|
||||
err = inputJson.Unmarshal(&stats)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if stats.HttpCode2xx != 4532188.710192006 {
|
||||
t.Fatalf("duration.2XX: %f", stats.HttpCode2xx)
|
||||
}
|
||||
if stats.HttpCode4xx != 196870.22898800002 {
|
||||
t.Fatalf("duration.4XX: %f", stats.HttpCode4xx)
|
||||
}
|
||||
if stats.HttpCode5xx != 32787.14909299999 {
|
||||
t.Fatalf("duration.5XX: %f", stats.HttpCode5xx)
|
||||
}
|
||||
if stats.HitHttpCode2xx != 88678 {
|
||||
t.Fatalf("hit.2XX: %d", stats.HitHttpCode2xx)
|
||||
}
|
||||
if stats.HitHttpCode4xx != 1748 {
|
||||
t.Fatalf("hit.4XX: %d", stats.HitHttpCode4xx)
|
||||
}
|
||||
if stats.HitHttpCode5xx != 179 {
|
||||
t.Fatalf("hit.5XX: %d", stats.HitHttpCode5xx)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHttpStats(t *testing.T) {
|
||||
cases := []struct {
|
||||
prevTime time.Time
|
||||
nowTime time.Time
|
||||
prevStats *sApiHttpStats
|
||||
nowStats sApiHttpStats
|
||||
}{
|
||||
{
|
||||
nowTime: func() time.Time {
|
||||
tm, _ := timeutils.ParseTimeStr("2025-06-01 00:01:00")
|
||||
return tm
|
||||
}(),
|
||||
nowStats: sApiHttpStats{
|
||||
SHttpStats: SHttpStats{
|
||||
HttpCode2xx: 400,
|
||||
HttpCode4xx: 700,
|
||||
HttpCode5xx: 1000,
|
||||
HitHttpCode2xx: 4000,
|
||||
HitHttpCode4xx: 7000,
|
||||
HitHttpCode5xx: 10000,
|
||||
},
|
||||
Paths: []SHttpStats{
|
||||
{
|
||||
HttpCode2xx: 150,
|
||||
HttpCode4xx: 250,
|
||||
HttpCode5xx: 310,
|
||||
HitHttpCode2xx: 1500,
|
||||
HitHttpCode4xx: 2500,
|
||||
HitHttpCode5xx: 3500,
|
||||
Method: "GET",
|
||||
Path: "/servers",
|
||||
Name: "list_servers",
|
||||
},
|
||||
{
|
||||
HttpCode2xx: 150,
|
||||
HttpCode4xx: 250,
|
||||
HttpCode5xx: 350,
|
||||
HitHttpCode2xx: 1500,
|
||||
HitHttpCode4xx: 2500,
|
||||
HitHttpCode5xx: 3500,
|
||||
Method: "POST",
|
||||
Path: "/servers",
|
||||
Name: "create_servers",
|
||||
},
|
||||
{
|
||||
HttpCode2xx: 100,
|
||||
HttpCode4xx: 200,
|
||||
HttpCode5xx: 300,
|
||||
HitHttpCode2xx: 1000,
|
||||
HitHttpCode4xx: 2000,
|
||||
HitHttpCode5xx: 3000,
|
||||
Method: "PUT",
|
||||
Path: "/servers/*",
|
||||
Name: "update_servers",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
prevTime: func() time.Time {
|
||||
tm, _ := timeutils.ParseTimeStr("2025-06-01 00:00:00")
|
||||
return tm
|
||||
}(),
|
||||
nowTime: func() time.Time {
|
||||
tm, _ := timeutils.ParseTimeStr("2025-06-01 00:01:00")
|
||||
return tm
|
||||
}(),
|
||||
prevStats: &sApiHttpStats{
|
||||
SHttpStats: SHttpStats{
|
||||
HttpCode2xx: 200,
|
||||
HttpCode4xx: 400,
|
||||
HttpCode5xx: 600,
|
||||
HitHttpCode2xx: 2000,
|
||||
HitHttpCode4xx: 4000,
|
||||
HitHttpCode5xx: 6000,
|
||||
},
|
||||
Paths: []SHttpStats{
|
||||
{
|
||||
HttpCode2xx: 100,
|
||||
HttpCode4xx: 200,
|
||||
HttpCode5xx: 300,
|
||||
HitHttpCode2xx: 1000,
|
||||
HitHttpCode4xx: 2000,
|
||||
HitHttpCode5xx: 3000,
|
||||
Method: "GET",
|
||||
Path: "/servers",
|
||||
Name: "list_servers",
|
||||
},
|
||||
{
|
||||
HttpCode2xx: 100,
|
||||
HttpCode4xx: 200,
|
||||
HttpCode5xx: 300,
|
||||
HitHttpCode2xx: 1000,
|
||||
HitHttpCode4xx: 2000,
|
||||
HitHttpCode5xx: 3000,
|
||||
Method: "POST",
|
||||
Path: "/servers",
|
||||
Name: "create_servers",
|
||||
},
|
||||
},
|
||||
},
|
||||
nowStats: sApiHttpStats{
|
||||
SHttpStats: SHttpStats{
|
||||
HttpCode2xx: 400,
|
||||
HttpCode4xx: 700,
|
||||
HttpCode5xx: 1000,
|
||||
HitHttpCode2xx: 4000,
|
||||
HitHttpCode4xx: 7000,
|
||||
HitHttpCode5xx: 10000,
|
||||
},
|
||||
Paths: []SHttpStats{
|
||||
{
|
||||
HttpCode2xx: 150,
|
||||
HttpCode4xx: 250,
|
||||
HttpCode5xx: 310,
|
||||
HitHttpCode2xx: 1500,
|
||||
HitHttpCode4xx: 2500,
|
||||
HitHttpCode5xx: 3500,
|
||||
Method: "GET",
|
||||
Path: "/servers",
|
||||
Name: "list_servers",
|
||||
},
|
||||
{
|
||||
HttpCode2xx: 150,
|
||||
HttpCode4xx: 250,
|
||||
HttpCode5xx: 350,
|
||||
HitHttpCode2xx: 1500,
|
||||
HitHttpCode4xx: 2500,
|
||||
HitHttpCode5xx: 3500,
|
||||
Method: "POST",
|
||||
Path: "/servers",
|
||||
Name: "create_servers",
|
||||
},
|
||||
{
|
||||
HttpCode2xx: 100,
|
||||
HttpCode4xx: 200,
|
||||
HttpCode5xx: 300,
|
||||
HitHttpCode2xx: 1000,
|
||||
HitHttpCode4xx: 2000,
|
||||
HitHttpCode5xx: 3000,
|
||||
Method: "PUT",
|
||||
Path: "/servers/*",
|
||||
Name: "update_servers",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
var prev *sHttpStatsSnapshot
|
||||
if c.prevStats != nil {
|
||||
prev = c.prevStats.convertSnapshot(c.prevTime)
|
||||
}
|
||||
curr := c.nowStats.convertSnapshot(c.nowTime)
|
||||
diff := calculateHttpStatsDiff(prev, curr)
|
||||
metrics := diff.metrics("test", "test", "test", "test")
|
||||
t.Log(jsonutils.Marshal(metrics).PrettyString())
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user