mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-21 00:24:07 +08:00
Compare commits
268 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d8a727eb8 | ||
|
|
49366c5174 | ||
|
|
a50782ab52 | ||
|
|
974dd220e8 | ||
|
|
bf99c1d824 | ||
|
|
678626ff3a | ||
|
|
8b6791b908 | ||
|
|
78b5b0a94c | ||
|
|
cb264e7d1a | ||
|
|
6fb58e8c63 | ||
|
|
4c12de8eea | ||
|
|
e55aa144fa | ||
|
|
a55732b782 | ||
|
|
128ea60569 | ||
|
|
0988bf1578 | ||
|
|
42612205fd | ||
|
|
de48910c63 | ||
|
|
c80945338e | ||
|
|
96973b15bd | ||
|
|
04521a1548 | ||
|
|
9025a56617 | ||
|
|
973ebbf9f3 | ||
|
|
c53164e430 | ||
|
|
95aaa66c76 | ||
|
|
1e2773bd18 | ||
|
|
e6ba4a1dc7 | ||
|
|
e5afb63551 | ||
|
|
ced94cfb66 | ||
|
|
628244f7b9 | ||
|
|
7033974ab4 | ||
|
|
cb733ded80 | ||
|
|
658d734ec4 | ||
|
|
2f3e6f80a7 | ||
|
|
c4b5f59e11 | ||
|
|
5a5cca4110 | ||
|
|
5f8c36b407 | ||
|
|
a62ac5fb30 | ||
|
|
9694075bee | ||
|
|
4e84ace30a | ||
|
|
e96dbaba60 | ||
|
|
05d7a87c1b | ||
|
|
d94ddc43a4 | ||
|
|
57d3e37c08 | ||
|
|
ce7dd991d2 | ||
|
|
6364389877 | ||
|
|
3c2f99313b | ||
|
|
e91bc4e8fb | ||
|
|
946a0395ad | ||
|
|
dea562a733 | ||
|
|
a552c3ff85 | ||
|
|
cc5d7713e4 | ||
|
|
a94b00604d | ||
|
|
3d5361bee1 | ||
|
|
8c44e4e3e9 | ||
|
|
d46f44ccc1 | ||
|
|
3f06837b92 | ||
|
|
2c6aa4fb09 | ||
|
|
7835d0521b | ||
|
|
a43a3dc4bc | ||
|
|
99fb78de35 | ||
|
|
e7d67a41f5 | ||
|
|
5f1d1f748f | ||
|
|
8189fdb496 | ||
|
|
609db4298d | ||
|
|
09f31ce467 | ||
|
|
7cad0e5ee6 | ||
|
|
d5355f21bb | ||
|
|
e9f6a90bc5 | ||
|
|
b281ab8543 | ||
|
|
60b333bd1f | ||
|
|
b3093fbfd6 | ||
|
|
f8822c745a | ||
|
|
4c3adeb328 | ||
|
|
25c473a435 | ||
|
|
d65471ec41 | ||
|
|
8961bf4968 | ||
|
|
157921f5c4 | ||
|
|
cd65b9498b | ||
|
|
f850e179f2 | ||
|
|
cf7c8fb03f | ||
|
|
ace44f9490 | ||
|
|
72f6412f6c | ||
|
|
1eeb11be87 | ||
|
|
acab975d94 | ||
|
|
b2c52fd1fe | ||
|
|
e6975a6474 | ||
|
|
7c1d16cc63 | ||
|
|
17c6698073 | ||
|
|
ea4f290f8c | ||
|
|
c5e8ff9b39 | ||
|
|
10ad4c32dc | ||
|
|
625d7ef304 | ||
|
|
f68567e28c | ||
|
|
a368985923 | ||
|
|
a12e235fe3 | ||
|
|
27ec4567cc | ||
|
|
020092cc4d | ||
|
|
d64f80ddc8 | ||
|
|
cee3246346 | ||
|
|
7da7ffcb7a | ||
|
|
22e2896afc | ||
|
|
c63ed9093b | ||
|
|
9f4fc77bd2 | ||
|
|
8702653395 | ||
|
|
44d738a0b8 | ||
|
|
032353b0cc | ||
|
|
a6a2e4c288 | ||
|
|
0f67656287 | ||
|
|
5ad7bbf61c | ||
|
|
22dbb38ff5 | ||
|
|
420c1968dc | ||
|
|
07f482da0f | ||
|
|
dbee3ec258 | ||
|
|
aab33d1355 | ||
|
|
8e495f1589 | ||
|
|
67513c50c8 | ||
|
|
95abcef299 | ||
|
|
1c2472ae87 | ||
|
|
ce3e4ac385 | ||
|
|
5e787456b7 | ||
|
|
5a55a17967 | ||
|
|
c1a03c16b3 | ||
|
|
1fc6c8b42e | ||
|
|
a51b977953 | ||
|
|
b6fc27d64f | ||
|
|
aa2445d1c4 | ||
|
|
80670214be | ||
|
|
76c9d8a5ae | ||
|
|
5fd3aebbb1 | ||
|
|
04d533138f | ||
|
|
7547142600 | ||
|
|
7166a100ec | ||
|
|
3ff4d65300 | ||
|
|
b61399f12e | ||
|
|
1d4565807f | ||
|
|
5b232c2ff2 | ||
|
|
281698906d | ||
|
|
c25535d21b | ||
|
|
cb0d0b68b2 | ||
|
|
f6c9aa09ea | ||
|
|
2eec54723e | ||
|
|
f78047601b | ||
|
|
63cd9bec46 | ||
|
|
57bc6f1445 | ||
|
|
d5e6532711 | ||
|
|
4d511c98e9 | ||
|
|
f96c1f9fd2 | ||
|
|
315054703c | ||
|
|
f9064a0018 | ||
|
|
6641eb15f0 | ||
|
|
59f837c0e3 | ||
|
|
e5891349cd | ||
|
|
fe9f5fa4cc | ||
|
|
76b110445e | ||
|
|
d274e3078c | ||
|
|
e1269cf9fe | ||
|
|
5a972e6ddf | ||
|
|
a905f67fb2 | ||
|
|
9bca310026 | ||
|
|
edcbf3b2d3 | ||
|
|
e09c21d452 | ||
|
|
f270daa6ae | ||
|
|
49d1f6ee1e | ||
|
|
bdf015668f | ||
|
|
334ae46514 | ||
|
|
cbbf5c28e1 | ||
|
|
f517795c85 | ||
|
|
82b05b2cd1 | ||
|
|
429d38f06d | ||
|
|
b50d54d8cc | ||
|
|
d4104bb98d | ||
|
|
c8b1cfc397 | ||
|
|
df3d24b40a | ||
|
|
3483446885 | ||
|
|
b84b5786ed | ||
|
|
ad4f0da021 | ||
|
|
31aa3e36ee | ||
|
|
c4c095e0f8 | ||
|
|
a9a1c64ef0 | ||
|
|
dda5a309ac | ||
|
|
328dcf8ebb | ||
|
|
7628bd2a81 | ||
|
|
237a54a79f | ||
|
|
1927f32109 | ||
|
|
9dcabdb247 | ||
|
|
6785b43bad | ||
|
|
a51f8b6c2c | ||
|
|
40127b24e6 | ||
|
|
d2f608696f | ||
|
|
a38f03516e | ||
|
|
e7935d6412 | ||
|
|
4a72e87323 | ||
|
|
a6295d340a | ||
|
|
e8338f2832 | ||
|
|
f87d0e905a | ||
|
|
9274649334 | ||
|
|
13b05bf0c6 | ||
|
|
2069057967 | ||
|
|
197ff6f805 | ||
|
|
c52ee7d073 | ||
|
|
3eafa21456 | ||
|
|
749d063a61 | ||
|
|
7ee8b8abe5 | ||
|
|
3353aa0062 | ||
|
|
8e493053ee | ||
|
|
eb307bbffd | ||
|
|
904f6b3358 | ||
|
|
161cec3a08 | ||
|
|
8c6d9ad876 | ||
|
|
bdeed9e7a8 | ||
|
|
b9f3f55e62 | ||
|
|
aa60326bc3 | ||
|
|
43deb292fb | ||
|
|
99eaebe34a | ||
|
|
5afb0c82a8 | ||
|
|
8fbd42e535 | ||
|
|
c57c4cc5b2 | ||
|
|
c7ad1243be | ||
|
|
18b008d838 | ||
|
|
36b91f5afe | ||
|
|
fe0f3b01b9 | ||
|
|
45219f3cf4 | ||
|
|
eebdd2b591 | ||
|
|
18e806ba7d | ||
|
|
45dd2ece7c | ||
|
|
bb62477f80 | ||
|
|
a6340afcbe | ||
|
|
fc9e1719b7 | ||
|
|
73a8a01b63 | ||
|
|
1455c52270 | ||
|
|
c810ea46c6 | ||
|
|
9b9bcc881e | ||
|
|
0a4ad0a305 | ||
|
|
4573622ba5 | ||
|
|
11cd699c9c | ||
|
|
ef873d9f77 | ||
|
|
7ca332aa79 | ||
|
|
eca062143b | ||
|
|
9b6fe19ea4 | ||
|
|
f0e61cd918 | ||
|
|
a0170df031 | ||
|
|
c78f7a2f04 | ||
|
|
cb9b344bd4 | ||
|
|
b9c4336dff | ||
|
|
e5f352fa37 | ||
|
|
f0862574db | ||
|
|
d7978069a9 | ||
|
|
1df2e03b73 | ||
|
|
9c2502db8d | ||
|
|
22f188f8c0 | ||
|
|
d4656072de | ||
|
|
db34e8ad3b | ||
|
|
dd390aa6dd | ||
|
|
e9b0203da4 | ||
|
|
08c5f3c816 | ||
|
|
5317e842f3 | ||
|
|
afe7f5d828 | ||
|
|
c8966f7e87 | ||
|
|
f89c9b933a | ||
|
|
66c6a7570c | ||
|
|
297d905d4f | ||
|
|
c24c923a8f | ||
|
|
40909986f6 | ||
|
|
48d6492715 | ||
|
|
fcc635a90e | ||
|
|
38582f5f93 | ||
|
|
8deacfcf59 | ||
|
|
f1d422e85f |
@@ -1,4 +1,4 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/baremetal-base:v0.3.2
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/baremetal-base:v0.3.3
|
||||
|
||||
MAINTAINER "Zexi Li <lizexi@yunionyun.com>"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
FROM --platform=linux/amd64 registry.cn-beijing.aliyuncs.com/yunionio/centos-build:1.1-4 as build
|
||||
RUN yum install -y https://iso.yunion.cn/vm-images/baremetal-pxerom-1.1.0-21080303.x86_64.rpm
|
||||
#RUN yum install -y http://192.168.122.112:8083/baremetal-pxerom-1.1.0-21080303.x86_64.rpm
|
||||
RUN yum install -y https://iso.yunion.cn/vm-images/baremetal-pxerom-1.1.0-21092209.x86_64.rpm
|
||||
#RUN yum install -y http://192.168.23.50:8083/baremetal-pxerom-1.1.0-21092209.x86_64.rpm
|
||||
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.3.5
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/climc-base:20210817
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/climc-base:20210901
|
||||
|
||||
ADD ./build/climc/root/opt /opt
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ RUN mkdir -p /opt/yunion/bin
|
||||
|
||||
RUN echo http://dl-cdn.alpinelinux.org/alpine/edge/testing >>/etc/apk/repositories
|
||||
|
||||
RUN apk add --no-cache bash bash-completion tzdata ca-certificates vim ipmitool kubectl && \
|
||||
RUN apk add --no-cache bash bash-completion tzdata ca-certificates vim ipmitool kubectl ceph-common && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
|
||||
@@ -4,6 +4,5 @@ MAINTAINER "Yaoqi Wan wanyaoqi@yunionyun.com"
|
||||
|
||||
ENV TZ Asia/Shanghai
|
||||
|
||||
RUN apk add librados librbd
|
||||
RUN mkdir -p /opt/yunion/bin
|
||||
ADD ./_output/alpine-build/bin/host /opt/yunion/bin/host
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/host-deployer-base:1.0
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/host-deployer-base:1.1
|
||||
|
||||
MAINTAINER "Yaoqi Wan wanyaoqi@yunionyun.com"
|
||||
|
||||
|
||||
@@ -17,13 +17,13 @@ ANSIBLESERVER_BASE = v1.0.5
|
||||
ansibleserver-base:
|
||||
$(DOCKER_BUILDX)/ansibleserver-base:$(ANSIBLESERVER_BASE) -f ./Dockerfile.ansibleserver-base .
|
||||
|
||||
CLIMC_BASE_VERSION = 20210817
|
||||
CLIMC_BASE_VERSION = 20210901
|
||||
|
||||
climc-base:
|
||||
docker buildx build --platform linux/arm64,linux/amd64 --push \
|
||||
-t registry.cn-beijing.aliyuncs.com/yunionio/climc-base:$(CLIMC_BASE_VERSION) -f ./Dockerfile.climc-base .
|
||||
|
||||
BAREMETAL_BASE_VERSION = v0.3.2
|
||||
BAREMETAL_BASE_VERSION = v0.3.3
|
||||
|
||||
baremetal-base:
|
||||
$(DOCKER_BUILDX)/baremetal-base:$(BAREMETAL_BASE_VERSION) -f ./Dockerfile.baremetal-base .
|
||||
|
||||
@@ -13,6 +13,5 @@ MAINTAINER "Yaoqi Wan wanyaoqi@yunionyun.com"
|
||||
|
||||
ENV TZ Asia/Shanghai
|
||||
|
||||
RUN apk add librados librbd
|
||||
RUN mkdir -p /opt/yunion/bin
|
||||
COPY --from=build /root/go/src/yunion.io/x/onecloud/_output/bin/host /opt/yunion/bin/host
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
,外网地址为{{ $d.public_dns }}:{{ $d.public_connect_port }}
|
||||
{{- end -}}
|
||||
|
||||
{{- if and $d.address_type $d.address -}}
|
||||
,服务地址为{{ $d.address_type }}{{ $d.address }}
|
||||
{{- if $d.address -}}
|
||||
,服务地址为{{ $d.address }}
|
||||
{{- end -}}
|
||||
|
||||
{{- if $d.ips -}}
|
||||
@@ -29,8 +29,8 @@
|
||||
,IP地址为{{ $d.ip_addr }}
|
||||
{{- end -}}
|
||||
|
||||
{{- if $d.account -}}
|
||||
,初始帐号为{{ $d.account }}
|
||||
{{- if $d.login_account -}}
|
||||
,初始帐号为{{ $d.login_account }}
|
||||
{{- end -}}
|
||||
|
||||
{{- if $d.password -}}
|
||||
@@ -56,7 +56,7 @@
|
||||
{{- else -}}
|
||||
SSH
|
||||
{{- end -}}
|
||||
或控制面板控制台访问虚拟机。
|
||||
或前往控制台访问虚拟机。
|
||||
{{- end -}}
|
||||
|
||||
{{- if has .resource_type $consoleServiceType -}}
|
||||
|
||||
@@ -3,4 +3,12 @@
|
||||
{{- if $d.brand -}}
|
||||
{{ $d.brand }}平台
|
||||
{{- end -}}
|
||||
|
||||
{{- if $d.private_dns -}}
|
||||
,内网地址为{{ $d.private_dns }}:{{ $d.private_connect_port }}
|
||||
{{- end -}}
|
||||
|
||||
{{- if $d.public_dns -}}
|
||||
,外网地址为{{ $d.public_dns }}:{{ $d.public_connect_port }}的
|
||||
{{- end -}}
|
||||
{{ .resource_type_display }}{{ $d.name }}还有{{ .advance_days }}天就要到期释放,如需续期使用,请尽快前往控制台处理
|
||||
|
||||
@@ -9,8 +9,8 @@ Your {{ if $d.brand -}} {{ $d.brand }} {{ end -}} {{ .resource_type_display }} {
|
||||
, the internet address is {{ $d.public_dns }}:{{ $d.public_connect_port }}
|
||||
{{- end -}}
|
||||
|
||||
{{- if and $d.address_type $d.address -}}
|
||||
, the service address is {{ $d.address_type }}{{ $d.address }}
|
||||
{{- if $d.address -}}
|
||||
, the service address is {{ $d.address }}
|
||||
{{- end -}}
|
||||
|
||||
{{- if $d.ips -}}
|
||||
@@ -46,7 +46,7 @@ Your {{ if $d.brand -}} {{ $d.brand }} {{ end -}} {{ .resource_type_display }} {
|
||||
{{- end -}}
|
||||
|
||||
{{- if eq .resource_type "server" -}}
|
||||
, and please use {{ if $d.windows -}} Remote Desktop Connector (RDC) {{ else -}} SSH {{ end -}} or the control panel console to access the VM.
|
||||
, and please use {{ if $d.windows -}} Remote Desktop Connector (RDC) {{ else -}} SSH {{ end -}} or go to the console to access the VM.
|
||||
{{- end -}}
|
||||
|
||||
{{- if has .resource_type $consoleServiceType -}}
|
||||
|
||||
@@ -6,7 +6,7 @@ Your {{ if $d.brand -}} {{ $d.brand }} {{ end -}} {{ .resource_type_display }} {
|
||||
{{- end -}}
|
||||
|
||||
{{- if $d.public_dns -}}
|
||||
, the internet address is {{ $d.public_dns }}:{{ $d.public_connect_port }}
|
||||
, the external address is {{ $d.public_dns }}:{{ $d.public_connect_port }}
|
||||
{{- end -}}
|
||||
|
||||
{{- if and $d.address_type $d.address -}}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
{{- $d := .resource_details -}}
|
||||
Your {{ if $d.brand -}} {{ $d.brand }} {{ end -}} {{ .resource_type }} {{ $d.name }} {{ if $d.project -}} in project {{ $d.project }} {{ end -}} will expire and be released in {{ .advance_days }} days. If you need to renew, please go to the console as soon as possible
|
||||
Your {{ if $d.brand -}} {{ $d.brand }} {{ end -}} {{ .resource_type }} {{ $d.name }} {{ if $d.public_dns -}} with external address {{ $d.public_dns }}:{{ $d.public_connect_port }} {{ end -}} {{ if $d.project -}} in project {{ $d.project }} {{ end -}} will expire and be released in {{ .advance_days }} days. If you need to renew, please go to the console as soon as possible
|
||||
|
||||
@@ -37,7 +37,7 @@ func init() {
|
||||
cmd.CreateWithKeyword("create-aws", &options.SAWSCloudAccountCreateOptions{})
|
||||
cmd.CreateWithKeyword("create-openstack", &options.SOpenStackCloudAccountCreateOptions{})
|
||||
cmd.CreateWithKeyword("create-huawei", &options.SHuaweiCloudAccountCreateOptions{})
|
||||
cmd.CreateWithKeyword("create-huaweicloudstack", &options.SHuaweiCloudStackAccountCreateOptions{})
|
||||
cmd.CreateWithKeyword("create-hcso", &options.SHCSOAccountCreateOptions{})
|
||||
cmd.CreateWithKeyword("create-ucloud", &options.SUcloudCloudAccountCreateOptions{})
|
||||
cmd.CreateWithKeyword("create-zstack", &options.SZStackCloudAccountCreateOptions{})
|
||||
cmd.CreateWithKeyword("create-s3", &options.SS3CloudAccountCreateOptions{})
|
||||
@@ -57,7 +57,7 @@ func init() {
|
||||
cmd.UpdateWithKeyword("update-aws", &options.SAWSCloudAccountUpdateOptions{})
|
||||
cmd.UpdateWithKeyword("update-openstack", &options.SOpenStackCloudAccountUpdateOptions{})
|
||||
cmd.UpdateWithKeyword("update-huawei", &options.SHuaweiCloudAccountUpdateOptions{})
|
||||
cmd.UpdateWithKeyword("update-huaweicloudstack", &options.SHuaweiCloudStackAccountUpdateOptions{})
|
||||
cmd.UpdateWithKeyword("update-hcso", &options.SHCSOAccountUpdateOptions{})
|
||||
cmd.UpdateWithKeyword("update-ucloud", &options.SUcloudCloudAccountUpdateOptions{})
|
||||
cmd.UpdateWithKeyword("update-zstack", &options.SZStackCloudAccountUpdateOptions{})
|
||||
cmd.UpdateWithKeyword("update-s3", &options.SS3CloudAccountUpdateOptions{})
|
||||
@@ -75,7 +75,7 @@ func init() {
|
||||
cmd.PerformWithKeyword("update-credential-aws", "update-credential", &options.SAWSCloudAccountUpdateCredentialOptions{})
|
||||
cmd.PerformWithKeyword("update-credential-openstack", "update-credential", &options.SOpenStackCloudAccountUpdateCredentialOptions{})
|
||||
cmd.PerformWithKeyword("update-credential-huawei", "update-credential", &options.SHuaweiCloudAccountUpdateCredentialOptions{})
|
||||
cmd.PerformWithKeyword("update-credential-huaweicloudstack", "update-credential", &options.SHuaweiCloudStackAccountUpdateCredentialOptions{})
|
||||
cmd.PerformWithKeyword("update-credential-hcso", "update-credential", &options.SHCSOAccountUpdateCredentialOptions{})
|
||||
cmd.PerformWithKeyword("update-credential-ucloud", "update-credential", &options.SUcloudCloudAccountUpdateCredentialOptions{})
|
||||
cmd.PerformWithKeyword("update-credential-zstack", "update-credential", &options.SZStackCloudAccountUpdateCredentialOptions{})
|
||||
cmd.PerformWithKeyword("update-credential-s3", "update-credential", &options.SS3CloudAccountUpdateCredentialOptions{})
|
||||
|
||||
@@ -15,10 +15,12 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/cmd/climc/shell"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
@@ -26,6 +28,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
|
||||
"yunion.io/x/onecloud/pkg/util/fileutils2"
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
"yunion.io/x/onecloud/pkg/util/ssh"
|
||||
)
|
||||
|
||||
@@ -43,7 +46,7 @@ func init() {
|
||||
cmd.Perform("start", &options.BaseIdOptions{})
|
||||
cmd.Perform("stop", &options.BaseIdOptions{})
|
||||
cmd.Perform("reset", &options.BaseIdOptions{})
|
||||
cmd.Perform("delete", &options.BaseIdOptions{})
|
||||
cmd.BatchDelete(&options.BaseIdsOptions{})
|
||||
cmd.Perform("remove-all-netifs", &options.BaseIdOptions{})
|
||||
|
||||
cmd.BatchPerform("enable", &options.BaseIdsOptions{})
|
||||
@@ -523,9 +526,36 @@ func init() {
|
||||
return e
|
||||
}
|
||||
i, e := modules.Hosts.GetLoginInfo(s, srvid, nil)
|
||||
privateKey := ""
|
||||
if e != nil {
|
||||
return e
|
||||
if httputils.ErrorCode(e) == 404 || e.Error() == "ciphertext too short" {
|
||||
var err error
|
||||
privateKey, err = modules.Sshkeypairs.FetchPrivateKeyBySession(context.Background(), s)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "fetch private key")
|
||||
}
|
||||
params := jsonutils.NewDict()
|
||||
params.Add(jsonutils.NewString(string(args.ID)), "ID")
|
||||
ret, err := modules.Hosts.Get(s, args.ID, params)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get host by ID")
|
||||
}
|
||||
ip, err := ret.GetString("access_ip")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get the ip of the host")
|
||||
}
|
||||
|
||||
jsonItem := jsonutils.NewDict()
|
||||
jsonItem.Add(jsonutils.NewString(ip), "ip")
|
||||
jsonItem.Add(jsonutils.NewString("root"), "username")
|
||||
jsonItem.Add(jsonutils.NewString(""), "password")
|
||||
jsonItem.Add(jsonutils.NewInt(22), "port")
|
||||
i = jsonItem
|
||||
} else {
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
host, err := i.GetString("ip")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -542,7 +572,7 @@ func init() {
|
||||
if args.Port != 22 {
|
||||
port = args.Port
|
||||
}
|
||||
sshCli, err := ssh.NewClient(host, port, user, passwd, "")
|
||||
sshCli, err := ssh.NewClient(host, port, user, passwd, privateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@@ -88,6 +89,7 @@ func init() {
|
||||
cmd.Perform("create-eip", &options.ServerCreateEipOptions{})
|
||||
cmd.Perform("make-sshable", &options.ServerMakeSshableOptions{})
|
||||
cmd.Perform("migrate-network", &options.ServerMigrateNetworkOptions{})
|
||||
cmd.Perform("set-sshport", &options.ServerSetSshportOptions{})
|
||||
|
||||
cmd.Get("vnc", new(options.ServerIdOptions))
|
||||
cmd.Get("desc", new(options.ServerIdOptions))
|
||||
@@ -99,6 +101,8 @@ func init() {
|
||||
cmd.Get("change-owner-candidate-domains", new(options.ServerChangeOwnerCandidateDomainsOptions))
|
||||
cmd.Get("change-owner-candidate-domains", new(options.ServerChangeOwnerCandidateDomainsOptions))
|
||||
cmd.GetProperty(&options.ServerStatusStatisticsOptions{})
|
||||
cmd.GetProperty(&options.ServerProjectStatisticsOptions{})
|
||||
cmd.GetProperty(&options.ServerDomainStatisticsOptions{})
|
||||
|
||||
type ServerTaskShowOptions struct {
|
||||
ID string `help:"ID or name of server" json:"-"`
|
||||
@@ -817,13 +821,15 @@ func init() {
|
||||
return fmt.Errorf("Not found ip address from server %s", opts.ID)
|
||||
}
|
||||
|
||||
privateKey := ""
|
||||
params := jsonutils.NewDict()
|
||||
if len(opts.Key) > 0 {
|
||||
privateKey, e := ioutil.ReadFile(opts.Key)
|
||||
key, e := ioutil.ReadFile(opts.Key)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
params.Add(jsonutils.NewString(string(privateKey)), "private_key")
|
||||
params.Add(jsonutils.NewString(string(key)), "private_key")
|
||||
privateKey = string(key)
|
||||
}
|
||||
|
||||
i, e := modules.Servers.GetLoginInfo(s, srvid, params)
|
||||
@@ -831,14 +837,14 @@ func init() {
|
||||
return e
|
||||
}
|
||||
passwd, err := i.GetString("password")
|
||||
if err != nil {
|
||||
if err != nil && !opts.UseCloudroot {
|
||||
return err
|
||||
}
|
||||
if opts.Password != "" {
|
||||
passwd = opts.Password
|
||||
}
|
||||
user, err := i.GetString("username")
|
||||
if err != nil {
|
||||
if err != nil && !opts.UseCloudroot {
|
||||
return err
|
||||
}
|
||||
if opts.User != "" {
|
||||
@@ -868,8 +874,22 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
if opts.UseCloudroot {
|
||||
var err error
|
||||
privateKey, err = modules.Sshkeypairs.FetchPrivateKeyBySession(context.Background(), s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
passwd = ""
|
||||
user = "cloudroot"
|
||||
}
|
||||
|
||||
var sshCli *ssh.Client
|
||||
for sshCli, err = ssh.NewClient(host, port, user, passwd, ""); err != nil; {
|
||||
err = nil
|
||||
for ; sshCli == nil; sshCli, err = ssh.NewClient(host, port, user, passwd, privateKey) {
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
if opts.Host != "" {
|
||||
return err
|
||||
}
|
||||
@@ -877,12 +897,14 @@ func init() {
|
||||
closeForward(s, srvid, forwardItem)
|
||||
return err
|
||||
} else {
|
||||
forwardItem, err = openForward(s, srvid)
|
||||
if err != nil {
|
||||
return err
|
||||
if vpcid != "default" {
|
||||
forwardItem, e = openForward(s, srvid)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
host = forwardItem.ProxyAddr
|
||||
port = forwardItem.ProxyPort
|
||||
}
|
||||
host = forwardItem.ProxyAddr
|
||||
port = forwardItem.ProxyPort
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
29
cmd/climc/shell/devtool/serviceurl.go
Normal file
29
cmd/climc/shell/devtool/serviceurl.go
Normal file
@@ -0,0 +1,29 @@
|
||||
// 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 devtool
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/cmd/climc/shell"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
options "yunion.io/x/onecloud/pkg/mcclient/options/devtool"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmd := shell.NewResourceCmd(&modules.DevToolServiceUrls).WithKeyword("devtool-serviceurl")
|
||||
cmd.List(new(options.ServiceUrlListOptions))
|
||||
cmd.Create(new(options.ServiceUrlCreateOptions))
|
||||
cmd.Show(new(options.ServiceUrlOptions))
|
||||
cmd.Delete(new(options.ServiceUrlOptions))
|
||||
}
|
||||
29
cmd/climc/shell/devtool/sshinfo.go
Normal file
29
cmd/climc/shell/devtool/sshinfo.go
Normal file
@@ -0,0 +1,29 @@
|
||||
// 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 devtool
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/cmd/climc/shell"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
options "yunion.io/x/onecloud/pkg/mcclient/options/devtool"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmd := shell.NewResourceCmd(&modules.DevToolSshInfos).WithKeyword("devtool-sshinfo")
|
||||
cmd.List(new(options.SshInfoListOptions))
|
||||
cmd.Create(new(options.SshInfoCreateOptions))
|
||||
cmd.Show(new(options.SshInfoOptions))
|
||||
cmd.Delete(new(options.SshInfoOptions))
|
||||
}
|
||||
@@ -44,13 +44,14 @@ type BaseEventListOptions struct {
|
||||
|
||||
type EventListOptions struct {
|
||||
BaseEventListOptions
|
||||
Id string `help:"" metavar:"OBJ_ID"`
|
||||
Id []string `help:"object IDs" metavar:"OBJ_ID"`
|
||||
Name []string `help:"object names" metavar:"OBJ_NAME"`
|
||||
Type []string `help:"Type of relevant object" metavar:"OBJ_TYPE"`
|
||||
}
|
||||
|
||||
type TypeEventListOptions struct {
|
||||
BaseEventListOptions
|
||||
ID string `help:"" metavar:"OBJ_ID"`
|
||||
ID []string `help:"object IDs" metavar:"OBJ_ID"`
|
||||
}
|
||||
|
||||
func doComputeEventList(s *mcclient.ClientSession, args *EventListOptions) error {
|
||||
@@ -71,7 +72,10 @@ func DoEventList(man modulebase.ResourceManager, s *mcclient.ClientSession, args
|
||||
params.Add(jsonutils.NewStringArray(args.Type), "obj_type")
|
||||
}
|
||||
if len(args.Id) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Id), "obj_id")
|
||||
params.Add(jsonutils.NewStringArray(args.Id), "obj_id")
|
||||
}
|
||||
if len(args.Name) > 0 {
|
||||
params.Add(jsonutils.NewStringArray(args.Name), "obj_name")
|
||||
}
|
||||
if len(args.Since) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Since), "since")
|
||||
|
||||
@@ -16,7 +16,6 @@ package shell
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/pkg/util/timeutils"
|
||||
|
||||
@@ -110,7 +109,7 @@ func init() {
|
||||
}
|
||||
fmt.Println("primary key hash:", fm.PrimaryKeyHash())
|
||||
|
||||
ret := fm.Decrypt([]byte(args.MSG), time.Hour*-1)
|
||||
ret := fm.Decrypt([]byte(args.MSG))
|
||||
if len(ret) == 0 {
|
||||
return fmt.Errorf("invalid message")
|
||||
}
|
||||
|
||||
@@ -21,13 +21,13 @@ import (
|
||||
"yunion.io/x/structarg"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
huawei "yunion.io/x/onecloud/pkg/multicloud/huaweistack"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/huaweistack/shell"
|
||||
huawei "yunion.io/x/onecloud/pkg/multicloud/hcso"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/hcso/shell"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
type BaseOptions struct {
|
||||
cloudprovider.SHuaweiCloudStackEndpoints
|
||||
cloudprovider.SHCSOEndpoints
|
||||
Help bool `help:"Show help" default:"false"`
|
||||
Debug bool `help:"Show debug" default:"false"`
|
||||
AccessKey string `help:"Access key" default:"$HUAWEI_ACCESS_KEY" metavar:"HUAWEI_ACCESS_KEY"`
|
||||
@@ -92,7 +92,7 @@ func newClient(options *BaseOptions) (*huawei.SRegion, error) {
|
||||
options.AccessKey,
|
||||
options.Secret,
|
||||
options.ProjectId,
|
||||
&options.SHuaweiCloudStackEndpoints,
|
||||
&options.SHCSOEndpoints,
|
||||
).Debug(options.Debug),
|
||||
)
|
||||
if err != nil {
|
||||
6
go.mod
6
go.mod
@@ -40,6 +40,7 @@ require (
|
||||
github.com/coredns/coredns v1.3.0
|
||||
github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a // indirect
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
|
||||
github.com/creack/pty v1.1.11
|
||||
github.com/dnaeon/go-vcr v1.1.0 // indirect
|
||||
github.com/dnstap/golang-dnstap v0.0.0-20170829151710-2cf77a2b5e11 // indirect
|
||||
github.com/eapache/go-resiliency v1.1.0 // indirect
|
||||
@@ -78,7 +79,6 @@ require (
|
||||
github.com/jdcloud-api/jdcloud-sdk-go v1.55.0
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
|
||||
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
|
||||
github.com/kr/pty v1.1.5
|
||||
github.com/lestrrat-go/jwx v1.0.2
|
||||
github.com/lestrrat/go-jwx v0.0.0-20180221005942-b7d4802280ae
|
||||
github.com/lestrrat/go-pdebug v0.0.0-20180220043741-569c97477ae8 // indirect
|
||||
@@ -153,9 +153,9 @@ require (
|
||||
yunion.io/x/jsonutils v0.0.0-20210709075951-798a67800349
|
||||
yunion.io/x/log v0.0.0-20201210064738-43181789dc74
|
||||
yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7
|
||||
yunion.io/x/pkg v0.0.0-20210721081124-55078288ca4c
|
||||
yunion.io/x/pkg v0.0.0-20210918114143-ce839f862c5f
|
||||
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e
|
||||
yunion.io/x/sqlchemy v0.0.0-20210619142628-653684d2c4f8
|
||||
yunion.io/x/sqlchemy v0.0.0-20210918113031-c1c107f37ada
|
||||
yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce
|
||||
)
|
||||
|
||||
|
||||
32
go.sum
32
go.sum
@@ -172,6 +172,8 @@ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfc
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -224,8 +226,6 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.5.0 h1:fi+bqFAx/oLK54somfCtEZs9HeH1LHVoEPUgARpTqyc=
|
||||
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
|
||||
github.com/gin-gonic/gin v1.7.0 h1:jGB9xAJQ12AIGNB4HguylppmDK1Am9ppF7XnGXXJuoU=
|
||||
github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
@@ -250,13 +250,10 @@ github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+
|
||||
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.12.1 h1:2FITxuFt/xuCNP1Acdhv62OzaCiviiE4kotfhkmOqEc=
|
||||
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
|
||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/universal-translator v0.16.0 h1:X++omBR/4cE2MNg91AoC3rmGrCjJ8eAeUP/K/EKx4DM=
|
||||
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
|
||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
|
||||
@@ -342,8 +339,6 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR
|
||||
github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=
|
||||
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gosuri/uilive v0.0.0-20170323041506-ac356e6e42cd/go.mod h1:qkLSc0A5EXSP6B04TrN4oQoxqFI7A8XvoXSlJi8cwk8=
|
||||
@@ -411,12 +406,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
|
||||
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5 h1:hyz3dwM5QLc1Rfoz4FuWJQG5BN7tc6K1MndAUnGpQr4=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
|
||||
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
|
||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/lestrrat-go/iter v0.0.0-20200422075355-fc1769541911 h1:FvnrqecqX4zT0wOIbYK1gNgTm0677INEWiFY8UEYggY=
|
||||
@@ -440,8 +431,6 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.9 h1:d5US/mDsogSGW37IV293h//ZFaeajb69h+EHFsv2xGg=
|
||||
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
@@ -471,8 +460,6 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1f
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/mholt/caddy v0.10.11 h1:s8X+R8DuBbrrMuUTcWSxlDe567B0s5EDmiDBKSYsioY=
|
||||
github.com/mholt/caddy v0.10.11/go.mod h1:Wb1PlT4DAYSqOEd03MsqkdkXnTxA8v9pKjdpxbqM1kY=
|
||||
github.com/miekg/dns v1.1.4 h1:rCMZsU2ScVSYcAsOXgmC6+AKOK+6pmQTOcw03nfwYV0=
|
||||
github.com/miekg/dns v1.1.4/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.25 h1:dFwPR6SfLtrSwgDcIq2bcU/gVutB4sNApq2HBdqcakg=
|
||||
github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||
github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc=
|
||||
@@ -755,7 +742,6 @@ golang.org/x/sys v0.0.0-20190606122018-79a91cf218c4/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190830023255-19e00faab6ad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -878,10 +864,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fatih/set.v0 v0.2.1 h1:Xvyyp7LXu34P0ROhCyfXkmQCAoOUKb1E2JS9I7SE5CY=
|
||||
gopkg.in/fatih/set.v0 v0.2.1/go.mod h1:5eLWEndGL4zGGemXWrKuts+wTJR0y+w+auqUJZbmyBg=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
|
||||
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
@@ -941,11 +923,11 @@ yunion.io/x/ovsdb v0.0.0-20200526071744-27bf0940cbc7/go.mod h1:0vLkNEhlmA64HViPB
|
||||
yunion.io/x/pkg v0.0.0-20190620104149-945c25821dbf/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v0.0.0-20190628082551-f4033ba2ea30/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v0.0.0-20200814072949-4f1b541857d6/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v0.0.0-20210721081124-55078288ca4c h1:/ejlt78/0xod4bdkEThUuYsQ7vLajd48wpL2GMMSaXs=
|
||||
yunion.io/x/pkg v0.0.0-20210721081124-55078288ca4c/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v0.0.0-20210918114143-ce839f862c5f h1:maply0f3AsvoXqkpTKkb6/tZFbRAT/rdkk1Cw3FkoB8=
|
||||
yunion.io/x/pkg v0.0.0-20210918114143-ce839f862c5f/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e h1:v+EzIadodSwkdZ/7bremd7J8J50Cise/HCylsOJngmo=
|
||||
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e/go.mod h1:0iFKpOs1y4lbCxeOmq3Xx/0AcQoewVPwj62eRluioEo=
|
||||
yunion.io/x/sqlchemy v0.0.0-20210619142628-653684d2c4f8 h1:+kywPlOttXAZvbxsVqR73B5GbSVgG3Xdo4socLWRkcg=
|
||||
yunion.io/x/sqlchemy v0.0.0-20210619142628-653684d2c4f8/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI=
|
||||
yunion.io/x/sqlchemy v0.0.0-20210918113031-c1c107f37ada h1:ZIhSSwFHfnzPMKSyiN0nkGwvC6RUeuCIAnWuTtDS900=
|
||||
yunion.io/x/sqlchemy v0.0.0-20210918113031-c1c107f37ada/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI=
|
||||
yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce h1:kU8xE7O5uZ1GSJVMZHoJ+jrNL7csUQHYGyAPW9QfNpE=
|
||||
yunion.io/x/structarg v0.0.0-20200720093445-9f850fa222ce/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng=
|
||||
|
||||
@@ -121,7 +121,7 @@ func (man *SAnsiblePlaybookManager) InitializeData() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (apb *SAnsiblePlaybook) ValidateDeleteCondition(ctx context.Context) error {
|
||||
func (apb *SAnsiblePlaybook) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
|
||||
if apb.Status == api.AnsiblePlaybookStatusRunning {
|
||||
return httperrors.NewConflictError("playbook is in running state")
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ func (man *SAnsiblePlaybookV2Manager) InitializeData() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (apb *SAnsiblePlaybookV2) ValidateDeleteCondition(ctx context.Context) error {
|
||||
func (apb *SAnsiblePlaybookV2) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
|
||||
if apb.Status == api.AnsiblePlaybookStatusRunning {
|
||||
return httperrors.NewConflictError("playbook is in running state")
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
package apihelper
|
||||
|
||||
import (
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
mcclient "yunion.io/x/onecloud/pkg/mcclient"
|
||||
mcclient_modulebase "yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
@@ -44,6 +46,14 @@ type IModelSetEmulatedIncluder interface {
|
||||
IncludeEmulated() bool
|
||||
}
|
||||
|
||||
type IModelSetFilter interface {
|
||||
ModelFilter() []string
|
||||
}
|
||||
|
||||
type IModelListParam interface {
|
||||
ModelParamFilter() jsonutils.JSONObject
|
||||
}
|
||||
|
||||
func SyncModelSets(mssOld IModelSets, s *mcclient.ClientSession, opt *Options) (r ModelSetsUpdateResult, err error) {
|
||||
mss := mssOld.ModelSetList()
|
||||
mssNews := mssOld.NewEmpty()
|
||||
|
||||
@@ -120,6 +120,10 @@ func GetModels(opts *GetModelsOptions) error {
|
||||
"cloud_env=onpremise",
|
||||
)
|
||||
}
|
||||
if inter, ok := opts.ModelSet.(IModelSetFilter); ok {
|
||||
filter := inter.ModelFilter()
|
||||
listOptions.Filter = append(listOptions.Filter, filter...)
|
||||
}
|
||||
if !minUpdatedAt.Equal(PseudoZeroTime) {
|
||||
// Only fetching pending deletes when we are doing incremental fetch
|
||||
listOptions.PendingDeleteAll = options.Bool(true)
|
||||
@@ -129,6 +133,10 @@ func GetModels(opts *GetModelsOptions) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("%s: making list params: %s", manKeyPlural, err)
|
||||
}
|
||||
if inter, ok := opts.ModelSet.(IModelListParam); ok {
|
||||
filter := inter.ModelParamFilter()
|
||||
params.Update(filter)
|
||||
}
|
||||
//XXX
|
||||
//params.Set(api.LBAGENT_QUERY_ORIG_KEY, jsonutils.NewString(api.LBAGENT_QUERY_ORIG_VAL))
|
||||
|
||||
|
||||
@@ -543,19 +543,6 @@ type ServerCloneInput struct {
|
||||
PreferHostId string `json:"prefer_host_id"`
|
||||
}
|
||||
|
||||
type ServerDeployInput struct {
|
||||
apis.Meta
|
||||
|
||||
Id string
|
||||
|
||||
Keypair string `json:"keypair"`
|
||||
DeleteKeypair *bool `json:"__delete_keypair__"`
|
||||
DeployConfigs []*DeployConfig `json:"deploy_configs"`
|
||||
ResetPassword *bool `json:"reset_password"`
|
||||
Password string `json:"password"`
|
||||
AutoStart *bool `json:"auto_start"`
|
||||
}
|
||||
|
||||
type GuestBatchMigrateRequest struct {
|
||||
apis.Meta
|
||||
|
||||
|
||||
@@ -29,12 +29,13 @@ const (
|
||||
|
||||
DEFAULT_DISK_TYPE = DISK_TYPE_ROTATE
|
||||
|
||||
DISK_DRIVER_MEGARAID = "MegaRaid"
|
||||
DISK_DRIVER_LINUX = "Linux"
|
||||
DISK_DRIVER_HPSARAID = "HPSARaid"
|
||||
DISK_DRIVER_MPT2SAS = "Mpt2SAS"
|
||||
DISK_DRIVER_MARVELRAID = "MarvelRaid"
|
||||
DISK_DRIVER_PCIE = "PCIE"
|
||||
DISK_DRIVER_MEGARAID = "MegaRaid"
|
||||
DISK_DRIVER_LINUX = "Linux"
|
||||
DISK_DRIVER_HPSARAID = "HPSARaid"
|
||||
DISK_DRIVER_MPT2SAS = "Mpt2SAS"
|
||||
DISK_DRIVER_MARVELRAID = "MarvelRaid"
|
||||
DISK_DRIVER_ADAPTECRAID = "AdaptecRaid"
|
||||
DISK_DRIVER_PCIE = "PCIE"
|
||||
|
||||
HDD_DISK_SPEC_TYPE = "HDD"
|
||||
SSD_DISK_SPEC_TYPE = "SSD"
|
||||
@@ -60,6 +61,7 @@ var (
|
||||
DISK_DRIVER_HPSARAID,
|
||||
DISK_DRIVER_MPT2SAS,
|
||||
DISK_DRIVER_MARVELRAID,
|
||||
DISK_DRIVER_ADAPTECRAID,
|
||||
)
|
||||
|
||||
DISK_DRIVERS = sets.NewString(
|
||||
|
||||
22
pkg/apis/compute/cdrom.go
Normal file
22
pkg/apis/compute/cdrom.go
Normal file
@@ -0,0 +1,22 @@
|
||||
// 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
|
||||
|
||||
type GuestcdromJsonDesc struct {
|
||||
ImageId string `json:"image_id"`
|
||||
Path string `json:"path"`
|
||||
Name string `json:"name"`
|
||||
Size int64 `json:"size"`
|
||||
}
|
||||
@@ -36,23 +36,23 @@ const (
|
||||
CLOUD_PROVIDER_SYNC_STATUS_IDLE = "idle"
|
||||
CLOUD_PROVIDER_SYNC_STATUS_ERROR = "error"
|
||||
|
||||
CLOUD_PROVIDER_ONECLOUD = "OneCloud"
|
||||
CLOUD_PROVIDER_VMWARE = "VMware"
|
||||
CLOUD_PROVIDER_ALIYUN = "Aliyun"
|
||||
CLOUD_PROVIDER_APSARA = "Apsara"
|
||||
CLOUD_PROVIDER_QCLOUD = "Qcloud"
|
||||
CLOUD_PROVIDER_AZURE = "Azure"
|
||||
CLOUD_PROVIDER_AWS = "Aws"
|
||||
CLOUD_PROVIDER_HUAWEI = "Huawei"
|
||||
CLOUD_PROVIDER_HUAWEI_CLOUD_STACK = "HuaweiCloudStack"
|
||||
CLOUD_PROVIDER_OPENSTACK = "OpenStack"
|
||||
CLOUD_PROVIDER_UCLOUD = "Ucloud"
|
||||
CLOUD_PROVIDER_ZSTACK = "ZStack"
|
||||
CLOUD_PROVIDER_GOOGLE = "Google"
|
||||
CLOUD_PROVIDER_CTYUN = "Ctyun"
|
||||
CLOUD_PROVIDER_ECLOUD = "Ecloud"
|
||||
CLOUD_PROVIDER_JDCLOUD = "JDcloud"
|
||||
CLOUD_PROVIDER_CLOUDPODS = "Cloudpods"
|
||||
CLOUD_PROVIDER_ONECLOUD = "OneCloud"
|
||||
CLOUD_PROVIDER_VMWARE = "VMware"
|
||||
CLOUD_PROVIDER_ALIYUN = "Aliyun"
|
||||
CLOUD_PROVIDER_APSARA = "Apsara"
|
||||
CLOUD_PROVIDER_QCLOUD = "Qcloud"
|
||||
CLOUD_PROVIDER_AZURE = "Azure"
|
||||
CLOUD_PROVIDER_AWS = "Aws"
|
||||
CLOUD_PROVIDER_HUAWEI = "Huawei"
|
||||
CLOUD_PROVIDER_HCSO = "HCSO"
|
||||
CLOUD_PROVIDER_OPENSTACK = "OpenStack"
|
||||
CLOUD_PROVIDER_UCLOUD = "Ucloud"
|
||||
CLOUD_PROVIDER_ZSTACK = "ZStack"
|
||||
CLOUD_PROVIDER_GOOGLE = "Google"
|
||||
CLOUD_PROVIDER_CTYUN = "Ctyun"
|
||||
CLOUD_PROVIDER_ECLOUD = "Ecloud"
|
||||
CLOUD_PROVIDER_JDCLOUD = "JDcloud"
|
||||
CLOUD_PROVIDER_CLOUDPODS = "Cloudpods"
|
||||
|
||||
CLOUD_PROVIDER_GENERICS3 = "S3"
|
||||
CLOUD_PROVIDER_CEPH = "Ceph"
|
||||
@@ -98,7 +98,7 @@ const (
|
||||
var (
|
||||
CLOUD_PROVIDER_VALID_STATUS = []string{CLOUD_PROVIDER_CONNECTED}
|
||||
CLOUD_PROVIDER_VALID_HEALTH_STATUS = []string{CLOUD_PROVIDER_HEALTH_NORMAL, CLOUD_PROVIDER_HEALTH_NO_PERMISSION}
|
||||
PRIVATE_CLOUD_PROVIDERS = []string{CLOUD_PROVIDER_ZSTACK, CLOUD_PROVIDER_OPENSTACK, CLOUD_PROVIDER_APSARA, CLOUD_PROVIDER_HUAWEI_CLOUD_STACK}
|
||||
PRIVATE_CLOUD_PROVIDERS = []string{CLOUD_PROVIDER_ZSTACK, CLOUD_PROVIDER_OPENSTACK, CLOUD_PROVIDER_APSARA, CLOUD_PROVIDER_HCSO}
|
||||
|
||||
CLOUD_PROVIDERS = []string{
|
||||
CLOUD_PROVIDER_ONECLOUD,
|
||||
@@ -109,7 +109,7 @@ var (
|
||||
CLOUD_PROVIDER_AZURE,
|
||||
CLOUD_PROVIDER_AWS,
|
||||
CLOUD_PROVIDER_HUAWEI,
|
||||
CLOUD_PROVIDER_HUAWEI_CLOUD_STACK,
|
||||
CLOUD_PROVIDER_HCSO,
|
||||
CLOUD_PROVIDER_OPENSTACK,
|
||||
CLOUD_PROVIDER_UCLOUD,
|
||||
CLOUD_PROVIDER_ZSTACK,
|
||||
@@ -147,8 +147,8 @@ var (
|
||||
CLOUD_PROVIDER_HUAWEI: []string{
|
||||
HOST_TYPE_HUAWEI,
|
||||
},
|
||||
CLOUD_PROVIDER_HUAWEI_CLOUD_STACK: {
|
||||
HOST_TYPE_HUAWEI_CLOUD_STACK,
|
||||
CLOUD_PROVIDER_HCSO: {
|
||||
HOST_TYPE_HCSO,
|
||||
},
|
||||
CLOUD_PROVIDER_OPENSTACK: []string{
|
||||
HOST_TYPE_OPENSTACK,
|
||||
|
||||
@@ -125,7 +125,7 @@ type DnsZoneDetails struct {
|
||||
// 关联vpc数量
|
||||
VpcCount int `json:"vpc_count"`
|
||||
// Cache info
|
||||
CloudCaches []DnsZoneCacheDetails `json:"cloud_caches"`
|
||||
CloudCaches []jsonutils.JSONObject `json:"cloud_caches"`
|
||||
}
|
||||
|
||||
type DnsZoneListInput struct {
|
||||
@@ -141,7 +141,8 @@ type DnsZoneListInput struct {
|
||||
ZoneType string `json:"zone_type"`
|
||||
|
||||
// Filter dns zone By vpc
|
||||
VpcId string `json:"vpc_id"`
|
||||
VpcId string `json:"vpc_id"`
|
||||
WithCache bool `json:"with_cache"`
|
||||
}
|
||||
|
||||
type DnsZoneSyncStatusInput struct {
|
||||
|
||||
@@ -153,21 +153,21 @@ const (
|
||||
HYPERVISOR_HYPERV = "hyperv"
|
||||
HYPERVISOR_XEN = "xen"
|
||||
|
||||
HYPERVISOR_ALIYUN = "aliyun"
|
||||
HYPERVISOR_APSARA = "apsara"
|
||||
HYPERVISOR_QCLOUD = "qcloud"
|
||||
HYPERVISOR_AZURE = "azure"
|
||||
HYPERVISOR_AWS = "aws"
|
||||
HYPERVISOR_HUAWEI = "huawei"
|
||||
HYPERVISOR_HUAWEI_CLOUD_STACK = "huaweicloudstack"
|
||||
HYPERVISOR_OPENSTACK = "openstack"
|
||||
HYPERVISOR_UCLOUD = "ucloud"
|
||||
HYPERVISOR_ZSTACK = "zstack"
|
||||
HYPERVISOR_GOOGLE = "google"
|
||||
HYPERVISOR_CTYUN = "ctyun"
|
||||
HYPERVISOR_ECLOUD = "ecloud"
|
||||
HYPERVISOR_JDCLOUD = "jdcloud"
|
||||
HYPERVISOR_CLOUDPODS = "cloudpods"
|
||||
HYPERVISOR_ALIYUN = "aliyun"
|
||||
HYPERVISOR_APSARA = "apsara"
|
||||
HYPERVISOR_QCLOUD = "qcloud"
|
||||
HYPERVISOR_AZURE = "azure"
|
||||
HYPERVISOR_AWS = "aws"
|
||||
HYPERVISOR_HUAWEI = "huawei"
|
||||
HYPERVISOR_HCSO = "hcso"
|
||||
HYPERVISOR_OPENSTACK = "openstack"
|
||||
HYPERVISOR_UCLOUD = "ucloud"
|
||||
HYPERVISOR_ZSTACK = "zstack"
|
||||
HYPERVISOR_GOOGLE = "google"
|
||||
HYPERVISOR_CTYUN = "ctyun"
|
||||
HYPERVISOR_ECLOUD = "ecloud"
|
||||
HYPERVISOR_JDCLOUD = "jdcloud"
|
||||
HYPERVISOR_CLOUDPODS = "cloudpods"
|
||||
|
||||
// HYPERVISOR_DEFAULT = HYPERVISOR_KVM
|
||||
HYPERVISOR_DEFAULT = HYPERVISOR_KVM
|
||||
@@ -192,7 +192,7 @@ var HYPERVISORS = []string{
|
||||
HYPERVISOR_AWS,
|
||||
HYPERVISOR_QCLOUD,
|
||||
HYPERVISOR_HUAWEI,
|
||||
HYPERVISOR_HUAWEI_CLOUD_STACK,
|
||||
HYPERVISOR_HCSO,
|
||||
HYPERVISOR_OPENSTACK,
|
||||
HYPERVISOR_UCLOUD,
|
||||
HYPERVISOR_ZSTACK,
|
||||
@@ -227,53 +227,53 @@ var PRIVATE_CLOUD_HYPERVISORS = []string{
|
||||
HYPERVISOR_OPENSTACK,
|
||||
HYPERVISOR_APSARA,
|
||||
HYPERVISOR_CLOUDPODS,
|
||||
HYPERVISOR_HUAWEI_CLOUD_STACK,
|
||||
HYPERVISOR_HCSO,
|
||||
}
|
||||
|
||||
// var HYPERVISORS = []string{HYPERVISOR_ALIYUN}
|
||||
|
||||
var HYPERVISOR_HOSTTYPE = map[string]string{
|
||||
HYPERVISOR_KVM: HOST_TYPE_HYPERVISOR,
|
||||
HYPERVISOR_BAREMETAL: HOST_TYPE_BAREMETAL,
|
||||
HYPERVISOR_ESXI: HOST_TYPE_ESXI,
|
||||
HYPERVISOR_CONTAINER: HOST_TYPE_KUBELET,
|
||||
HYPERVISOR_ALIYUN: HOST_TYPE_ALIYUN,
|
||||
HYPERVISOR_APSARA: HOST_TYPE_APSARA,
|
||||
HYPERVISOR_AZURE: HOST_TYPE_AZURE,
|
||||
HYPERVISOR_AWS: HOST_TYPE_AWS,
|
||||
HYPERVISOR_QCLOUD: HOST_TYPE_QCLOUD,
|
||||
HYPERVISOR_HUAWEI: HOST_TYPE_HUAWEI,
|
||||
HYPERVISOR_HUAWEI_CLOUD_STACK: HOST_TYPE_HUAWEI_CLOUD_STACK,
|
||||
HYPERVISOR_OPENSTACK: HOST_TYPE_OPENSTACK,
|
||||
HYPERVISOR_UCLOUD: HOST_TYPE_UCLOUD,
|
||||
HYPERVISOR_ZSTACK: HOST_TYPE_ZSTACK,
|
||||
HYPERVISOR_GOOGLE: HOST_TYPE_GOOGLE,
|
||||
HYPERVISOR_CTYUN: HOST_TYPE_CTYUN,
|
||||
HYPERVISOR_ECLOUD: HOST_TYPE_ECLOUD,
|
||||
HYPERVISOR_JDCLOUD: HOST_TYPE_JDCLOUD,
|
||||
HYPERVISOR_CLOUDPODS: HOST_TYPE_CLOUDPODS,
|
||||
HYPERVISOR_KVM: HOST_TYPE_HYPERVISOR,
|
||||
HYPERVISOR_BAREMETAL: HOST_TYPE_BAREMETAL,
|
||||
HYPERVISOR_ESXI: HOST_TYPE_ESXI,
|
||||
HYPERVISOR_CONTAINER: HOST_TYPE_KUBELET,
|
||||
HYPERVISOR_ALIYUN: HOST_TYPE_ALIYUN,
|
||||
HYPERVISOR_APSARA: HOST_TYPE_APSARA,
|
||||
HYPERVISOR_AZURE: HOST_TYPE_AZURE,
|
||||
HYPERVISOR_AWS: HOST_TYPE_AWS,
|
||||
HYPERVISOR_QCLOUD: HOST_TYPE_QCLOUD,
|
||||
HYPERVISOR_HUAWEI: HOST_TYPE_HUAWEI,
|
||||
HYPERVISOR_HCSO: HOST_TYPE_HCSO,
|
||||
HYPERVISOR_OPENSTACK: HOST_TYPE_OPENSTACK,
|
||||
HYPERVISOR_UCLOUD: HOST_TYPE_UCLOUD,
|
||||
HYPERVISOR_ZSTACK: HOST_TYPE_ZSTACK,
|
||||
HYPERVISOR_GOOGLE: HOST_TYPE_GOOGLE,
|
||||
HYPERVISOR_CTYUN: HOST_TYPE_CTYUN,
|
||||
HYPERVISOR_ECLOUD: HOST_TYPE_ECLOUD,
|
||||
HYPERVISOR_JDCLOUD: HOST_TYPE_JDCLOUD,
|
||||
HYPERVISOR_CLOUDPODS: HOST_TYPE_CLOUDPODS,
|
||||
}
|
||||
|
||||
var HOSTTYPE_HYPERVISOR = map[string]string{
|
||||
HOST_TYPE_HYPERVISOR: HYPERVISOR_KVM,
|
||||
HOST_TYPE_BAREMETAL: HYPERVISOR_BAREMETAL,
|
||||
HOST_TYPE_ESXI: HYPERVISOR_ESXI,
|
||||
HOST_TYPE_KUBELET: HYPERVISOR_CONTAINER,
|
||||
HOST_TYPE_ALIYUN: HYPERVISOR_ALIYUN,
|
||||
HOST_TYPE_APSARA: HYPERVISOR_APSARA,
|
||||
HOST_TYPE_AZURE: HYPERVISOR_AZURE,
|
||||
HOST_TYPE_AWS: HYPERVISOR_AWS,
|
||||
HOST_TYPE_QCLOUD: HYPERVISOR_QCLOUD,
|
||||
HOST_TYPE_HUAWEI: HYPERVISOR_HUAWEI,
|
||||
HOST_TYPE_HUAWEI_CLOUD_STACK: HYPERVISOR_HUAWEI_CLOUD_STACK,
|
||||
HOST_TYPE_OPENSTACK: HYPERVISOR_OPENSTACK,
|
||||
HOST_TYPE_UCLOUD: HYPERVISOR_UCLOUD,
|
||||
HOST_TYPE_ZSTACK: HYPERVISOR_ZSTACK,
|
||||
HOST_TYPE_GOOGLE: HYPERVISOR_GOOGLE,
|
||||
HOST_TYPE_CTYUN: HYPERVISOR_CTYUN,
|
||||
HOST_TYPE_ECLOUD: HYPERVISOR_ECLOUD,
|
||||
HOST_TYPE_JDCLOUD: HYPERVISOR_JDCLOUD,
|
||||
HOST_TYPE_CLOUDPODS: HYPERVISOR_CLOUDPODS,
|
||||
HOST_TYPE_HYPERVISOR: HYPERVISOR_KVM,
|
||||
HOST_TYPE_BAREMETAL: HYPERVISOR_BAREMETAL,
|
||||
HOST_TYPE_ESXI: HYPERVISOR_ESXI,
|
||||
HOST_TYPE_KUBELET: HYPERVISOR_CONTAINER,
|
||||
HOST_TYPE_ALIYUN: HYPERVISOR_ALIYUN,
|
||||
HOST_TYPE_APSARA: HYPERVISOR_APSARA,
|
||||
HOST_TYPE_AZURE: HYPERVISOR_AZURE,
|
||||
HOST_TYPE_AWS: HYPERVISOR_AWS,
|
||||
HOST_TYPE_QCLOUD: HYPERVISOR_QCLOUD,
|
||||
HOST_TYPE_HUAWEI: HYPERVISOR_HUAWEI,
|
||||
HOST_TYPE_HCSO: HYPERVISOR_HCSO,
|
||||
HOST_TYPE_OPENSTACK: HYPERVISOR_OPENSTACK,
|
||||
HOST_TYPE_UCLOUD: HYPERVISOR_UCLOUD,
|
||||
HOST_TYPE_ZSTACK: HYPERVISOR_ZSTACK,
|
||||
HOST_TYPE_GOOGLE: HYPERVISOR_GOOGLE,
|
||||
HOST_TYPE_CTYUN: HYPERVISOR_CTYUN,
|
||||
HOST_TYPE_ECLOUD: HYPERVISOR_ECLOUD,
|
||||
HOST_TYPE_JDCLOUD: HYPERVISOR_JDCLOUD,
|
||||
HOST_TYPE_CLOUDPODS: HYPERVISOR_CLOUDPODS,
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -66,3 +66,35 @@ type GuestdiskUpdateInput struct {
|
||||
|
||||
Index *int8 `json:"index"`
|
||||
}
|
||||
|
||||
type GuestdiskJsonDesc struct {
|
||||
DiskId string `json:"disk_id"`
|
||||
Driver string `json:"driver"`
|
||||
CacheMode string `json:"cache_mode"`
|
||||
AioMode string `json:"aio_mode"`
|
||||
Iops int `json:"iops"`
|
||||
Bps int `json:"bps"`
|
||||
Size int `json:"size"`
|
||||
TemplateId string `json:"template_id"`
|
||||
ImagePath string `json:"image_path"`
|
||||
StorageId string `json:"storage_id"`
|
||||
Migrating bool `json:"migrating"`
|
||||
Path string `json:"path"`
|
||||
Format string `json:"format"`
|
||||
Index int8 `json:"index"`
|
||||
MergeSnapshot bool `json:"merge_snapshot"`
|
||||
EsxiFlatFilePath string `json:"esxi_flat_file_path"`
|
||||
Fs string `json:"fs"`
|
||||
Mountpoint string `json:"mountpoint"`
|
||||
Dev string `json:"dev"`
|
||||
IsSSD bool `json:"is_ssd"`
|
||||
|
||||
// esxi
|
||||
ImageInfo struct {
|
||||
ImageType string `json:"image_type"`
|
||||
ImageExternalId string `json:"image_external_id"`
|
||||
StorageCacheHostIp string `json:"storage_cache_host_ip"`
|
||||
} `json:"image_info"`
|
||||
|
||||
TargetStorageId string `json:"target_storage_id"`
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ const (
|
||||
MIRROR_JOB = "__mirror_job_status"
|
||||
MIRROR_JOB_READY = "ready"
|
||||
MIRROR_JOB_FAILED = "failed"
|
||||
|
||||
SSH_PORT = "__ssh_port"
|
||||
)
|
||||
|
||||
const BASE_INSTANCE_SNAPSHOT_ID = "__base_instance_snapshot_id"
|
||||
|
||||
@@ -48,6 +48,7 @@ type GuestMakeSshableInput struct {
|
||||
User string
|
||||
PrivateKey string
|
||||
Password string
|
||||
Port int
|
||||
}
|
||||
|
||||
type GuestMakeSshableOutput struct {
|
||||
@@ -57,3 +58,7 @@ type GuestMakeSshableOutput struct {
|
||||
type GuestMakeSshableCmdOutput struct {
|
||||
ShellCmd string
|
||||
}
|
||||
|
||||
type GuestSetSshPortInput struct {
|
||||
Port int
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
package compute
|
||||
|
||||
import "yunion.io/x/jsonutils"
|
||||
|
||||
type GuestnetworkDetails struct {
|
||||
GuestJointResourceDetails
|
||||
|
||||
@@ -70,3 +72,44 @@ type GuestnetworkUpdateInput struct {
|
||||
|
||||
Index *int8 `json:"index"`
|
||||
}
|
||||
|
||||
type GuestnetworkJsonDesc struct {
|
||||
Net string `json:"net"`
|
||||
NetId string `json:"net_id"`
|
||||
Mac string `json:"mac"`
|
||||
Virtual bool `json:"virtual"`
|
||||
Ip string `json:"ip"`
|
||||
Gateway string `json:"gateway"`
|
||||
DNS string `json:"dns"`
|
||||
Domain string `json:"domain"`
|
||||
Routes jsonutils.JSONObject `json:"routes"`
|
||||
Ifname string `json:"ifname"`
|
||||
Masklen int8 `json:"masklen"`
|
||||
Driver string `json:"driver"`
|
||||
Vlan int `json:"vlan"`
|
||||
Bw int `json:"bw"`
|
||||
Mtu int `json:"mtu"`
|
||||
Index int8 `json:"index"`
|
||||
VirtualIps []string `json:"virtual_ips"`
|
||||
ExternalId string `json:"external_id"`
|
||||
TeamWith string `json:"team_with"`
|
||||
Manual *bool `json:"manual"`
|
||||
|
||||
Vpc struct {
|
||||
Id string `json:"id"`
|
||||
Provider string `json:"provider"`
|
||||
MappedIpAddr string `json:"mapped_ip_addr"`
|
||||
} `json:"vpc"`
|
||||
|
||||
Networkaddresses jsonutils.JSONObject `json:"networkaddresses"`
|
||||
|
||||
Bridge string `json:"bridge"`
|
||||
WireId string `json:"wire_id"`
|
||||
Interface string `json:"interface"`
|
||||
|
||||
// baremetal
|
||||
Rate int `json:"rate"`
|
||||
BaremetalId string `json:"baremetal_id"`
|
||||
NicType string `json:"nic_type"`
|
||||
LinkUp bool `json:"link_up"`
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
"yunion.io/x/onecloud/pkg/apis/billing"
|
||||
)
|
||||
@@ -121,12 +123,14 @@ func (input *ServerListInput) AfterUnmarshal() {
|
||||
type ServerRebuildRootInput struct {
|
||||
apis.Meta
|
||||
|
||||
// 镜像名称
|
||||
Image string `json:"image"`
|
||||
// swagger: ignore
|
||||
Image string `json:"image" yunion-deprecated-by:"image_id"`
|
||||
// 镜像 id
|
||||
// required: true
|
||||
ImageId string `json:"image_id"`
|
||||
Keypair string `json:"keypair"`
|
||||
ImageId string `json:"image_id"`
|
||||
// swagger: ignore
|
||||
Keypair string `json:"keypair" yunion-deprecated-by:"keypair_id"`
|
||||
// 秘钥Id
|
||||
KeypairId string `json:"keypair_id"`
|
||||
ResetPassword *bool `json:"reset_password"`
|
||||
Password string `json:"password"`
|
||||
@@ -134,26 +138,6 @@ type ServerRebuildRootInput struct {
|
||||
AllDisks *bool `json:"all_disks"`
|
||||
}
|
||||
|
||||
func (i ServerRebuildRootInput) GetImageName() string {
|
||||
if len(i.Image) > 0 {
|
||||
return i.Image
|
||||
}
|
||||
if len(i.ImageId) > 0 {
|
||||
return i.ImageId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (i ServerRebuildRootInput) GetKeypairName() string {
|
||||
if len(i.Keypair) > 0 {
|
||||
return i.Keypair
|
||||
}
|
||||
if len(i.KeypairId) > 0 {
|
||||
return i.KeypairId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ServerResumeInput struct {
|
||||
apis.Meta
|
||||
}
|
||||
@@ -555,3 +539,152 @@ type ServerMigrateNetworkInput struct {
|
||||
// Destination network Id
|
||||
Dest string `json:"dest"`
|
||||
}
|
||||
|
||||
type ServerDeployInput struct {
|
||||
apis.Meta
|
||||
|
||||
// swagger: ignore
|
||||
Keypair string `json:"keypair" yunion-deprecated-by:"keypair_id"`
|
||||
// 秘钥Id
|
||||
KeypairId string `json:"keypair_id"`
|
||||
|
||||
// 清理指定公钥
|
||||
// 若指定的秘钥Id和虚拟机的秘钥Id不相同, 则清理旧的公钥
|
||||
DeletePublicKey string `json:"delete_public_key"`
|
||||
// 解绑当前虚拟机秘钥, 并清理公钥信息
|
||||
DeleteKeypair bool `json:"__delete_keypair__"`
|
||||
// 生成随机密码, 优先级低于password
|
||||
ResetPassword bool `json:"reset_password"`
|
||||
// 重置指定密码
|
||||
Password string `json:"password"`
|
||||
// 部署完成后是否自动启动
|
||||
// 若虚拟机重置密码后需要重启生效,并且当前虚拟机状态为running, 此参数默认为true
|
||||
// 若虚拟机状态为ready, 指定此参数后,部署完成后,虚拟机会自动启动
|
||||
AutoStart bool `json:"auto_start"`
|
||||
// swagger: ignore
|
||||
Restart bool `json:"restart"`
|
||||
|
||||
// swagger: ignore
|
||||
DeployConfigs []*DeployConfig `json:"deploy_configs"`
|
||||
}
|
||||
|
||||
type ServerUserDataInput struct {
|
||||
UserData string `json:"user_data"`
|
||||
}
|
||||
|
||||
type ServerAttachDiskInput struct {
|
||||
DiskId string `json:"disk_id"`
|
||||
}
|
||||
|
||||
type ServerDetachDiskInput struct {
|
||||
// 磁盘Id,若磁盘未挂载在虚拟机上,不返回错误
|
||||
DiskId string `json:"disk_id"`
|
||||
// 是否保留磁盘
|
||||
// default: false
|
||||
KeepDisk bool `json:"keep_disk"`
|
||||
}
|
||||
|
||||
type ServerChangeConfigInput struct {
|
||||
// 实例类型, 优先级高于vcpu_count和vmem_size
|
||||
InstanceType string `json:"instance_type"`
|
||||
// swagger: ignore
|
||||
Sku string `json:"sku" yunion-deprecated-by:"instance_type"`
|
||||
// swagger: ignore
|
||||
Flavor string `json:"flavor" yunion-deprecated-by:"instance_type"`
|
||||
|
||||
// cpu大小
|
||||
VcpuCount int `json:"vcpu_count"`
|
||||
// 内存大小, 1024M, 1G
|
||||
VmemSize string `json:"vmem_size"`
|
||||
|
||||
// 调整完配置后是否自动启动
|
||||
AutoStart bool `json:"auto_start"`
|
||||
|
||||
Disks []DiskConfig `json:"disks"`
|
||||
}
|
||||
|
||||
type ServerUpdateInput struct {
|
||||
apis.VirtualResourceBaseUpdateInput
|
||||
|
||||
// 删除保护开关
|
||||
DisableDelete *bool `json:"disable_delete"`
|
||||
// 启动顺序
|
||||
BootOrder *string `json:"boot_order"`
|
||||
// 关机执行操作
|
||||
ShutdownBehavior *string `json:"shutdown_behavior"`
|
||||
Vga *string `json:"vga"`
|
||||
Vdi *string `json:"vdi"`
|
||||
Machine *string `json:"machine"`
|
||||
Bios *string `json:"bios"`
|
||||
|
||||
SrcIpCheck *bool `json:"src_ip_check"`
|
||||
SrcMacCheck *bool `json:"src_mac_check"`
|
||||
|
||||
SshPort int `json:"ssh_port"`
|
||||
}
|
||||
|
||||
type GuestJsonDesc struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
UUID string `json:"uuid"`
|
||||
Mem int `json:"mem"`
|
||||
Cpu int `json:"cpu"`
|
||||
Vga string `json:"vga"`
|
||||
Vdi string `json:"vdi"`
|
||||
Machine string `json:"machie"`
|
||||
Bios string `json:"bios"`
|
||||
BootOrder string `json:"boot_order"`
|
||||
SrcIpCheck bool `json:"src_ip_check"`
|
||||
SrcMacCheck bool `json:"src_mac_check"`
|
||||
IsMaster *bool `json:"is_master"`
|
||||
IsSlave *bool `json:"is_slave"`
|
||||
HostId string `json:"host_id"`
|
||||
|
||||
IsolatedDevices []*IsolatedDeviceJsonDesc `json:"isolated_devices"`
|
||||
|
||||
Domain string `json:"domain"`
|
||||
|
||||
Nics []*GuestnetworkJsonDesc `json:"nics"`
|
||||
Disks []*GuestdiskJsonDesc `json:"disks"`
|
||||
|
||||
Cdrom *GuestcdromJsonDesc `json:"cdrom"`
|
||||
|
||||
Tenant string `json:"tenant"`
|
||||
TenantId string `json:"tenant_id"`
|
||||
DomainId string `json:"domain_id"`
|
||||
ProjectDomain string `json:"project_domain"`
|
||||
|
||||
Keypair string `json:"keypair"`
|
||||
Pubkey string `json:"pubkey"`
|
||||
|
||||
NetworkRoles []string `json:"network_roles"`
|
||||
|
||||
Secgroups []*SecgroupJsonDesc `json:"secgroups"`
|
||||
SecurityRules string `json:"security_rules"`
|
||||
AdminSecurityRules string `json:"admin_security_rules"`
|
||||
|
||||
ExtraOptions jsonutils.JSONObject `json:"extra_options"`
|
||||
|
||||
Kvm string `json:"kvm"`
|
||||
|
||||
Zone string `json:"zone"`
|
||||
ZoneId string `json:"zone_id"`
|
||||
|
||||
OsName string `json:"os_name"`
|
||||
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
UserData string `json:"user_data"`
|
||||
PendingDeleted bool `json:"pending_deleted"`
|
||||
|
||||
ScallingGroupId string `json:"scalling_group_id"`
|
||||
|
||||
// baremetal
|
||||
DiskConfig jsonutils.JSONObject `json:"disk_config"`
|
||||
NicsStandby []*GuestnetworkJsonDesc `json:"nics_standby"`
|
||||
|
||||
// esxi
|
||||
InstanceSnapshotInfo struct {
|
||||
InstanceSnapshotId string `json:"instance_snapshot_id"`
|
||||
InstanceId string `json:"instance_id"`
|
||||
} `json:"instance_snapshot_info"`
|
||||
}
|
||||
|
||||
@@ -23,21 +23,21 @@ const (
|
||||
HOST_TYPE_HYPERV = "hyperv" // # Microsoft Hyper-V
|
||||
HOST_TYPE_XEN = "xen" // # XenServer
|
||||
|
||||
HOST_TYPE_ALIYUN = "aliyun"
|
||||
HOST_TYPE_APSARA = "apsara"
|
||||
HOST_TYPE_AWS = "aws"
|
||||
HOST_TYPE_QCLOUD = "qcloud"
|
||||
HOST_TYPE_AZURE = "azure"
|
||||
HOST_TYPE_HUAWEI = "huawei"
|
||||
HOST_TYPE_HUAWEI_CLOUD_STACK = "huaweicloudstack"
|
||||
HOST_TYPE_OPENSTACK = "openstack"
|
||||
HOST_TYPE_UCLOUD = "ucloud"
|
||||
HOST_TYPE_ZSTACK = "zstack"
|
||||
HOST_TYPE_GOOGLE = "google"
|
||||
HOST_TYPE_CTYUN = "ctyun"
|
||||
HOST_TYPE_ECLOUD = "ecloud"
|
||||
HOST_TYPE_JDCLOUD = "jdcloud"
|
||||
HOST_TYPE_CLOUDPODS = "cloudpods"
|
||||
HOST_TYPE_ALIYUN = "aliyun"
|
||||
HOST_TYPE_APSARA = "apsara"
|
||||
HOST_TYPE_AWS = "aws"
|
||||
HOST_TYPE_QCLOUD = "qcloud"
|
||||
HOST_TYPE_AZURE = "azure"
|
||||
HOST_TYPE_HUAWEI = "huawei"
|
||||
HOST_TYPE_HCSO = "hcso"
|
||||
HOST_TYPE_OPENSTACK = "openstack"
|
||||
HOST_TYPE_UCLOUD = "ucloud"
|
||||
HOST_TYPE_ZSTACK = "zstack"
|
||||
HOST_TYPE_GOOGLE = "google"
|
||||
HOST_TYPE_CTYUN = "ctyun"
|
||||
HOST_TYPE_ECLOUD = "ecloud"
|
||||
HOST_TYPE_JDCLOUD = "jdcloud"
|
||||
HOST_TYPE_CLOUDPODS = "cloudpods"
|
||||
|
||||
HOST_TYPE_DEFAULT = HOST_TYPE_HYPERVISOR
|
||||
|
||||
@@ -112,7 +112,7 @@ var HOST_TYPES = []string{
|
||||
HOST_TYPE_AWS,
|
||||
HOST_TYPE_QCLOUD,
|
||||
HOST_TYPE_HUAWEI,
|
||||
HOST_TYPE_HUAWEI_CLOUD_STACK,
|
||||
HOST_TYPE_HCSO,
|
||||
HOST_TYPE_OPENSTACK,
|
||||
HOST_TYPE_UCLOUD,
|
||||
HOST_TYPE_ZSTACK,
|
||||
|
||||
@@ -95,3 +95,12 @@ type IsolatedDeviceUpdateInput struct {
|
||||
apis.StandaloneResourceBaseUpdateInput
|
||||
IsolatedDeviceReservedResourceInput
|
||||
}
|
||||
|
||||
type IsolatedDeviceJsonDesc struct {
|
||||
Id string `json:"id"`
|
||||
DevType string `json:"dev_type"`
|
||||
Model string `json:"model"`
|
||||
Addr string `json:"addr"`
|
||||
VendorDeviceId string `json:"vendor_device_id"`
|
||||
Vendor string `json:"vendor"`
|
||||
}
|
||||
|
||||
@@ -209,22 +209,11 @@ type NetworkCreateInput struct {
|
||||
BgpType string `json:"bgp_type"`
|
||||
}
|
||||
|
||||
type NetworkDetails struct {
|
||||
apis.SharableVirtualResourceDetails
|
||||
WireResourceInfo
|
||||
|
||||
SNetwork
|
||||
|
||||
// 是否是内网
|
||||
Exit bool `json:"exit"`
|
||||
// 端口数量
|
||||
Ports int `json:"ports"`
|
||||
// 已使用端口数量
|
||||
PortsUsed int `json:"ports_used"`
|
||||
// 网卡数量
|
||||
type SNetworkNics struct {
|
||||
// 虚拟机网卡数量
|
||||
Vnics int `json:"vnics"`
|
||||
// 裸金属网卡数量
|
||||
BmVnics int `json:"bm_nics"`
|
||||
BmVnics int `json:"bm_vnics"`
|
||||
// 负载均衡网卡数量
|
||||
LbVnics int `json:"lb_vnics"`
|
||||
// 浮动Ip网卡数量
|
||||
@@ -233,6 +222,48 @@ type NetworkDetails struct {
|
||||
// 预留IP数量
|
||||
ReserveVnics int `json:"reserve_vnics"`
|
||||
|
||||
// RDS网卡数量
|
||||
RdsVnics int `json:"rds_vnics"`
|
||||
// NAT网关网卡数量
|
||||
NatVnics int `json:"nat_vnics"`
|
||||
BmReusedVnics int `json:"bm_reused_vnics"`
|
||||
|
||||
// 弹性网卡数量
|
||||
NetworkinterfaceVnics int `json:"networkinterface_vnics"`
|
||||
|
||||
// 已使用端口数量
|
||||
PortsUsed int `json:"ports_used"`
|
||||
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
func (self *SNetworkNics) SumTotal() {
|
||||
self.Total = self.Vnics +
|
||||
self.BmVnics +
|
||||
self.LbVnics +
|
||||
self.LbVnics +
|
||||
self.EipVnics +
|
||||
self.GroupVnics +
|
||||
self.ReserveVnics +
|
||||
self.RdsVnics +
|
||||
self.NetworkinterfaceVnics +
|
||||
self.NatVnics -
|
||||
self.BmReusedVnics
|
||||
self.PortsUsed = self.Total
|
||||
}
|
||||
|
||||
type NetworkDetails struct {
|
||||
apis.SharableVirtualResourceDetails
|
||||
WireResourceInfo
|
||||
|
||||
SNetwork
|
||||
SNetworkNics
|
||||
|
||||
// 是否是内网
|
||||
Exit bool `json:"exit"`
|
||||
// 端口数量
|
||||
Ports int `json:"ports"`
|
||||
|
||||
// 路由信息
|
||||
Routes [][]string `json:"routes"`
|
||||
Schedtags []SchedtagShortDescDetails `json:"schedtags"`
|
||||
|
||||
@@ -59,7 +59,7 @@ var (
|
||||
|
||||
REGIONAL_NETWORK_PROVIDERS = []string{
|
||||
CLOUD_PROVIDER_HUAWEI,
|
||||
CLOUD_PROVIDER_HUAWEI_CLOUD_STACK,
|
||||
CLOUD_PROVIDER_HCSO,
|
||||
CLOUD_PROVIDER_CTYUN,
|
||||
CLOUD_PROVIDER_UCLOUD,
|
||||
CLOUD_PROVIDER_GOOGLE,
|
||||
|
||||
@@ -17,6 +17,7 @@ package compute
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
"yunion.io/x/pkg/util/secrules"
|
||||
@@ -181,6 +182,7 @@ type SecgroupListInput struct {
|
||||
RegionalFilterListInput
|
||||
|
||||
ManagedResourceListInput
|
||||
WithCache bool `json:"witch_cache"`
|
||||
}
|
||||
|
||||
type SecurityGroupCacheListInput struct {
|
||||
@@ -252,6 +254,8 @@ type SecgroupDetails struct {
|
||||
InRules []SecgroupRuleDetails `json:"in_rules"`
|
||||
// 出方向规则信息
|
||||
OutRules []SecgroupRuleDetails `json:"out_rules"`
|
||||
|
||||
CloudCaches []jsonutils.JSONObject `json:"cloud_caches"`
|
||||
}
|
||||
|
||||
type SecurityGroupResourceInfo struct {
|
||||
@@ -312,3 +316,8 @@ type SecurityGroupCloneInput struct {
|
||||
type SecgroupImportRulesInput struct {
|
||||
Rules []SSecgroupRuleCreateInput `json:"rules"`
|
||||
}
|
||||
|
||||
type SecgroupJsonDesc struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
@@ -74,10 +74,20 @@ const (
|
||||
OS_ARCH_AARCH64 = "aarch64"
|
||||
)
|
||||
|
||||
func IsARM(osArch string) bool {
|
||||
return utils.IsInStringArray(osArch, []string{
|
||||
var (
|
||||
ARCH_X86 = []string{
|
||||
OS_ARCH_X86,
|
||||
OS_ARCH_I386,
|
||||
OS_ARCH_X86_32,
|
||||
OS_ARCH_X86_64,
|
||||
}
|
||||
ARCH_ARM = []string{
|
||||
OS_ARCH_ARM,
|
||||
OS_ARCH_AARCH32,
|
||||
OS_ARCH_AARCH64,
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
func IsARM(osArch string) bool {
|
||||
return utils.IsInStringArray(osArch, ARCH_ARM)
|
||||
}
|
||||
|
||||
@@ -87,3 +87,12 @@ type SApplyInfo struct {
|
||||
ServerId string
|
||||
TryTimes int
|
||||
}
|
||||
|
||||
type DevtoolManagerServiceUrlInput struct {
|
||||
ServiceName string
|
||||
ServerId string
|
||||
}
|
||||
|
||||
type DevtoolManagerServiceUrlOutput struct {
|
||||
ServiceUrl string
|
||||
}
|
||||
|
||||
23
pkg/apis/devtool/serviceurl.go
Normal file
23
pkg/apis/devtool/serviceurl.go
Normal file
@@ -0,0 +1,23 @@
|
||||
// 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 devtool
|
||||
|
||||
const (
|
||||
SERVICEURL_STATUS_CREATING = "creating"
|
||||
SERVICEURL_STATUS_READY = "ready"
|
||||
SERVICEURL_STATUS_DELETING = "deleting"
|
||||
SERVICEURL_STATUS_CREATE_FAILED = "create_failed"
|
||||
SERVICEURL_STATUS_DELETE_FAILED = "delete_failed"
|
||||
)
|
||||
23
pkg/apis/devtool/sshinfo.go
Normal file
23
pkg/apis/devtool/sshinfo.go
Normal file
@@ -0,0 +1,23 @@
|
||||
// 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 devtool
|
||||
|
||||
const (
|
||||
SSHINFO_STATUS_CREATING = "creating"
|
||||
SSHINFO_STATUS_READY = "ready"
|
||||
SSHINFO_STATUS_DELETING = "deleting"
|
||||
SSHINFO_STATUS_CREATE_FAILED = "create_failed"
|
||||
SSHINFO_STATUS_DELETE_FAILED = "delete_failed"
|
||||
)
|
||||
@@ -109,6 +109,7 @@ var (
|
||||
"customized_private_prefixes",
|
||||
"global_http_proxy",
|
||||
"global_https_proxy",
|
||||
"ignore_nonrunning_guests",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,9 @@ const (
|
||||
LocalFilePrefix = "file://"
|
||||
S3Prefix = "s3://"
|
||||
|
||||
IMAGE_STORAGE_DRIVER_LOCAL = "local"
|
||||
IMAGE_STORAGE_DRIVER_S3 = "s3"
|
||||
|
||||
// image properties
|
||||
IMAGE_OS_ARCH = "os_arch"
|
||||
IMAGE_OS_DISTRO = "os_distribution"
|
||||
|
||||
@@ -195,10 +195,13 @@ type STag struct {
|
||||
}
|
||||
|
||||
type MetadataResourceListInput struct {
|
||||
// 通过标签过滤
|
||||
// 通过标签过滤(包含这些标签)
|
||||
Tags []STag `json:"tags"`
|
||||
|
||||
// 通过标签过滤
|
||||
// 通过标签过滤(不包含这些标签)
|
||||
NoTags []STag `json:"no_tags"`
|
||||
|
||||
// 通过标签排序
|
||||
OrderByTag string `json:"order_by_tag"`
|
||||
|
||||
// deprecated
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
package monitor
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
)
|
||||
|
||||
@@ -28,8 +26,8 @@ type AlertRecordShieldCreateInput struct {
|
||||
ResName string `json:"res_name"`
|
||||
ResId string `json:"res_id"`
|
||||
|
||||
StartTime time.Time `json:"start_time"`
|
||||
EndTime time.Time `json:"end_time"`
|
||||
StartTime string `json:"start_time"`
|
||||
EndTime string `json:"end_time"`
|
||||
}
|
||||
|
||||
type AlertRecordShieldDetails struct {
|
||||
|
||||
@@ -14,7 +14,11 @@
|
||||
|
||||
package monitor
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/apis"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
)
|
||||
|
||||
const (
|
||||
SEND_STATE_OK = "ok"
|
||||
@@ -41,8 +45,9 @@ type AlertRecordDetails struct {
|
||||
apis.StatusStandaloneResourceDetails
|
||||
apis.ScopedResourceBaseInfo
|
||||
|
||||
ResNum int64 `json:"res_num"`
|
||||
AlertName string `json:"alert_name"`
|
||||
ResNum int64 `json:"res_num"`
|
||||
AlertName string `json:"alert_name"`
|
||||
TriggerTime time.Time
|
||||
}
|
||||
|
||||
type AlertRecordCreateInput struct {
|
||||
|
||||
@@ -56,6 +56,8 @@ type CommonAlertCreateInput struct {
|
||||
Channel []string `json:"channel"`
|
||||
// 通知接受者
|
||||
Recipients []string `json:"recipients"`
|
||||
|
||||
RobotIds []string `json:"robot_ids"`
|
||||
// 静默期
|
||||
SilentPeriod string `json:"silent_period"`
|
||||
// 报警类型
|
||||
@@ -101,6 +103,7 @@ type CommonAlertListInput struct {
|
||||
Level string `json:"level"`
|
||||
ResType []string `json:"res_type"`
|
||||
UsedBy string `json:"used_by"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type CommonAlertUpdateInput struct {
|
||||
@@ -132,6 +135,7 @@ type CommonAlertDetails struct {
|
||||
NotifierId string `json:"notifier_id"`
|
||||
Channel []string `json:"channel"`
|
||||
Recipients []string `json:"recipients"`
|
||||
RobotIds []string `json:"robot_ids"`
|
||||
// 静默期
|
||||
SilentPeriod string `json:"silent_period"`
|
||||
Status string `json:"status"`
|
||||
|
||||
@@ -42,11 +42,16 @@ type MonitorResourceListInput struct {
|
||||
ResId []string `json:"res_id"`
|
||||
ResType string `json:"res_type"`
|
||||
OnlyResId bool `json:"only_res_id"`
|
||||
|
||||
ResName string `json:"res_name"`
|
||||
}
|
||||
|
||||
type MonitorResourceDetails struct {
|
||||
apis.VirtualResourceDetails
|
||||
compute.CloudregionResourceInfo
|
||||
compute.CloudaccountResourceInfo
|
||||
Ips string `json:"ips"`
|
||||
AccessIp string `json:"access_ip"`
|
||||
|
||||
AttachAlertCount int64 `json:"attach_alert_count"`
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ type MonitorResourceJointListInput struct {
|
||||
Alerting bool `json:"alertinng"`
|
||||
SendState string `json:"send_state"`
|
||||
ResType string `json:"res_type"`
|
||||
ResName string `json:"res_name"`
|
||||
AlertName string `json:"alert_name"`
|
||||
}
|
||||
|
||||
type MonitorResourceJointCreateInput struct {
|
||||
@@ -44,10 +46,13 @@ type MonitorResourceJointCreateInput struct {
|
||||
}
|
||||
|
||||
type MonitorResourceJointDetails struct {
|
||||
ResName string `json:"res_name"`
|
||||
ResType string `json:"res_type"`
|
||||
AlertName string `json:"alert_name"`
|
||||
AlertRule jsonutils.JSONObject `json:"alert_rule"`
|
||||
Level string `json:"level"`
|
||||
SendState string `json:"send_state"`
|
||||
ResName string `json:"res_name"`
|
||||
ResId string `json:"res_id"`
|
||||
ResType string `json:"res_type"`
|
||||
AlertName string `json:"alert_name"`
|
||||
AlertRule jsonutils.JSONObject `json:"alert_rule"`
|
||||
Level string `json:"level"`
|
||||
SendState string `json:"send_state"`
|
||||
State string `json:"state"`
|
||||
IsSetShield bool `json:"is_set_shield"`
|
||||
}
|
||||
|
||||
@@ -78,8 +78,9 @@ type NotificationListInput struct {
|
||||
}
|
||||
|
||||
type NotificationSettingOneCloud struct {
|
||||
Channel string `json:"channel"`
|
||||
UserIds []string `json:"user_ids"`
|
||||
Channel string `json:"channel"`
|
||||
UserIds []string `json:"user_ids"`
|
||||
RobotIds []string `json:"robot_ids"`
|
||||
}
|
||||
|
||||
type SendWebhookSync struct {
|
||||
|
||||
@@ -238,3 +238,9 @@ type StatusStatistic struct {
|
||||
// 需要指定pending_delete=all
|
||||
PendingDeletedCount int64 `json:"pending_deleted_count"`
|
||||
}
|
||||
|
||||
type ProjectStatistic struct {
|
||||
Count int
|
||||
Id string
|
||||
Name string
|
||||
}
|
||||
|
||||
@@ -32,4 +32,5 @@ const (
|
||||
HUAWEI = "huawei"
|
||||
APSARA = "apsara"
|
||||
JDCLOUD = "jdcloud"
|
||||
CLOUDPODS = "cloudpods"
|
||||
)
|
||||
|
||||
@@ -65,6 +65,7 @@ type Application struct {
|
||||
isExiting bool
|
||||
idleConnsClosed chan struct{}
|
||||
httpServer *http.Server
|
||||
slaveHttpServer *http.Server
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -490,15 +491,16 @@ func (app *Application) ListenAndServeWithoutCleanup(addr, certFile, keyFile str
|
||||
}
|
||||
|
||||
func (app *Application) ListenAndServeTLSWithCleanup2(addr string, certFile, keyFile string, onStop func(), isMaster bool) {
|
||||
httpSrv := app.initServer(addr)
|
||||
if isMaster {
|
||||
app.addDefaultHandlers()
|
||||
AddPProfHandler(app)
|
||||
}
|
||||
app.httpServer = app.initServer(addr)
|
||||
if isMaster {
|
||||
app.httpServer = httpSrv
|
||||
app.registerCleanShutdown(app.httpServer, onStop)
|
||||
} else {
|
||||
app.slaveHttpServer = httpSrv
|
||||
}
|
||||
app.listenAndServeInternal(app.httpServer, certFile, keyFile)
|
||||
app.listenAndServeInternal(httpSrv, certFile, keyFile)
|
||||
if isMaster {
|
||||
app.waitCleanShutdown()
|
||||
}
|
||||
|
||||
@@ -2448,9 +2448,7 @@ func (s *SBaremetalServer) DoDiskConfig(term *ssh.Client) error {
|
||||
}
|
||||
}
|
||||
|
||||
tool := disktool.NewSSHPartitionTool(term)
|
||||
tool.FetchDiskConfs(baremetal.GetDiskConfigurations(layouts))
|
||||
err = tool.RetrieveDiskInfo()
|
||||
tool, err := disktool.NewSSHPartitionTool(term, layouts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -2458,6 +2456,7 @@ func (s *SBaremetalServer) DoDiskConfig(term *ssh.Client) error {
|
||||
for tried := 0; !tool.IsAllDisksReady() && tried < maxTries; tried++ {
|
||||
time.Sleep(5 * time.Second)
|
||||
tool.RetrieveDiskInfo()
|
||||
log.Warningf("disktool not ready string: %s", tool.DebugString())
|
||||
}
|
||||
|
||||
if !tool.IsAllDisksReady() {
|
||||
@@ -2528,11 +2527,9 @@ func (s *SBaremetalServer) DoPartitionDisk(term *ssh.Client) ([]*disktool.Partit
|
||||
return nil, errors.Wrapf(err, "CalculateLayout")
|
||||
}
|
||||
|
||||
tool := disktool.NewSSHPartitionTool(term)
|
||||
tool.FetchDiskConfs(baremetal.GetDiskConfigurations(layouts))
|
||||
err = tool.RetrieveDiskInfo()
|
||||
tool, err := disktool.NewSSHPartitionTool(term, layouts)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "RetrieveDiskInfo")
|
||||
return nil, errors.Wrapf(err, "NewSSHPartitionTool")
|
||||
}
|
||||
|
||||
disks, _ := s.desc.GetArray("disks")
|
||||
@@ -2605,9 +2602,7 @@ func (s *SBaremetalServer) DoRebuildRootDisk(term *ssh.Client) ([]*disktool.Part
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tool := disktool.NewSSHPartitionTool(term)
|
||||
tool.FetchDiskConfs(baremetal.GetDiskConfigurations(layouts))
|
||||
err = tool.RetrieveDiskInfo()
|
||||
tool, err := disktool.NewSSHPartitionTool(term, layouts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -2722,7 +2717,58 @@ func (s *SBaremetalServer) deployFs(term *ssh.Client, deployInfo *deployapi.Depl
|
||||
if strings.ToLower(rootfs.GetOs()) == "windows" {
|
||||
return nil, fmt.Errorf("Unsupported OS: %s", rootfs.GetOs())
|
||||
}
|
||||
return guestfs.DeployGuestFs(rootfs, s.desc, deployInfo)
|
||||
desc, err := deployapi.GuestDescToDeployDesc(s.desc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "To deploy desc fail")
|
||||
}
|
||||
desc, err = s.reIndexDescNics(term, desc)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "reIndexDescNics")
|
||||
}
|
||||
|
||||
return guestfs.DeployGuestFs(rootfs, desc, deployInfo)
|
||||
}
|
||||
|
||||
func (s *SBaremetalServer) reIndexDescNics(term *ssh.Client, desc *deployapi.GuestDesc) (*deployapi.GuestDesc, error) {
|
||||
rNics, err := tasks.GetNicsInfo(term)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "Get server %s remote nics", s.GetName())
|
||||
}
|
||||
findRemoteNic := func(mac string) (int, *types.SNicDevInfo) {
|
||||
for idx, nic := range rNics {
|
||||
if nic.Mac.String() == mac {
|
||||
return idx, rNics[idx]
|
||||
}
|
||||
}
|
||||
return -1, nil
|
||||
}
|
||||
reIndexNics := func(nics []*deployapi.Nic) ([]*deployapi.Nic, error) {
|
||||
for idx, nic := range nics {
|
||||
if nic.GetNicType() == api.NIC_TYPE_IPMI {
|
||||
continue
|
||||
}
|
||||
rIdx, rNic := findRemoteNic(nic.GetMac())
|
||||
if rNic == nil {
|
||||
return nil, errors.Errorf("Not found remote nic by mac %q", nic.GetMac())
|
||||
}
|
||||
if nics[idx].Index != int32(rIdx) {
|
||||
log.Infof("Reindex nic %s index %d to %d", nics[idx].GetMac(), nics[idx].Index, rIdx)
|
||||
nics[idx].Index = int32(rIdx)
|
||||
}
|
||||
}
|
||||
return nics, nil
|
||||
}
|
||||
nics, err := reIndexNics(desc.Nics)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Reindex nics")
|
||||
}
|
||||
desc.Nics = nics
|
||||
sNics, err := reIndexNics(desc.NicsStandby)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Reindex standby nics")
|
||||
}
|
||||
desc.NicsStandby = sNics
|
||||
return desc, nil
|
||||
}
|
||||
|
||||
func (s *SBaremetalServer) GetNics() []types.SServerNic {
|
||||
|
||||
@@ -79,6 +79,7 @@ func (h *DHCPHandler) ServeDHCP(pkt dhcp.Packet, _ *net.UDPAddr, _ *net.Interfac
|
||||
if req.RelayAddr.String() == "0.0.0.0" {
|
||||
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(h.baremetalManager.GetClientSession())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -188,7 +189,7 @@ func (req *dhcpRequest) fetchConfig(session *mcclient.ClientSession) (*dhcp.Resp
|
||||
if len(netConf.GuestDhcp) > 0 {
|
||||
dhcpAddrList = strings.Split(netConf.GuestDhcp, ",")
|
||||
}
|
||||
log.Debugf("dhcpAddrList %s", dhcpAddrList)
|
||||
log.Debugf("find network config %#v, dhcpAddrList %s", netConf, dhcpAddrList)
|
||||
|
||||
// TODO: set cache for netConf
|
||||
if req.isPXERequest() {
|
||||
@@ -227,6 +228,7 @@ func (req *dhcpRequest) fetchConfig(session *mcclient.ClientSession) (*dhcp.Resp
|
||||
// from guestdhcp import GuestDHCPHelperTask
|
||||
// task = GuestDHCPHelperTask(self)
|
||||
// task.start()
|
||||
log.Infof("Not found baremetal by mac: %s", req.ClientMac)
|
||||
return nil, nil, nil
|
||||
}
|
||||
req.baremetalInstance = bmInstance
|
||||
|
||||
@@ -670,6 +670,10 @@ func getDMIMemInfo(cli *ssh.Client) (*types.SDMIMemInfo, error) {
|
||||
return sysutils.ParseDMIMemInfo(ret), nil
|
||||
}
|
||||
|
||||
func GetNicsInfo(cli *ssh.Client) ([]*types.SNicDevInfo, error) {
|
||||
return getNicsInfo(cli)
|
||||
}
|
||||
|
||||
func getNicsInfo(cli *ssh.Client) ([]*types.SNicDevInfo, error) {
|
||||
ret, err := cli.Run("/lib/mos/lsnic")
|
||||
if err != nil {
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/baremetal/utils/raid"
|
||||
@@ -91,7 +92,7 @@ func DetectStorageInfo(term raid.IExecTerm, wait bool) ([]*baremetal.BaremetalSt
|
||||
break
|
||||
}
|
||||
}
|
||||
log.Infof("RaidDiskInfo: %#v, NonRaidSCSIDiskInfo: %#v, PCIEDiskInfo: %#v", raidDiskInfo, nonRaidDiskInfo, pcieDiskInfo)
|
||||
log.Infof("RaidDiskInfo: %s, NonRaidSCSIDiskInfo: %s, PCIEDiskInfo: %s", jsonutils.Marshal(raidDiskInfo), jsonutils.Marshal(nonRaidDiskInfo), jsonutils.Marshal(pcieDiskInfo))
|
||||
if len(nonRaidDiskInfo) < len(lvDiskInfo) {
|
||||
return nil, nil, nil, fmt.Errorf("Fail to retrieve disk info")
|
||||
}
|
||||
|
||||
@@ -288,7 +288,7 @@ func (ps *DiskPartitions) String() string {
|
||||
func (ps *DiskPartitions) DebugString() string {
|
||||
partitionsStr := []string{}
|
||||
for _, p := range ps.partitions {
|
||||
partitionsStr = append(partitionsStr, fmt.Sprintf("%#v", *p))
|
||||
partitionsStr = append(partitionsStr, fmt.Sprintf("{%#v}", *p))
|
||||
}
|
||||
return fmt.Sprintf("driver: %s, dev: %s, sectors: %d, partitions: %#v", ps.driver, ps.dev, ps.sectors, partitionsStr)
|
||||
}
|
||||
@@ -599,7 +599,7 @@ func (tool *PartitionTool) DebugString() string {
|
||||
return ret
|
||||
}
|
||||
for driver, disks := range tool.diskTable {
|
||||
s := fmt.Sprintf("%s: %v", driver, disksString(disks))
|
||||
s := fmt.Sprintf("(%s: %v)", driver, disksString(disks))
|
||||
ret = append(ret, s)
|
||||
}
|
||||
return strings.Join(ret, "\n")
|
||||
@@ -753,7 +753,7 @@ type SSHPartitionTool struct {
|
||||
term *ssh.Client
|
||||
}
|
||||
|
||||
func NewSSHPartitionTool(term *ssh.Client) *SSHPartitionTool {
|
||||
func newSSHPartitionTool(term *ssh.Client) *SSHPartitionTool {
|
||||
tool := &SSHPartitionTool{
|
||||
term: term,
|
||||
}
|
||||
@@ -761,6 +761,15 @@ func NewSSHPartitionTool(term *ssh.Client) *SSHPartitionTool {
|
||||
return tool
|
||||
}
|
||||
|
||||
func NewSSHPartitionTool(term *ssh.Client, layouts []baremetal.Layout) (*SSHPartitionTool, error) {
|
||||
tool := newSSHPartitionTool(term)
|
||||
tool.FetchDiskConfs(baremetal.GetDiskConfigurations(layouts))
|
||||
if err := tool.RetrieveDiskInfo(); err != nil {
|
||||
return nil, errors.Wrapf(err, "RetrieveDiskInfo")
|
||||
}
|
||||
return tool, nil
|
||||
}
|
||||
|
||||
func (tool *SSHPartitionTool) Run(cmds ...string) ([]string, error) {
|
||||
return tool.term.Run(cmds...)
|
||||
}
|
||||
|
||||
655
pkg/baremetal/utils/raid/adaptec/adaptec.go
Normal file
655
pkg/baremetal/utils/raid/adaptec/adaptec.go
Normal file
@@ -0,0 +1,655 @@
|
||||
// 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 adaptec
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/tristate"
|
||||
"yunion.io/x/pkg/util/stringutils"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/baremetal/utils/raid"
|
||||
"yunion.io/x/onecloud/pkg/compute/baremetal"
|
||||
"yunion.io/x/onecloud/pkg/util/regutils2"
|
||||
)
|
||||
|
||||
func init() {
|
||||
raid.RegisterDriver(api.DISK_DRIVER_ADAPTECRAID, NewAdaptecRaid)
|
||||
}
|
||||
|
||||
const (
|
||||
ControllerModeRaidExposeRaw = "RAID (Expose RAW)"
|
||||
ControllerModeRaidHideRaw = "RAID (Hide RAW)"
|
||||
ControllerModeMixed = "Mixed"
|
||||
)
|
||||
|
||||
type AdaptecRaid struct {
|
||||
term raid.IExecTerm
|
||||
adapters []*AdaptecRaidAdaptor
|
||||
}
|
||||
|
||||
func NewAdaptecRaid(term raid.IExecTerm) raid.IRaidDriver {
|
||||
return &AdaptecRaid{
|
||||
term: term,
|
||||
adapters: make([]*AdaptecRaidAdaptor, 0),
|
||||
}
|
||||
}
|
||||
|
||||
func GetCommand(args ...string) string {
|
||||
bin := "/opt/adaptec/arcconf"
|
||||
return raid.GetCommand(bin, args...)
|
||||
}
|
||||
|
||||
func (r *AdaptecRaid) GetName() string {
|
||||
return baremetal.DISK_DRIVER_ADAPTECRAID
|
||||
}
|
||||
|
||||
func (r *AdaptecRaid) ParsePhyDevs() error {
|
||||
cmd := GetCommand("LIST")
|
||||
ret, err := r.term.Run(cmd)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "list controllers")
|
||||
}
|
||||
if err := r.parsePhyDevs(ret); err != nil {
|
||||
return errors.Wrap(err, "parse physical device")
|
||||
}
|
||||
if len(r.adapters) == 0 {
|
||||
return errors.Errorf("Not found adaptec raid controller")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *AdaptecRaid) CleanRaid() error {
|
||||
for _, ada := range r.adapters {
|
||||
ada.removeJBODDisks()
|
||||
ada.RemoveLogicVolumes()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *AdaptecRaid) GetAdapters() []raid.IRaidAdapter {
|
||||
ret := make([]raid.IRaidAdapter, 0)
|
||||
for _, a := range r.adapters {
|
||||
ret = append(ret, a)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (r *AdaptecRaid) PreBuildRaid(confs []*api.BaremetalDiskConfig, adapterIdx int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
adaptorIDPatter = regexp.MustCompile(`Controller (?P<idx>[0-9]+):`)
|
||||
)
|
||||
|
||||
func getAdaptorIndex(line string) int {
|
||||
adapStr := regutils2.GetParams(adaptorIDPatter, line)["idx"]
|
||||
if adapStr == "" {
|
||||
return -1
|
||||
}
|
||||
adapInt, err := strconv.Atoi(adapStr)
|
||||
if err != nil {
|
||||
log.Errorf("Parse adapator string %q id error: %v", line, err)
|
||||
return -1
|
||||
}
|
||||
return adapInt
|
||||
}
|
||||
|
||||
func (r *AdaptecRaid) parsePhyDevs(lines []string) error {
|
||||
for _, line := range lines {
|
||||
index := getAdaptorIndex(line)
|
||||
if index == -1 {
|
||||
continue
|
||||
}
|
||||
ada, err := NewAdaptecRaidAdaptor(index, r)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "New raid adaptor %d", index)
|
||||
}
|
||||
r.adapters = append(r.adapters, ada)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AdaptecRaidAdaptor struct {
|
||||
*adaptorInfo
|
||||
|
||||
index int
|
||||
raid *AdaptecRaid
|
||||
devs []*AdaptecRaidPhyDev
|
||||
}
|
||||
|
||||
var (
|
||||
_ raid.IRaidAdapter = new(AdaptecRaidAdaptor)
|
||||
)
|
||||
|
||||
func NewAdaptecRaidAdaptor(index int, raid *AdaptecRaid) (*AdaptecRaidAdaptor, error) {
|
||||
adaptor := AdaptecRaidAdaptor{
|
||||
index: index,
|
||||
raid: raid,
|
||||
}
|
||||
if err := adaptor.fillInfo(); err != nil {
|
||||
return nil, errors.Wrapf(err, "fill adaptor %d info", adaptor.index)
|
||||
}
|
||||
if err := adaptor.fillDevices(); err != nil {
|
||||
return nil, errors.Wrap(err, "fill physical devices")
|
||||
}
|
||||
/*
|
||||
* if !adaptor.isRaidHideRawMode() {
|
||||
* if err := adaptor.setControllerModeRaidHideRaw(); err != nil {
|
||||
* return nil, errors.Wrap(err, "set controller mode to raid hide raw")
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
return &adaptor, nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) GetIndex() int {
|
||||
return ada.index
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) PreBuildRaid(confs []*api.BaremetalDiskConfig) error {
|
||||
if !ada.isRaidHideRawMode() {
|
||||
if err := ada.setControllerModeRaidHideRaw(); err != nil {
|
||||
return errors.Wrapf(err, "set controller mode to raid hide raw mode")
|
||||
}
|
||||
}
|
||||
if err := ada.removeJBODDisks(); err != nil {
|
||||
log.Warningf("remove all JBOD disks: %v", err)
|
||||
}
|
||||
// uninitialize all device to ready state
|
||||
if err := ada.uninitializeAllDevice(); err != nil {
|
||||
// return errors.Wrap(err, "uninitialize all devices")
|
||||
log.Warningf("uninitializeAllDevice error: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) getInitializeCmd(args ...string) string {
|
||||
newArgs := []string{"TASK", "START", fmt.Sprintf("%d", ada.GetIndex()), "DEVICE"}
|
||||
newArgs = append(newArgs, args...)
|
||||
newArgs = append(newArgs, "INITIALIZE", "noprompt")
|
||||
return GetCommand(newArgs...)
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) initializeDevice(channel string, id string) error {
|
||||
cmd := ada.getInitializeCmd(channel, id)
|
||||
_, err := ada.remoteRun(fmt.Sprintf("initialize device %s:%s", channel, id), cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) initializeAllDevice() error {
|
||||
cmd := ada.getInitializeCmd("ALL")
|
||||
_, err := ada.remoteRun("initialize all device", cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) uninitializeDevice(channel string, id string) error {
|
||||
cmd := ada.getUninitializeCmd(channel, id)
|
||||
_, err := ada.remoteRun(fmt.Sprintf("uninitialize device %s:%s", channel, id), cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) getUninitializeCmd(args ...string) string {
|
||||
newArgs := []string{"TASK", "START", fmt.Sprintf("%d", ada.GetIndex()), "DEVICE"}
|
||||
newArgs = append(newArgs, args...)
|
||||
newArgs = append(newArgs, "UNINITIALIZE", "noprompt")
|
||||
return GetCommand(newArgs...)
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) uninitializeAllDevice() error {
|
||||
cmd := ada.getUninitializeCmd("ALL")
|
||||
_, err := ada.remoteRun("uninitialize all devices", cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) getTerm() raid.IExecTerm {
|
||||
return ada.raid.term
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) remoteRun(hint string, cmd string) ([]string, error) {
|
||||
out, err := ada.getTerm().Run(cmd)
|
||||
if err != nil {
|
||||
return out, errors.Wrapf(err, "%q, out: %v", hint, out)
|
||||
}
|
||||
log.Debugf("remote run cmd %s %q successfully: %v", hint, cmd, out)
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) fillInfo() error {
|
||||
cmd := GetCommand("GETCONFIG", fmt.Sprintf("%d", ada.index), "AD")
|
||||
ret, err := ada.remoteRun("get AD config", cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info, err := getAdaptorInfo(ret)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get adaptor info")
|
||||
}
|
||||
ada.adaptorInfo = info
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) fillDevices() error {
|
||||
cmd := GetCommand("GETCONFIG", fmt.Sprintf("%d", ada.index), "PD")
|
||||
ret, err := ada.remoteRun("get PD config", cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
devs := getPhyDevices(ada.GetIndex(), ret)
|
||||
ada.devs = append(ada.devs, devs...)
|
||||
return nil
|
||||
}
|
||||
|
||||
func getPhyDevices(adapter int, lines []string) []*AdaptecRaidPhyDev {
|
||||
dev := newPhyDev(adapter)
|
||||
devs := make([]*AdaptecRaidPhyDev, 0)
|
||||
for _, line := range lines {
|
||||
if dev.parseLine(line) && dev.isComplete() {
|
||||
tmpDev := dev
|
||||
devs = append(devs, tmpDev)
|
||||
dev = newPhyDev(adapter)
|
||||
}
|
||||
}
|
||||
return devs
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) getChannelId(storage *baremetal.BaremetalStorage) (string, string, error) {
|
||||
if storage.Addr == "" {
|
||||
return "", "", errors.Errorf("storage %#v addr is empty", storage)
|
||||
}
|
||||
parts := strings.Split(storage.Addr, ":")
|
||||
if len(parts) != 2 {
|
||||
return "", "", errors.Errorf("invalid storage %#v addr %q", storage, storage.Addr)
|
||||
}
|
||||
return parts[0], parts[1], nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) getCreateCmd(args ...string) string {
|
||||
newArgs := []string{"CREATE", fmt.Sprintf("%d", ada.GetIndex())}
|
||||
newArgs = append(newArgs, args...)
|
||||
return GetCommand(newArgs...)
|
||||
}
|
||||
|
||||
// setControllerMode change adapter controller's mode
|
||||
// Controller Modes : 0 - RAID: Expose RAW
|
||||
// : 1 - Auto Volume Mode
|
||||
// : 2 - HBA Mode
|
||||
// : 3 - RAID: Hide RAW
|
||||
// : 4 - Simple Volume Mode
|
||||
// : 5 - Mixed
|
||||
func (ada *AdaptecRaidAdaptor) setControllerMode(mode int) error {
|
||||
cmd := GetCommand("SETCONTROLLERMODE", fmt.Sprintf("%d", ada.GetIndex()), fmt.Sprintf("%d", mode), "noprompt")
|
||||
if _, err := ada.remoteRun(fmt.Sprintf("set controller mode to %d", mode), cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) setControllerModeRaidExposeRaw() error {
|
||||
if err := ada.setControllerMode(0); err != nil {
|
||||
return errors.Wrap(err, "mode raid expose raw")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) setControllerModeRaidHideRaw() error {
|
||||
if err := ada.setControllerMode(3); err != nil {
|
||||
return errors.Wrap(err, "mode raid hide raw")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) setControllerModeMixed() error {
|
||||
if err := ada.setControllerMode(5); err != nil {
|
||||
return errors.Wrap(err, "mode mixed")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) buildJBOD(dev *baremetal.BaremetalStorage) error {
|
||||
channel, id, err := ada.getChannelId(dev)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get channel and id")
|
||||
}
|
||||
cmd := ada.getCreateCmd("JBOD", channel, id, "noprompt")
|
||||
if out, err := ada.remoteRun("create JBOD", cmd); err != nil {
|
||||
return errors.Wrapf(err, "run cmd %q, out: %q", cmd, out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) buildNonRaid(dev *baremetal.BaremetalStorage) error {
|
||||
// set to raid expose raw mode or mixed mode
|
||||
if !ada.isRaidExposeRawMode() && !ada.isMixedMode() {
|
||||
err := func() error {
|
||||
errs := []error{}
|
||||
if err := ada.setControllerModeRaidExposeRaw(); err != nil {
|
||||
errs = append(errs, err)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
if err := ada.setControllerModeMixed(); err != nil {
|
||||
errs = append(errs, err)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
return errors.NewAggregate(errs)
|
||||
}()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "set raid to expose raw or mixed mode")
|
||||
}
|
||||
}
|
||||
// try build JBOD firstly
|
||||
if err := ada.buildJBOD(dev); err != nil {
|
||||
log.Warningf("try build JBOD error: %v", err)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
// just uninitialize device when build JBOD fail
|
||||
channel, id, err := ada.getChannelId(dev)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := ada.uninitializeDevice(channel, id); err != nil {
|
||||
return errors.Wrapf(err, "uninitialize device %v when build jbod fail", dev)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) BuildNoneRaid(devs []*baremetal.BaremetalStorage) error {
|
||||
for _, dev := range devs {
|
||||
if err := ada.buildNonRaid(dev); err != nil {
|
||||
return errors.Wrap(err, "build nonraid")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) getBuildRaidCmd(level int, devs []*baremetal.BaremetalStorage) (string, error) {
|
||||
if len(devs) == 0 {
|
||||
return "", errors.Errorf("devices is empty")
|
||||
}
|
||||
args := []string{"LOGICALDRIVE", "MAX", fmt.Sprintf("%d", level)}
|
||||
chIds := []string{}
|
||||
for _, dev := range devs {
|
||||
ch, id, err := ada.getChannelId(dev)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "get device %v channel id", dev)
|
||||
}
|
||||
chIds = append(chIds, ch, id)
|
||||
}
|
||||
args = append(args, chIds...)
|
||||
cmd := ada.getCreateCmd(args...)
|
||||
return cmd, nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) buildRaid(level int, devs []*baremetal.BaremetalStorage, conf *api.BaremetalDiskConfig) error {
|
||||
// initialize each devs
|
||||
for _, dev := range devs {
|
||||
channel, id, err := ada.getChannelId(dev)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "get device %v channel id", dev)
|
||||
}
|
||||
if err := ada.initializeDevice(channel, id); err != nil {
|
||||
// return errors.Wrapf(err, "initialize device")
|
||||
log.Warningf("initialize device error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: support config to build raid params
|
||||
cmd, err := ada.getBuildRaidCmd(level, devs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = ada.remoteRun(fmt.Sprintf("build raid %d", level), cmd)
|
||||
return err
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) BuildRaid0(devs []*baremetal.BaremetalStorage, conf *api.BaremetalDiskConfig) error {
|
||||
return ada.buildRaid(0, devs, conf)
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) BuildRaid1(devs []*baremetal.BaremetalStorage, conf *api.BaremetalDiskConfig) error {
|
||||
return ada.buildRaid(1, devs, conf)
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) BuildRaid5(devs []*baremetal.BaremetalStorage, conf *api.BaremetalDiskConfig) error {
|
||||
return ada.buildRaid(5, devs, conf)
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) BuildRaid10(devs []*baremetal.BaremetalStorage, conf *api.BaremetalDiskConfig) error {
|
||||
return ada.buildRaid(10, devs, conf)
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) GetDevices() []*baremetal.BaremetalStorage {
|
||||
ret := []*baremetal.BaremetalStorage{}
|
||||
for idx, dev := range ada.devs {
|
||||
ret = append(ret, dev.ToBaremetalStorage(idx))
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) GetLogicVolumes() ([]*raid.RaidLogicalVolume, error) {
|
||||
cmd := GetCommand("GETCONFIG", fmt.Sprintf("%d", ada.index), "LD")
|
||||
ret, err := ada.remoteRun("get logic volumes", cmd)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Get logic volumes error: %v", err)
|
||||
}
|
||||
return getLogicalVolumes(ada.index, ret)
|
||||
}
|
||||
|
||||
func getLogicalVolumes(adapter int, lines []string) ([]*raid.RaidLogicalVolume, error) {
|
||||
lvs := make([]*raid.RaidLogicalVolume, 0)
|
||||
for _, line := range lines {
|
||||
m := regutils2.SubGroupMatch(`Logical Device number\s+(?P<idx>\d+)`, line)
|
||||
if len(m) > 0 {
|
||||
idxStr := m["idx"]
|
||||
idx, err := strconv.Atoi(idxStr)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("%s index str is not digit: %v", idxStr, err)
|
||||
}
|
||||
lvs = append(lvs, &raid.RaidLogicalVolume{
|
||||
Index: idx,
|
||||
Adapter: adapter,
|
||||
})
|
||||
}
|
||||
}
|
||||
return lvs, nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) removeJBODDisks() error {
|
||||
cmd := GetCommand("DELETE", fmt.Sprintf("%d", ada.index), "JBOD", "ALL", "noprompt")
|
||||
out, err := ada.remoteRun("delete JBOD disks", cmd)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "delete all JBOD output: %q", out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ada *AdaptecRaidAdaptor) RemoveLogicVolumes() error {
|
||||
lvs, err := ada.GetLogicVolumes()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get logic volumes")
|
||||
}
|
||||
if len(lvs) == 0 {
|
||||
return nil
|
||||
}
|
||||
cmd := GetCommand("DELETE", fmt.Sprintf("%d", ada.index), "LOGICALDRIVE", "ALL", "noprompt")
|
||||
out, err := ada.remoteRun("delete logical volumes", cmd)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "delete all logicaldrive output: %q", out)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type adaptorInfo struct {
|
||||
status string
|
||||
mode string
|
||||
name string
|
||||
sn string
|
||||
wwn string
|
||||
slot string
|
||||
}
|
||||
|
||||
func (ada *adaptorInfo) key() string {
|
||||
return ada.name + ada.sn
|
||||
}
|
||||
|
||||
func (ada *adaptorInfo) isRaidExposeRawMode() bool {
|
||||
return ada.mode == ControllerModeRaidExposeRaw
|
||||
}
|
||||
|
||||
func (ada *adaptorInfo) isRaidHideRawMode() bool {
|
||||
return ada.mode == ControllerModeRaidHideRaw
|
||||
}
|
||||
|
||||
func (ada *adaptorInfo) isMixedMode() bool {
|
||||
return ada.mode == ControllerModeMixed
|
||||
}
|
||||
|
||||
func getAdaptorInfo(lines []string) (*adaptorInfo, error) {
|
||||
ada := new(adaptorInfo)
|
||||
for _, l := range lines {
|
||||
key, val := stringutils.SplitKeyValue(l)
|
||||
if len(key) == 0 {
|
||||
continue
|
||||
}
|
||||
switch key {
|
||||
case "Controller Status":
|
||||
ada.status = val
|
||||
case "Controller Mode":
|
||||
ada.mode = val
|
||||
case "Controller Model":
|
||||
ada.name = val
|
||||
case "Controller Serial Number":
|
||||
ada.sn = val
|
||||
case "Controller World Wide Name":
|
||||
ada.wwn = val
|
||||
case "Physical Slot":
|
||||
ada.slot = val
|
||||
}
|
||||
}
|
||||
if len(ada.key()) == 0 {
|
||||
return nil, errors.Errorf("Not found SN and model name")
|
||||
}
|
||||
return ada, nil
|
||||
}
|
||||
|
||||
type AdaptecRaidPhyDev struct {
|
||||
*raid.RaidBasePhyDev
|
||||
// channelId and deviceId is parsed by Reported Channel,Device(T:L)
|
||||
// e.g.: Reported Channel,Device(T:L) : 0,6(6:0)
|
||||
channelId string
|
||||
deviceId string
|
||||
}
|
||||
|
||||
func newPhyDev(adapter int) *AdaptecRaidPhyDev {
|
||||
dev := &AdaptecRaidPhyDev{
|
||||
RaidBasePhyDev: raid.NewRaidBasePhyDev(api.DISK_DRIVER_ADAPTECRAID),
|
||||
}
|
||||
dev.Adapter = adapter
|
||||
return dev
|
||||
}
|
||||
|
||||
func (dev *AdaptecRaidPhyDev) isComplete() bool {
|
||||
if !dev.RaidBasePhyDev.IsComplete() {
|
||||
return false
|
||||
}
|
||||
if dev.channelId == "" || dev.deviceId == "" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (dev *AdaptecRaidPhyDev) ToBaremetalStorage(index int) *baremetal.BaremetalStorage {
|
||||
s := dev.RaidBasePhyDev.ToBaremetalStorage(index)
|
||||
s.Addr = fmt.Sprintf("%s:%s", dev.channelId, dev.deviceId)
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
var (
|
||||
channelDeviceRegexp = regexp.MustCompile(`Reported Channel,Device\(T:L\).*(?P<channel>\d+),(?P<device>\d+)\(\d+:\d+\)`)
|
||||
)
|
||||
|
||||
func (dev *AdaptecRaidPhyDev) parseLine(line string) bool {
|
||||
chanDevMatch := regutils2.GetParams(channelDeviceRegexp, line)
|
||||
if len(chanDevMatch) != 0 {
|
||||
channelId := chanDevMatch["channel"]
|
||||
deviceId := chanDevMatch["device"]
|
||||
dev.channelId = channelId
|
||||
dev.deviceId = deviceId
|
||||
return true
|
||||
}
|
||||
key, val := stringutils.SplitKeyValue(line)
|
||||
if key == "" {
|
||||
return false
|
||||
}
|
||||
switch key {
|
||||
case "Total Size":
|
||||
dat := strings.Split(val, " ")
|
||||
szStr, unitStr := dat[0], dat[1]
|
||||
var sz int64
|
||||
szInt, err := strconv.Atoi(szStr)
|
||||
if err != nil {
|
||||
log.Errorf("Parse size string %s: %v", szStr, err)
|
||||
return false
|
||||
}
|
||||
switch unitStr {
|
||||
case "GB":
|
||||
sz = int64(szInt * 1000 * 1000 * 100)
|
||||
case "TB":
|
||||
sz = int64(szInt * 1000 * 1000 * 1000 * 1000)
|
||||
case "MB":
|
||||
sz = int64(szInt * 1000 * 1000)
|
||||
default:
|
||||
log.Errorf("Unsupported unit: %s", unitStr)
|
||||
return false
|
||||
}
|
||||
dev.Size = sz / 1024 / 1024
|
||||
case "Model":
|
||||
dev.Model = strings.Join(regexp.MustCompile(`\s+`).Split(val, -1), " ")
|
||||
case "State":
|
||||
dev.Status = val
|
||||
case "SSD":
|
||||
if val == "No" {
|
||||
dev.Rotate = tristate.True
|
||||
} else {
|
||||
dev.Rotate = tristate.False
|
||||
}
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
422
pkg/baremetal/utils/raid/adaptec/adaptec_test.go
Normal file
422
pkg/baremetal/utils/raid/adaptec/adaptec_test.go
Normal file
@@ -0,0 +1,422 @@
|
||||
// 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 adaptec
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func Test_getAdaptorIndex(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args string
|
||||
want int
|
||||
}{
|
||||
{
|
||||
name: "Controllers found: 1",
|
||||
args: "Controllers found: 1",
|
||||
want: -1,
|
||||
},
|
||||
{
|
||||
name: " Controller 1: : Optimal, Slot 4, RAID (Expose RAW), Adaptec ASR8805, 6A2263667CA, 50000D1701B47780",
|
||||
args: " Controller 1: : Optimal, Slot 4, RAID (Expose RAW), Adaptec ASR8805, 6A2263667CA, 50000D1701B47780",
|
||||
want: 1,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := getAdaptorIndex(tt.args); got != tt.want {
|
||||
t.Errorf("getAdaptorIndex() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_getAdaptorInfo(t *testing.T) {
|
||||
input := `Controllers found: 1
|
||||
----------------------------------------------------------------------
|
||||
Controller information
|
||||
----------------------------------------------------------------------
|
||||
Controller Status : Optimal
|
||||
Controller Mode : RAID (Expose RAW)
|
||||
Channel description : SAS/SATA
|
||||
Controller Model : Adaptec ASR8805
|
||||
Controller Serial Number : 6A2263667CA
|
||||
Controller World Wide Name : 50000D1701B47780
|
||||
Controller Alarm : Disabled
|
||||
Physical Slot : 4
|
||||
Temperature : 42 C/ 107 F (Normal)
|
||||
Installed memory : 1024 MB
|
||||
Host bus type : PCIe
|
||||
Host bus speed : 8000 MHz
|
||||
Host bus link width : 8 bit(s)/link(s)
|
||||
Global task priority : High
|
||||
Performance Mode : Default/Dynamic
|
||||
PCI Device ID : 653
|
||||
Stayawake period : Disabled
|
||||
Spinup limit internal drives : 0
|
||||
Spinup limit external drives : 0
|
||||
Defunct disk drive count : 0
|
||||
NCQ status : Enabled
|
||||
Statistics data collection mode : Disabled
|
||||
Monitor Log Severity Level : Informational
|
||||
Global Max SAS Phy Link Rate : 12 Gbps
|
||||
Verify Write Setting : Not Applicable
|
||||
Save Custom Defaults Setting : Disabled
|
||||
Smart Poll : Enabled
|
||||
Error Tunable Profile : Normal
|
||||
--------------------------------------------------------
|
||||
Cache Properties
|
||||
--------------------------------------------------------
|
||||
Controller Cache Preservation : Disabled
|
||||
Global Physical Device Write Cache Policy: Drive Specific
|
||||
--------------------------------------------------------
|
||||
RAID Properties
|
||||
--------------------------------------------------------
|
||||
Logical devices/Failed/Degraded : 0/0/0
|
||||
Copyback : Disabled
|
||||
Automatic Failover : Enabled
|
||||
Background consistency check : Disabled
|
||||
Background consistency check period : 0
|
||||
--------------------------------------------------------
|
||||
Controller BIOS Setting Information
|
||||
--------------------------------------------------------
|
||||
Runtime BIOS : Enabled
|
||||
Array BBS Support : Disabled
|
||||
Physical Drives Displayed during POST : Disabled
|
||||
Backplane Mode : IBPI
|
||||
BIOS Halt on Missing Drive Count : 255
|
||||
--------------------------------------------------------
|
||||
Controller Version Information
|
||||
--------------------------------------------------------
|
||||
BIOS : 7.18-0 (33556)
|
||||
Firmware : 7.18-0 (33556)
|
||||
Driver : 1.2-1 (50983)
|
||||
Boot Flash : 7.18-0 (33556)
|
||||
CPLD (Load version/ Flash version) : 8/ 11
|
||||
SEEPROM (Load version/ Flash version) : 1/ 1
|
||||
FCT Custom Init String Version : 0x0
|
||||
|
||||
--------------------------------------------------------
|
||||
Controller Cache Backup Unit Information
|
||||
--------------------------------------------------------
|
||||
|
||||
Overall Backup Unit Status : Not Present
|
||||
--------------------------------------------------------
|
||||
Connector information
|
||||
|
||||
--------------------------------------------------------
|
||||
Connector #0
|
||||
Connector Name : CN0
|
||||
|
||||
--------------------------------------
|
||||
Lane Information
|
||||
--------------------------------------
|
||||
Lane #0
|
||||
Channel ID : 0
|
||||
Device ID : 0
|
||||
SAS Address : 50000D1701B47780
|
||||
PHY Identifier : 3
|
||||
-----------------------------------
|
||||
Lane SAS Phy Information
|
||||
-----------------------------------
|
||||
SAS Address : 50000D1701B47780
|
||||
|
||||
Lane #1
|
||||
Channel ID : 0
|
||||
Device ID : 1
|
||||
SAS Address : 50000D1701B47780
|
||||
PHY Identifier : 2
|
||||
-----------------------------------
|
||||
Lane SAS Phy Information
|
||||
-----------------------------------
|
||||
SAS Address : 50000D1701B47780
|
||||
|
||||
Lane #2
|
||||
Channel ID : 0
|
||||
Device ID : 2
|
||||
SAS Address : 50000D1701B47780
|
||||
PHY Identifier : 0
|
||||
-----------------------------------
|
||||
Lane SAS Phy Information
|
||||
-----------------------------------
|
||||
SAS Address : 50000D1701B47780
|
||||
|
||||
Lane #3
|
||||
Channel ID : 0
|
||||
Device ID : 3
|
||||
SAS Address : 50000D1701B47780
|
||||
PHY Identifier : 1
|
||||
-----------------------------------
|
||||
Lane SAS Phy Information
|
||||
-----------------------------------
|
||||
SAS Address : 50000D1701B47780
|
||||
|
||||
|
||||
Connector #1
|
||||
Connector Name : CN1
|
||||
|
||||
--------------------------------------
|
||||
Lane Information
|
||||
--------------------------------------
|
||||
Lane #0
|
||||
Channel ID : 0
|
||||
Device ID : 4
|
||||
SAS Address : 50000D1701B47780
|
||||
PHY Identifier : 5
|
||||
-----------------------------------
|
||||
Lane SAS Phy Information
|
||||
-----------------------------------
|
||||
SAS Address : 50000D1701B47780
|
||||
|
||||
Lane #1
|
||||
Channel ID : 0
|
||||
Device ID : 5
|
||||
SAS Address : 50000D1701B47780
|
||||
PHY Identifier : 6
|
||||
-----------------------------------
|
||||
Lane SAS Phy Information
|
||||
-----------------------------------
|
||||
SAS Address : 50000D1701B47780
|
||||
|
||||
Lane #2
|
||||
Channel ID : 0
|
||||
Device ID : 6
|
||||
SAS Address : 50000D1701B47780
|
||||
PHY Identifier : 4
|
||||
-----------------------------------
|
||||
Lane SAS Phy Information
|
||||
-----------------------------------
|
||||
SAS Address : 50000D1701B47780
|
||||
Attached PHY Identifier : 0
|
||||
Attached SAS Address : 5000C50077893141
|
||||
Negotiated Logical Link Rate : PHY enabled - 6 Gbps
|
||||
|
||||
Lane #3
|
||||
Channel ID : 0
|
||||
Device ID : 7
|
||||
SAS Address : 50000D1701B47780
|
||||
PHY Identifier : 7
|
||||
-----------------------------------
|
||||
Lane SAS Phy Information
|
||||
-----------------------------------
|
||||
SAS Address : 50000D1701B47780
|
||||
Attached PHY Identifier : 0
|
||||
Attached SAS Address : 50000395B839D9AE
|
||||
Negotiated Logical Link Rate : PHY enabled - 6 Gbps
|
||||
|
||||
|
||||
|
||||
|
||||
Command completed successfully.`
|
||||
lines := strings.Split(input, "\n")
|
||||
info, err := getAdaptorInfo(lines)
|
||||
if err != nil {
|
||||
t.Errorf("getAdaptorInfo: %v", err)
|
||||
}
|
||||
assert := assert.New(t)
|
||||
assert.Equal("Optimal", info.status)
|
||||
assert.Equal("RAID (Expose RAW)", info.mode)
|
||||
assert.Equal(true, info.isRaidExposeRawMode(), "should be raid expose raw mode")
|
||||
assert.Equal("Adaptec ASR8805", info.name)
|
||||
assert.Equal("6A2263667CA", info.sn)
|
||||
assert.Equal("50000D1701B47780", info.wwn)
|
||||
assert.Equal("4", info.slot)
|
||||
}
|
||||
|
||||
func Test_getPhyDevices(t *testing.T) {
|
||||
input := `Controllers found: 1
|
||||
----------------------------------------------------------------------
|
||||
Physical Device information
|
||||
----------------------------------------------------------------------
|
||||
Device #0
|
||||
Device is a Hard drive
|
||||
State : Online
|
||||
Block Size : 512 Bytes
|
||||
Supported : Yes
|
||||
Programmed Max Speed : SAS 6.0 Gb/s
|
||||
Transfer Speed : SAS 6.0 Gb/s
|
||||
Reported Channel,Device(T:L) : 0,6(6:0)
|
||||
Reported Location : Connector 1, Device 2
|
||||
Vendor : SEAGATE
|
||||
Model : ST300MM0006
|
||||
Firmware : LS0A
|
||||
Serial number : S0K30A4N
|
||||
World-wide name : 5000C50077893140
|
||||
Reserved Size : 415982 KB
|
||||
Used Size : 285696 MB
|
||||
Unused Size : 64 KB
|
||||
Total Size : 286102 MB
|
||||
Write Cache : Disabled (write-through)
|
||||
FRU : None
|
||||
S.M.A.R.T. : No
|
||||
S.M.A.R.T. warnings : 0
|
||||
Power State : Full rpm
|
||||
Supported Power States : Full rpm,Powered off
|
||||
SSD : No
|
||||
Temperature : 34 C/ 93 F
|
||||
----------------------------------------------------------------
|
||||
Device Phy Information
|
||||
----------------------------------------------------------------
|
||||
Phy #0
|
||||
PHY Identifier : 0
|
||||
SAS Address : 5000C50077893141
|
||||
Attached PHY Identifier : 4
|
||||
Attached SAS Address : 50000D1701B47780
|
||||
Phy #1
|
||||
PHY Identifier : 1
|
||||
SAS Address : 5000C50077893142
|
||||
----------------------------------------------------------------
|
||||
Runtime Error Counters
|
||||
----------------------------------------------------------------
|
||||
Hardware Error Count : 0
|
||||
Medium Error Count : 0
|
||||
Parity Error Count : 0
|
||||
Link Failure Count : 0
|
||||
Aborted Command Count : 0
|
||||
SMART Warning Count : 0
|
||||
|
||||
Device #1
|
||||
Device is a Hard drive
|
||||
State : Online
|
||||
Block Size : 512 Bytes
|
||||
Supported : Yes
|
||||
Programmed Max Speed : SAS 6.0 Gb/s
|
||||
Transfer Speed : SAS 6.0 Gb/s
|
||||
Reported Channel,Device(T:L) : 0,7(7:0)
|
||||
Reported Location : Connector 1, Device 3
|
||||
Vendor : TOSHIBA
|
||||
Model : AL13SEB300
|
||||
Firmware : DE0D
|
||||
Serial number : 84T0A31SFRD6
|
||||
World-wide name : 50000395B839D9AC
|
||||
Reserved Size : 415982 KB
|
||||
Used Size : 285696 MB
|
||||
Unused Size : 64 KB
|
||||
Total Size : 286102 MB
|
||||
Write Cache : Disabled (write-through)
|
||||
FRU : None
|
||||
S.M.A.R.T. : No
|
||||
S.M.A.R.T. warnings : 0
|
||||
Power State : Full rpm
|
||||
Supported Power States : Full rpm,Powered off
|
||||
SSD : No
|
||||
Temperature : 33 C/ 91 F
|
||||
----------------------------------------------------------------
|
||||
Device Phy Information
|
||||
----------------------------------------------------------------
|
||||
Phy #0
|
||||
PHY Identifier : 0
|
||||
SAS Address : 50000395B839D9AE
|
||||
Attached PHY Identifier : 7
|
||||
Attached SAS Address : 50000D1701B47780
|
||||
Phy #1
|
||||
PHY Identifier : 1
|
||||
SAS Address : 50000395B839D9AF
|
||||
----------------------------------------------------------------
|
||||
Runtime Error Counters
|
||||
----------------------------------------------------------------
|
||||
Hardware Error Count : 0
|
||||
Medium Error Count : 0
|
||||
Parity Error Count : 0
|
||||
Link Failure Count : 0
|
||||
Aborted Command Count : 0
|
||||
SMART Warning Count : 0
|
||||
|
||||
|
||||
|
||||
Command completed successfully.`
|
||||
lines := strings.Split(input, "\n")
|
||||
devs := getPhyDevices(1, lines)
|
||||
assert := assert.New(t)
|
||||
assert.Equal(2, len(devs), "physical devices should be 2")
|
||||
dev1 := devs[0]
|
||||
assert.Equal("0", dev1.channelId)
|
||||
assert.Equal("6", dev1.deviceId)
|
||||
assert.Equal("Online", dev1.Status)
|
||||
assert.Equal("ST300MM0006", dev1.Model)
|
||||
assert.Equal(true, dev1.Rotate.Bool())
|
||||
|
||||
dev2 := devs[1]
|
||||
assert.Equal("0", dev2.channelId)
|
||||
assert.Equal("7", dev2.deviceId)
|
||||
assert.Equal("Online", dev2.Status)
|
||||
assert.Equal("AL13SEB300", dev2.Model)
|
||||
assert.Equal(true, dev2.Rotate.Bool())
|
||||
}
|
||||
|
||||
func Test_getLogicalVolums(t *testing.T) {
|
||||
input := `Controllers found: 1
|
||||
----------------------------------------------------------------------
|
||||
Logical device information
|
||||
----------------------------------------------------------------------
|
||||
Logical Device number 0
|
||||
Logical Device name : LogicalDrv 0
|
||||
Block Size of member drives : 512 Bytes
|
||||
RAID level : 1
|
||||
Unique Identifier : 7D30DCD4
|
||||
Status of Logical Device : Optimal
|
||||
Additional details : Quick initialized
|
||||
Size : 285686 MB
|
||||
Parity space : 285696 MB
|
||||
Interface Type : Serial Attached SCSI
|
||||
Device Type : HDD
|
||||
Read-cache setting : Enabled
|
||||
Read-cache status : On
|
||||
Write-cache setting : Enabled
|
||||
Write-cache status : On
|
||||
Partitioned : No
|
||||
Protected by Hot-Spare : No
|
||||
Bootable : Yes
|
||||
Failed stripes : No
|
||||
Power settings : Disabled
|
||||
--------------------------------------------------------
|
||||
Logical Device segment information
|
||||
--------------------------------------------------------
|
||||
Segment 0 : Present (286102MB, SAS, HDD, Connector:1, Device:2) S0K30A4N
|
||||
Segment 1 : Present (286102MB, SAS, HDD, Connector:1, Device:3) 84T0A31SFRD6
|
||||
|
||||
|
||||
|
||||
Command completed successfully.`
|
||||
lines := strings.Split(input, "\n")
|
||||
lvs, err := getLogicalVolumes(1, lines)
|
||||
if err != nil {
|
||||
t.Errorf("getLogicalVolumes: %v", err)
|
||||
}
|
||||
assert := assert.New(t)
|
||||
assert.Equal(1, len(lvs), "logical volume len should be 1")
|
||||
lv := lvs[0]
|
||||
assert.Equal(1, lv.Adapter)
|
||||
assert.Equal(0, lv.Index)
|
||||
|
||||
inputNoLV := `Controllers found: 1
|
||||
----------------------------------------------------------------------
|
||||
Logical device information
|
||||
----------------------------------------------------------------------
|
||||
No logical devices configured
|
||||
|
||||
|
||||
Command completed successfully.`
|
||||
lines = strings.Split(inputNoLV, "\n")
|
||||
lvs, err = getLogicalVolumes(1, lines)
|
||||
if err != nil {
|
||||
t.Errorf("getLogicalVolumes: %v", err)
|
||||
}
|
||||
assert.Equal(0, len(lvs), "logical volume len should be 0")
|
||||
}
|
||||
@@ -12,4 +12,4 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package client // import "yunion.io/x/onecloud/pkg/multicloud/huaweistack/client"
|
||||
package adaptec // import "yunion.io/x/onecloud/pkg/baremetal/utils/raid/adaptec"
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/baremetal/utils/raid"
|
||||
_ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/adaptec"
|
||||
_ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/hpssactl"
|
||||
_ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/megactl"
|
||||
_ "yunion.io/x/onecloud/pkg/baremetal/utils/raid/mvcli"
|
||||
@@ -64,6 +65,8 @@ func GetDriverByKernelModule(module string, term raid.IExecTerm) (raid.IRaidDriv
|
||||
name = baremetal.DISK_DRIVER_HPSARAID
|
||||
case raid.MODULE_MPT2SAS, raid.MODULE_MPT3SAS:
|
||||
name = baremetal.DISK_DRIVER_MPT2SAS
|
||||
case raid.MODULE_AACRAID, raid.MODULE_SMARTPQI:
|
||||
name = baremetal.DISK_DRIVER_ADAPTECRAID
|
||||
}
|
||||
if name == "" {
|
||||
return nil, errors.Errorf("Not support module %q", module)
|
||||
@@ -93,13 +96,13 @@ func BuildRaid(driver raid.IRaidDriver, confs []*api.BaremetalDiskConfig, adapte
|
||||
if adapter == nil {
|
||||
return fmt.Errorf("Not found adapter by index %d", adapterIdx)
|
||||
}
|
||||
if err := buildRaid(adapter, confs); err != nil {
|
||||
if err := buildRaid(driver, adapter, confs); err != nil {
|
||||
return fmt.Errorf("Driver %s, adapter %d build raid: %v", driver.GetName(), adapterIdx, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func buildRaid(adapter raid.IRaidAdapter, confs []*api.BaremetalDiskConfig) error {
|
||||
func buildRaid(driver raid.IRaidDriver, adapter raid.IRaidAdapter, confs []*api.BaremetalDiskConfig) error {
|
||||
if err := adapter.PreBuildRaid(confs); err != nil {
|
||||
return fmt.Errorf("PreBuildRaid: %v", err)
|
||||
}
|
||||
@@ -139,6 +142,7 @@ func buildRaid(adapter raid.IRaidAdapter, confs []*api.BaremetalDiskConfig) erro
|
||||
if err != nil {
|
||||
return fmt.Errorf("Build raid %s: %v", conf.Conf, err)
|
||||
}
|
||||
log.Infof("Build %s:%d raid %s", driver.GetName(), adapter.GetIndex(), conf.Conf)
|
||||
}
|
||||
if len(nonDisks) > 0 {
|
||||
if err := adapter.BuildNoneRaid(nonDisks); err != nil {
|
||||
|
||||
@@ -36,6 +36,8 @@ const (
|
||||
MODULE_HPSA = "hpsa"
|
||||
MODULE_MPT2SAS = "mpt2sas"
|
||||
MODULE_MPT3SAS = "mpt3sas"
|
||||
MODULE_AACRAID = "aacraid"
|
||||
MODULE_SMARTPQI = "smartpqi"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -38,7 +38,7 @@ type Mpt2SASRaidPhyDev struct {
|
||||
}
|
||||
|
||||
func newMpt2SASRaidPhyDev(adapter int) *Mpt2SASRaidPhyDev {
|
||||
b := raid.NewRaidBasePhyDev(baremetal.DISK_DRIVER_MARVELRAID)
|
||||
b := raid.NewRaidBasePhyDev(baremetal.DISK_DRIVER_MPT2SAS)
|
||||
b.Adapter = adapter
|
||||
return &Mpt2SASRaidPhyDev{
|
||||
RaidBasePhyDev: b,
|
||||
@@ -116,6 +116,7 @@ func (dev *Mpt2SASRaidPhyDev) isComplete() bool {
|
||||
|
||||
func (dev *Mpt2SASRaidPhyDev) ToBaremetalStorage(idx int) *baremetal.BaremetalStorage {
|
||||
s := dev.RaidBasePhyDev.ToBaremetalStorage(idx)
|
||||
s.Index = int64(idx)
|
||||
s.Slot = dev.slot
|
||||
s.Enclosure = dev.enclosure
|
||||
s.Block = int64(dev.block)
|
||||
@@ -296,7 +297,9 @@ func (adapter *Mpt2SASRaidAdaptor) BuildRaid10(devs []*baremetal.BaremetalStorag
|
||||
}
|
||||
|
||||
func (adapter *Mpt2SASRaidAdaptor) BuildNoneRaid(devs []*baremetal.BaremetalStorage) error {
|
||||
return fmt.Errorf("Not impl")
|
||||
// TODO: not impl
|
||||
// return fmt.Errorf("Not impl")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (adapter *Mpt2SASRaidAdaptor) RemoveLogicVolumes() error {
|
||||
@@ -338,11 +341,25 @@ func (r *Mpt2SASRaid) ParsePhyDevs() error {
|
||||
return r.parseAdapters(ret)
|
||||
}
|
||||
|
||||
func getLineAdapterIndex(line string) int {
|
||||
dat := regexp.MustCompile(`\s+`).Split(strings.TrimSpace(line), -1)
|
||||
if len(dat) == 0 {
|
||||
return -1
|
||||
}
|
||||
if regexp.MustCompile(`\d+`).MatchString(dat[0]) {
|
||||
if !regexp.MustCompile(`^\d+`).MatchString(dat[0]) {
|
||||
return -1
|
||||
}
|
||||
idx, _ := strconv.Atoi(dat[0])
|
||||
return idx
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
func (r *Mpt2SASRaid) parseAdapters(lines []string) error {
|
||||
for _, line := range lines {
|
||||
dat := regexp.MustCompile(`\s+`).Split(strings.TrimSpace(line), -1)
|
||||
if regexp.MustCompile(`\d+`).MatchString(dat[0]) {
|
||||
idx, _ := strconv.Atoi(dat[0])
|
||||
idx := getLineAdapterIndex(line)
|
||||
if idx >= 0 {
|
||||
adapter := newMpt2SASRaidAdaptor(idx, r)
|
||||
r.adapters = append(r.adapters, adapter)
|
||||
}
|
||||
|
||||
40
pkg/baremetal/utils/raid/sas2iru/sas2iru_test.go
Normal file
40
pkg/baremetal/utils/raid/sas2iru/sas2iru_test.go
Normal file
@@ -0,0 +1,40 @@
|
||||
// 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 sas2iru
|
||||
|
||||
import "testing"
|
||||
|
||||
func Test_getLineAdapterIndex(t *testing.T) {
|
||||
tests := []struct {
|
||||
line string
|
||||
want int
|
||||
}{
|
||||
{
|
||||
line: "0 SAS3008 100h 97h 00h:5eh:00h:00h 1000h 0097h",
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
line: "SAS3IRCU: Utility Completed Successfully.",
|
||||
want: -1,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.line, func(t *testing.T) {
|
||||
if got := getLineAdapterIndex(tt.line); got != tt.want {
|
||||
t.Errorf("getLineAdapterIndex() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ func ServeForeverExtended(app *appsrv.Application, options *common_options.BaseO
|
||||
if options.EnableSsl {
|
||||
proto = "https"
|
||||
}
|
||||
log.Infof("Start listen on %s://%s", proto, addr)
|
||||
log.Infof("Start listen on %s://%s, isMaster: %v", proto, addr, isMaster)
|
||||
var certfile string
|
||||
var sslfile string
|
||||
if options.EnableSsl {
|
||||
|
||||
@@ -19,9 +19,11 @@ import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
@@ -86,25 +88,45 @@ func InitDB(options *common_options.DBOptions) {
|
||||
}
|
||||
// lm := lockman.NewNoopLockManager()
|
||||
|
||||
if len(options.EtcdEndpoints) != 0 {
|
||||
log.Infof("using etcd as resource informer backend")
|
||||
tlsCfg, err := options.GetEtcdTLSConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("get etcd informer backend tls config err: %v", err)
|
||||
startInitInformer(options)
|
||||
}
|
||||
|
||||
// startInitInformer starts goroutine init informer backend
|
||||
func startInitInformer(options *common_options.DBOptions) {
|
||||
go func() {
|
||||
if len(options.EtcdEndpoints) == 0 {
|
||||
return
|
||||
}
|
||||
informerBackend, err := informer.NewEtcdBackend(&etcd.SEtcdOptions{
|
||||
EtcdEndpoint: options.EtcdEndpoints,
|
||||
EtcdTimeoutSeconds: 5,
|
||||
EtcdRequestTimeoutSeconds: 2,
|
||||
EtcdLeaseExpireSeconds: 5,
|
||||
EtcdEnabldSsl: options.EtcdUseTLS,
|
||||
TLSConfig: tlsCfg,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
log.Fatalf("new etcd informer backend error: %v", err)
|
||||
for {
|
||||
log.Infof("using etcd as resource informer backend")
|
||||
if err := initInformer(options); err != nil {
|
||||
log.Errorf("Init informer error: %v", err)
|
||||
time.Sleep(10 * time.Second)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
informer.Init(informerBackend)
|
||||
}()
|
||||
}
|
||||
|
||||
func initInformer(options *common_options.DBOptions) error {
|
||||
tlsCfg, err := options.GetEtcdTLSConfig()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get etcd informer backend tls config")
|
||||
}
|
||||
informerBackend, err := informer.NewEtcdBackend(&etcd.SEtcdOptions{
|
||||
EtcdEndpoint: options.EtcdEndpoints,
|
||||
EtcdTimeoutSeconds: 5,
|
||||
EtcdRequestTimeoutSeconds: 2,
|
||||
EtcdLeaseExpireSeconds: 5,
|
||||
EtcdEnabldSsl: options.EtcdUseTLS,
|
||||
TLSConfig: tlsCfg,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "new etcd informer backend")
|
||||
}
|
||||
informer.Init(informerBackend)
|
||||
return nil
|
||||
}
|
||||
|
||||
func CloseDB() {
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"yunion.io/x/pkg/gotypes"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
@@ -284,12 +285,32 @@ func FetchCustomizeColumns(
|
||||
if ret[0].Len() != len(objs) {
|
||||
return nil, httperrors.NewInternalServerError("Invalid FetchCustomizeColumns return value, inconsistent obj count: input %d != output %d", len(objs), ret[0].Len())
|
||||
}
|
||||
|
||||
showReason := false
|
||||
if query.Contains("show_fail_reason") {
|
||||
showReason = true
|
||||
}
|
||||
|
||||
retVal := make([]*jsonutils.JSONDict, ret[0].Len())
|
||||
for i := 0; i < ret[0].Len(); i += 1 {
|
||||
jsonDict := ValueToJSONDict(ret[0].Index(i))
|
||||
// NOTE: don't use obj update jsonDict as retval
|
||||
jsonDict.Update(jsonutils.Marshal(objs[i]).(*jsonutils.JSONDict))
|
||||
out := apis.ModelBaseDetails{
|
||||
CanDelete: true,
|
||||
}
|
||||
|
||||
err = ValidateDeleteCondition(objs[i].(IModel), ctx, jsonDict)
|
||||
if err != nil {
|
||||
out.CanDelete = false
|
||||
if showReason {
|
||||
out.DeleteFailReason = httperrors.NewErrorFromGeneralError(ctx, err)
|
||||
}
|
||||
}
|
||||
jsonDict.Update(jsonutils.Marshal(out))
|
||||
|
||||
retVal[i] = jsonDict
|
||||
|
||||
}
|
||||
return retVal, nil
|
||||
}
|
||||
@@ -319,3 +340,14 @@ func CustomizeDelete(model IModel, ctx context.Context, userCred mcclient.TokenC
|
||||
}
|
||||
return ValueToError(ret[0])
|
||||
}
|
||||
|
||||
func ValidateDeleteCondition(model IModel, ctx context.Context, data jsonutils.JSONObject) error {
|
||||
ret, err := call(model, "ValidateDeleteCondition", ctx, data)
|
||||
if err != nil {
|
||||
return httperrors.NewGeneralError(err)
|
||||
}
|
||||
if len(ret) != 1 {
|
||||
return httperrors.NewInternalServerError("Invald ValidateDeleteCondition return value")
|
||||
}
|
||||
return ValueToError(ret[0])
|
||||
}
|
||||
|
||||
@@ -854,17 +854,9 @@ func (dispatcher *DBModelDispatcher) List(ctx context.Context, query jsonutils.J
|
||||
|
||||
func getModelExtraDetails(item IModel, ctx context.Context, showReason bool) apis.ModelBaseDetails {
|
||||
out := apis.ModelBaseDetails{
|
||||
CanDelete: true,
|
||||
CanUpdate: true,
|
||||
}
|
||||
err := item.ValidateDeleteCondition(ctx)
|
||||
if err != nil {
|
||||
out.CanDelete = false
|
||||
if showReason {
|
||||
out.DeleteFailReason = httperrors.NewErrorFromGeneralError(ctx, err)
|
||||
}
|
||||
}
|
||||
err = item.ValidateUpdateCondition(ctx)
|
||||
err := item.ValidateUpdateCondition(ctx)
|
||||
if err != nil {
|
||||
out.CanUpdate = false
|
||||
if showReason {
|
||||
@@ -1834,9 +1826,9 @@ func DeleteModel(ctx context.Context, userCred mcclient.TokenCredential, item IM
|
||||
|
||||
func deleteItem(manager IModelManager, model IModel, ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
// log.Debugf("deleteItem %s", jsonutils.Marshal(model))
|
||||
err := model.ValidateDeleteCondition(ctx)
|
||||
|
||||
err := ValidateDeleteCondition(model, ctx, nil)
|
||||
if err != nil {
|
||||
log.Errorf("validate delete condition error: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -286,7 +286,7 @@ func (dispatcher *DBJointModelDispatcher) Detach(ctx context.Context, id1 string
|
||||
}
|
||||
|
||||
func DetachJoint(ctx context.Context, userCred mcclient.TokenCredential, item IJointModel) error {
|
||||
err := item.ValidateDeleteCondition(ctx)
|
||||
err := ValidateDeleteCondition(item, ctx, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ type IModel interface {
|
||||
|
||||
// delete hooks
|
||||
AllowDeleteItem(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool
|
||||
ValidateDeleteCondition(ctx context.Context) error
|
||||
// ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error
|
||||
// CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error
|
||||
PreDelete(ctx context.Context, userCred mcclient.TokenCredential)
|
||||
MarkDelete() error
|
||||
|
||||
@@ -30,13 +30,9 @@ import (
|
||||
|
||||
type SMetadataResourceBaseModelManager struct{}
|
||||
|
||||
func (meta *SMetadataResourceBaseModelManager) ListItemFilter(
|
||||
manager IModelManager,
|
||||
q *sqlchemy.SQuery,
|
||||
input apis.MetadataResourceListInput,
|
||||
) *sqlchemy.SQuery {
|
||||
func (meta *SMetadataResourceBaseModelManager) objIdQueryWithTags(modelName string, oTags ...apis.STag) *sqlchemy.SQuery {
|
||||
tags := map[string][]string{}
|
||||
for _, tag := range input.Tags {
|
||||
for _, tag := range oTags {
|
||||
if _, ok := tags[tag.Key]; !ok {
|
||||
tags[tag.Key] = []string{}
|
||||
}
|
||||
@@ -46,7 +42,7 @@ func (meta *SMetadataResourceBaseModelManager) ListItemFilter(
|
||||
}
|
||||
|
||||
if len(tags) > 0 {
|
||||
metadataResQ := Metadata.Query().Equals("obj_type", manager.Keyword()).SubQuery()
|
||||
metadataResQ := Metadata.Query().Equals("obj_type", modelName).SubQuery()
|
||||
metadataView := metadataResQ.Query()
|
||||
idx := 0
|
||||
for key, values := range tags {
|
||||
@@ -66,8 +62,30 @@ func (meta *SMetadataResourceBaseModelManager) ListItemFilter(
|
||||
idx++
|
||||
}
|
||||
metadatas := metadataView.SubQuery()
|
||||
sq := metadatas.Query(metadatas.Field("obj_id")).Distinct().SubQuery()
|
||||
q = q.Filter(sqlchemy.In(q.Field("id"), sq))
|
||||
return metadatas.Query(metadatas.Field("obj_id")).Distinct()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (meta *SMetadataResourceBaseModelManager) ListItemFilter(
|
||||
manager IModelManager,
|
||||
q *sqlchemy.SQuery,
|
||||
input apis.MetadataResourceListInput,
|
||||
) *sqlchemy.SQuery {
|
||||
if len(input.Tags) > 0 {
|
||||
sq := meta.objIdQueryWithTags(manager.Keyword(), input.Tags...)
|
||||
if sq != nil {
|
||||
q = q.Filter(sqlchemy.In(q.Field("id"), sq.SubQuery()))
|
||||
}
|
||||
}
|
||||
|
||||
if len(input.NoTags) > 0 {
|
||||
for _, tag := range input.NoTags {
|
||||
sq := meta.objIdQueryWithTags(manager.Keyword(), tag)
|
||||
if sq != nil {
|
||||
q = q.Filter(sqlchemy.NotIn(q.Field("id"), sq.SubQuery()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if input.WithoutUserMeta != nil || input.WithUserMeta != nil {
|
||||
|
||||
@@ -580,7 +580,7 @@ func (model *SModelBase) ValidateUpdateCondition(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (model *SModelBase) ValidateDeleteCondition(ctx context.Context) error {
|
||||
func (model *SModelBase) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -363,7 +363,7 @@ func (self *SOpsLog) AllowDeleteItem(ctx context.Context, userCred mcclient.Toke
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SOpsLog) ValidateDeleteCondition(ctx context.Context) error {
|
||||
func (self *SOpsLog) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
|
||||
return httperrors.NewForbiddenError("not allow to delete log")
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ func (ps *SProxySetting) HttpTransportProxyFunc() httputils.TransportProxyFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func (ps *SProxySetting) ValidateDeleteCondition(ctx context.Context) error {
|
||||
func (ps *SProxySetting) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
|
||||
if ps.Id == proxyapi.ProxySettingId_DIRECT {
|
||||
return httperrors.NewConflictError("DIRECT setting cannot be deleted")
|
||||
}
|
||||
@@ -122,7 +122,7 @@ func (ps *SProxySetting) ValidateDeleteCondition(ctx context.Context) error {
|
||||
ps.Id, n, man.KeywordPlural())
|
||||
}
|
||||
}
|
||||
return ps.SInfrasResourceBase.ValidateDeleteCondition(ctx)
|
||||
return ps.SInfrasResourceBase.ValidateDeleteCondition(ctx, nil)
|
||||
}
|
||||
|
||||
func (ps *SProxySetting) AllowPerformTest(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
|
||||
@@ -173,7 +173,7 @@ func (self *STask) AllowDeleteItem(ctx context.Context, userCred mcclient.TokenC
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *STask) ValidateDeleteCondition(ctx context.Context) error {
|
||||
func (self *STask) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
|
||||
return httperrors.NewForbiddenError("forbidden")
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +130,72 @@ func (manager *SVirtualResourceBaseManager) GetPropertyStatistics(ctx context.Co
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (manager *SVirtualResourceBaseManager) AllowGetPropertyProjectStatistics(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return IsAdminAllowGetSpec(userCred, manager, "project-statistics")
|
||||
}
|
||||
|
||||
func (manager *SVirtualResourceBaseManager) GetPropertyProjectStatistics(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) ([]apis.ProjectStatistic, error) {
|
||||
im, ok := manager.GetVirtualObject().(IModelManager)
|
||||
if !ok {
|
||||
im = manager
|
||||
}
|
||||
|
||||
tenants := TenantCacheManager.GetTenantQuery().Equals("domain_id", userCred.GetProjectDomainId()).SubQuery()
|
||||
|
||||
_q, err := ListItemQueryFilters(im, ctx, im.Query(), userCred, query, policy.PolicyActionList)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sq := _q.SubQuery()
|
||||
|
||||
q := sq.Query(
|
||||
sq.Field("tenant_id"),
|
||||
sqlchemy.COUNT("count"),
|
||||
).GroupBy(sq.Field("tenant_id"))
|
||||
|
||||
q.Join(tenants, sqlchemy.Equals(q.Field("tenant_id"), tenants.Field("id")))
|
||||
|
||||
q.AppendField(tenants.Field("id"))
|
||||
q.AppendField(tenants.Field("name"))
|
||||
|
||||
result := []apis.ProjectStatistic{}
|
||||
return result, q.All(&result)
|
||||
}
|
||||
|
||||
func (manager *SVirtualResourceBaseManager) AllowGetPropertyDomainStatistics(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return IsAdminAllowGetSpec(userCred, manager, "domain-statistics")
|
||||
}
|
||||
|
||||
func (manager *SVirtualResourceBaseManager) GetPropertyDomainStatistics(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) ([]apis.ProjectStatistic, error) {
|
||||
im, ok := manager.GetVirtualObject().(IModelManager)
|
||||
if !ok {
|
||||
im = manager
|
||||
}
|
||||
|
||||
domains := TenantCacheManager.GetDomainQuery().SubQuery()
|
||||
|
||||
_q, err := ListItemQueryFilters(im, ctx, im.Query(), userCred, query, policy.PolicyActionList)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sq := _q.SubQuery()
|
||||
|
||||
q := sq.Query(
|
||||
sq.Field("domain_id"),
|
||||
sqlchemy.COUNT("count"),
|
||||
).GroupBy(sq.Field("domain_id"))
|
||||
|
||||
q.Join(domains, sqlchemy.Equals(q.Field("domain_id"), domains.Field("id")))
|
||||
|
||||
q.AppendField(domains.Field("id"))
|
||||
q.AppendField(domains.Field("name"))
|
||||
|
||||
result := []apis.ProjectStatistic{}
|
||||
return result, q.All(&result)
|
||||
}
|
||||
|
||||
func (manager *SVirtualResourceBaseManager) FilterByHiddenSystemAttributes(q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject, scope rbacutils.TRbacScope) *sqlchemy.SQuery {
|
||||
q = manager.SStatusStandaloneResourceBaseManager.FilterByHiddenSystemAttributes(q, userCred, query, scope)
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ func NotifyRobot(robotIds []string, priority npk.TNotifyPriority, event string,
|
||||
|
||||
// NotifyRobot will send messages via all robot contact type such as dingtalk-robot.
|
||||
func NotifyRobotWithCtx(ctx context.Context, robotIds []string, priority npk.TNotifyPriority, event string, data jsonutils.JSONObject) error {
|
||||
rawNotify(context.Background(), sNotifyParams{
|
||||
rawNotify(ctx, sNotifyParams{
|
||||
robots: robotIds,
|
||||
channel: npk.NotifyByRobot,
|
||||
priority: priority,
|
||||
@@ -284,6 +284,7 @@ func EventNotify(ctx context.Context, userCred mcclient.TokenCredential, ep SEve
|
||||
ResourceDetails: objDetails,
|
||||
Event: event.String(),
|
||||
AdvanceDays: ep.AdvanceDays,
|
||||
Priority: string(npk.NotifyPriorityNormal),
|
||||
ProjectId: projectId,
|
||||
ProjectDomainId: projectDomainId,
|
||||
}
|
||||
|
||||
@@ -102,6 +102,8 @@ type BaseOptions struct {
|
||||
|
||||
GlobalHTTPProxy string `help:"Global http proxy"`
|
||||
GlobalHTTPSProxy string `help:"Global https proxy"`
|
||||
|
||||
IgnoreNonrunningGuests bool `default:"true" help:"Count memory for running guests only when do scheduling. Ignore memory allocation for non-running guests"`
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -82,12 +82,11 @@ func (manager *SInformerSyncManager) startWatcher() error {
|
||||
log.Infof("[%s] Start resource informer watcher for %s", manager.Name(), manager.resourceManager.GetKeyword())
|
||||
ctx := context.Background()
|
||||
s := auth.GetAdminSession(ctx, consts.GetRegion(), "v1")
|
||||
watchMan, err := informer.NewWatchManagerBySession(s)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "NewWatchManagerBySession")
|
||||
}
|
||||
if err := watchMan.For(manager.resourceManager).AddEventHandler(ctx, manager); err != nil {
|
||||
return errors.Wrapf(err, "watch resource %s", manager.resourceManager.GetKeyword())
|
||||
}
|
||||
informer.NewWatchManagerBySessionBg(s, func(watchMan *informer.SWatchManager) error {
|
||||
if err := watchMan.For(manager.resourceManager).AddEventHandler(ctx, manager); err != nil {
|
||||
return errors.Wrapf(err, "watch resource %s", manager.resourceManager.GetKeyword())
|
||||
}
|
||||
return nil
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -320,7 +320,7 @@ type SCloudproviderDelegate struct {
|
||||
|
||||
Options struct {
|
||||
cloudprovider.SApsaraEndpoints
|
||||
cloudprovider.SHuaweiCloudStackEndpoints
|
||||
cloudprovider.SHCSOEndpoints
|
||||
}
|
||||
|
||||
ProxySetting proxyapi.SProxySetting
|
||||
@@ -337,7 +337,7 @@ func (self *SCloudprovider) GetDelegate() (*SCloudproviderDelegate, error) {
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "result.Unmarshal")
|
||||
}
|
||||
if provider.Provider == api.CLOUD_PROVIDER_APSARA || provider.Provider == api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK {
|
||||
if provider.Provider == api.CLOUD_PROVIDER_APSARA || provider.Provider == api.CLOUD_PROVIDER_HCSO {
|
||||
result, err := modules.Cloudaccounts.Get(s, provider.CloudaccountId, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "modules.Cloudaccounts.Get")
|
||||
@@ -408,8 +408,7 @@ func (self *SCloudprovider) GetProvider() (cloudprovider.ICloudProvider, error)
|
||||
|
||||
ProxyFunc: proxyFunc,
|
||||
|
||||
SHuaweiCloudStackEndpoints: delegate.Options.SHuaweiCloudStackEndpoints,
|
||||
SApsaraEndpoints: delegate.Options.SApsaraEndpoints,
|
||||
Options: jsonutils.Marshal(delegate.Options).(*jsonutils.JSONDict),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ func (manager *SCloudaccountManager) newFromICloudaccount(ctx context.Context, u
|
||||
}
|
||||
|
||||
func (self *SCloudaccount) registerHuaweSaml(ctx context.Context) error {
|
||||
if self.Provider != computeapi.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK {
|
||||
if self.Provider != computeapi.CLOUD_PROVIDER_HCSO {
|
||||
return nil
|
||||
}
|
||||
delegate, err := self.getCloudDelegate(ctx)
|
||||
@@ -482,7 +482,7 @@ type SCloudDelegate struct {
|
||||
Brand string
|
||||
|
||||
Options struct {
|
||||
cloudprovider.SHuaweiCloudStackEndpoints
|
||||
cloudprovider.SHCSOEndpoints
|
||||
cloudprovider.SApsaraEndpoints
|
||||
}
|
||||
ProxySetting proxyapi.SProxySetting
|
||||
@@ -568,8 +568,7 @@ func (account *SCloudDelegate) GetProvider() (cloudprovider.ICloudProvider, erro
|
||||
Secret: passwd,
|
||||
ProxyFunc: proxyFunc,
|
||||
|
||||
SApsaraEndpoints: account.Options.SApsaraEndpoints,
|
||||
SHuaweiCloudStackEndpoints: account.Options.SHuaweiCloudStackEndpoints,
|
||||
Options: jsonutils.Marshal(account.Options).(*jsonutils.JSONDict),
|
||||
|
||||
AccountId: account.Id,
|
||||
})
|
||||
|
||||
@@ -262,7 +262,7 @@ func (self *SCloudpolicy) GetCloudgroups() ([]SCloudgroup, error) {
|
||||
return groups, nil
|
||||
}
|
||||
|
||||
func (self *SCloudpolicy) ValidateDeleteCondition(ctx context.Context) error {
|
||||
func (self *SCloudpolicy) ValidateDeleteCondition(ctx context.Context, info jsonutils.JSONObject) error {
|
||||
users, err := self.GetCloudusers()
|
||||
if err != nil {
|
||||
return httperrors.NewGeneralError(errors.Wrapf(err, "GetCloudusers"))
|
||||
@@ -277,14 +277,14 @@ func (self *SCloudpolicy) ValidateDeleteCondition(ctx context.Context) error {
|
||||
if len(groups) > 0 {
|
||||
return httperrors.NewNotEmptyError("policy %s has %d groups used", self.Name, len(groups))
|
||||
}
|
||||
return self.SStatusInfrasResourceBase.ValidateDeleteCondition(ctx)
|
||||
return self.SStatusInfrasResourceBase.ValidateDeleteCondition(ctx, nil)
|
||||
}
|
||||
|
||||
func (self *SCloudpolicy) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
lockman.LockObject(ctx, self)
|
||||
defer lockman.ReleaseObject(ctx, self)
|
||||
|
||||
err := self.ValidateDeleteCondition(ctx)
|
||||
err := self.ValidateDeleteCondition(ctx, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ func (d *SHuaweiSAMLDriver) GetSpInitiatedLoginData(ctx context.Context, userCre
|
||||
return data, httperrors.NewGeneralError(err)
|
||||
}
|
||||
account := _account.(*SCloudaccount)
|
||||
if account.Provider != api.CLOUD_PROVIDER_HUAWEI && account.Provider != api.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK {
|
||||
if account.Provider != api.CLOUD_PROVIDER_HUAWEI && account.Provider != api.CLOUD_PROVIDER_HCSO {
|
||||
return data, httperrors.NewClientError("cloudaccount %s is %s not %s", account.Id, account.Provider, api.CLOUD_PROVIDER_HUAWEI)
|
||||
}
|
||||
if account.SAMLAuth.IsFalse() {
|
||||
|
||||
@@ -17,51 +17,94 @@ package apsaramon
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/apsara"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
type SApsaraMetric struct {
|
||||
Timestamp int64
|
||||
UserId string
|
||||
InstanceId string
|
||||
Maximum float64
|
||||
Minimum float64
|
||||
Average float64
|
||||
NodeId string
|
||||
}
|
||||
|
||||
func (self *SApsaraCloudReport) collectRegionMetricOfHost(region cloudprovider.ICloudRegion, servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
aliReg := region.(*apsara.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "common.TimeRangeFromArgs")
|
||||
}
|
||||
for metricName, influxDbSpecs := range aliMetricSpecs {
|
||||
rtnArray, _, err := aliReg.DescribeMetricList(metricName, "acs_ecs_dashboard", since, until, "")
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
|
||||
instances := []api.ServerDetails{}
|
||||
instanceMaps := map[string]api.ServerDetails{}
|
||||
jsonutils.Update(&instances, servers)
|
||||
for i := range instances {
|
||||
if len(instances[i].ExternalId) == 0 {
|
||||
continue
|
||||
}
|
||||
if len(rtnArray) > 0 {
|
||||
for _, rtnMetric := range rtnArray {
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString("external_id")
|
||||
if instanceId, _ := rtnMetric.GetString("instanceId"); instanceId == external_id {
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, rtnMetric, influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
instanceMaps[instances[i].ExternalId] = instances[i]
|
||||
metric, err := common.FillVMCapacity(jsonutils.Marshal(instances[i]).(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "common.FillVMCapacity")
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
}
|
||||
|
||||
err = common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
if err != nil {
|
||||
log.Errorf("send server base metric error: %v", err)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(len(apsaraMetricSpecs))
|
||||
for _metricName, _influxDbSpecs := range apsaraMetricSpecs {
|
||||
go func(metricName string, influxDbSpecs []string) {
|
||||
defer wg.Done()
|
||||
dataList = []influxdb.SMetricData{}
|
||||
metricArray, err := aliReg.FetchMetricData(metricName, "acs_ecs_dashboard", since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
return
|
||||
}
|
||||
|
||||
metrics := []SApsaraMetric{}
|
||||
jsonutils.Update(&metrics, metricArray)
|
||||
|
||||
for _, rtnMetric := range metrics {
|
||||
server, ok := instanceMaps[rtnMetric.InstanceId]
|
||||
if ok {
|
||||
serverMetric, err := self.collectMetricFromThisServer(jsonutils.Marshal(server), rtnMetric, influxDbSpecs)
|
||||
if err != nil {
|
||||
log.Errorf("collect %s error: %v", metricName, err)
|
||||
continue
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Infof("SendMetrics %s length: %d", metricName, len(dataList))
|
||||
err = common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
if err != nil {
|
||||
log.Errorf("SendMetrics %s length: %d error: %v", metricName, len(dataList), err)
|
||||
}
|
||||
|
||||
}(_metricName, _influxDbSpecs)
|
||||
}
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
wg.Wait()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SApsaraCloudReport) collectRegionMetricOfRedis(region cloudprovider.ICloudRegion,
|
||||
@@ -92,24 +135,25 @@ func (self *SApsaraCloudReport) collectRegionMetricOfRedis(region cloudprovider.
|
||||
}
|
||||
for metricName, influxDbSpecs := range aliRedisMetricSpecs {
|
||||
for _, pre := range redisDeployType {
|
||||
rtnArray, _, err := aliReg.DescribeMetricList(pre+metricName, "acs_kvstore", since, until, "")
|
||||
rtnArray, err := aliReg.FetchMetricData(pre+metricName, "acs_kvstore", since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if len(rtnArray) > 0 {
|
||||
for _, rtnMetric := range rtnArray {
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString("external_id")
|
||||
if instanceId, _ := rtnMetric.GetString("instanceId"); instanceId == external_id {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, rtnMetric, influxDbSpecs)
|
||||
node_id, _ := rtnMetric.GetString("nodeId")
|
||||
serverMetric.Tags = append(serverMetric.Tags, influxdb.SKeyValue{Key: "node_id", Value: node_id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
|
||||
metrics := []SApsaraMetric{}
|
||||
jsonutils.Update(&metrics, rtnArray)
|
||||
|
||||
for _, rtnMetric := range metrics {
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString("external_id")
|
||||
if rtnMetric.InstanceId == external_id {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, rtnMetric, influxDbSpecs)
|
||||
serverMetric.Tags = append(serverMetric.Tags, influxdb.SKeyValue{Key: "node_id", Value: rtnMetric.NodeId})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -126,30 +170,29 @@ func (self *SApsaraCloudReport) collectRegionMetricOfRds(region cloudprovider.IC
|
||||
return err
|
||||
}
|
||||
for metricName, influxDbSpecs := range aliRdsMetricSpecs {
|
||||
rtnArray, _, err := aliReg.DescribeMetricList(metricName, "acs_rds_dashboard", since, until, "")
|
||||
rtnArray, err := aliReg.FetchMetricData(metricName, "acs_rds_dashboard", since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if len(rtnArray) > 0 {
|
||||
for _, rtnMetric := range rtnArray {
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString("external_id")
|
||||
if instanceId, _ := rtnMetric.GetString("instanceId"); instanceId == external_id {
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, rtnMetric, influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
metrics := []SApsaraMetric{}
|
||||
jsonutils.Update(&metrics, rtnArray)
|
||||
|
||||
for _, rtnMetric := range metrics {
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString("external_id")
|
||||
if rtnMetric.InstanceId == external_id {
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dataList = append(dataList, metric)
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, rtnMetric, influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,7 +207,7 @@ func (self *SApsaraCloudReport) collectRegionMetricOfOss(region cloudprovider.IC
|
||||
return err
|
||||
}
|
||||
for metricName, influxDbSpecs := range aliOSSMetricSpecs {
|
||||
rtnArray, _, err := aliReg.DescribeMetricList(metricName, "acs_oss", since, until, "")
|
||||
rtnArray, err := aliReg.FetchMetricData(metricName, "acs_oss", since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
@@ -196,22 +239,24 @@ func (self *SApsaraCloudReport) collectRegionMetricOfElb(region cloudprovider.IC
|
||||
return err
|
||||
}
|
||||
for metricName, influxDbSpecs := range aliElbMetricSpecs {
|
||||
rtnArray, _, err := aliReg.DescribeMetricList(metricName, "acs_slb_dashboard", since, until, "")
|
||||
rtnArray, err := aliReg.FetchMetricData(metricName, "acs_slb_dashboard", since, until)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if len(rtnArray) > 0 {
|
||||
for _, rtnMetric := range rtnArray {
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString("external_id")
|
||||
if instanceId, _ := rtnMetric.GetString("instanceId"); instanceId == external_id {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, rtnMetric, influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
|
||||
metrics := []SApsaraMetric{}
|
||||
jsonutils.Update(&metrics, rtnArray)
|
||||
|
||||
for _, rtnMetric := range metrics {
|
||||
for _, server := range servers {
|
||||
external_id, _ := server.GetString("external_id")
|
||||
if rtnMetric.InstanceId == external_id {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, rtnMetric, influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dataList = append(dataList, serverMetric)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,19 +264,13 @@ func (self *SApsaraCloudReport) collectRegionMetricOfElb(region cloudprovider.IC
|
||||
return common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
}
|
||||
|
||||
func (self *SApsaraCloudReport) collectMetricFromThisServer(server jsonutils.JSONObject, rtnMetric jsonutils.JSONObject,
|
||||
influxDbSpecs []string) (influxdb.SMetricData, error) {
|
||||
func (self *SApsaraCloudReport) collectMetricFromThisServer(server jsonutils.JSONObject, rtnMetric SApsaraMetric, influxDbSpecs []string) (influxdb.SMetricData, error) {
|
||||
metric, err := self.NewMetricFromJson(server)
|
||||
//metric, err := common.JsonToMetric(server.(*jsonutils.JSONDict), "", common.ServerTags, make([]string, 0))
|
||||
if err != nil {
|
||||
return influxdb.SMetricData{}, err
|
||||
}
|
||||
timestamp, _ := rtnMetric.Get("timestamp")
|
||||
metric.Timestamp = time.Unix(timestamp.(*jsonutils.JSONInt).Value()/1000, 0)
|
||||
fieldValue, err := rtnMetric.Float(UNIT_AVERAGE)
|
||||
if err != nil {
|
||||
return influxdb.SMetricData{}, err
|
||||
}
|
||||
metric.Timestamp = time.Unix(rtnMetric.Timestamp/1000, 0)
|
||||
fieldValue := rtnMetric.Average
|
||||
//根据条件拼装metric的tag和metirc信息
|
||||
influxDbSpec := influxDbSpecs[2]
|
||||
measurement := common.SubstringBefore(influxDbSpec, ".")
|
||||
|
||||
@@ -131,6 +131,18 @@ var aliMetricSpecs = map[string][]string{
|
||||
"DiskReadIOPS": {DEFAULT_STATISTICS, UNIT_CPS, INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
"DiskWriteIOPS": {DEFAULT_STATISTICS, UNIT_CPS, INFLUXDB_FIELD_DISK_WRITE_IOPS},
|
||||
}
|
||||
var apsaraMetricSpecs = map[string][]string{
|
||||
"vm.MemoryUtilization": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_MEM_USAGE},
|
||||
"vm.CPUUtilization": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_CPU_USAGE},
|
||||
"InternetInRate": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_NET_BPS_RX_INTERNET},
|
||||
"IntranetInRate": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_NET_BPS_RX_INTRANET},
|
||||
"InternetOutRate": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_NET_BPS_TX_INTERNET},
|
||||
"IntranetOutRate": {DEFAULT_STATISTICS, UNIT_BPS, INFLUXDB_FIELD_NET_BPS_TX_INTRANET},
|
||||
"DiskReadBPS": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
"DiskWriteBPS": {DEFAULT_STATISTICS, UNIT_BYTEPS, INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
"DiskReadIOPS": {DEFAULT_STATISTICS, UNIT_CPS, INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
"DiskWriteIOPS": {DEFAULT_STATISTICS, UNIT_CPS, INFLUXDB_FIELD_DISK_WRITE_IOPS},
|
||||
}
|
||||
var aliRdsMetricSpecs = map[string][]string{
|
||||
"CpuUsage": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_CPU_USAGE},
|
||||
"MemoryUsage": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_RDS_MEM_USAGE},
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
@@ -41,37 +42,49 @@ func (self *SAzureCloudReport) collectRegionMetricOfHost(region cloudprovider.IC
|
||||
return err
|
||||
}
|
||||
for _, server := range servers {
|
||||
srvId, _ := server.GetString("id")
|
||||
srvName, _ := server.GetString("name")
|
||||
srvPrefix := srvId + "/" + "srvName"
|
||||
external_id, err := server.GetString("external_id")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
classicKey := "microsoft.classiccompute/virtualmachines"
|
||||
ns := "Microsoft.Compute/virtualMachines"
|
||||
metricSpecs := azureMetricSpecs
|
||||
if strings.Contains(strings.ToLower(external_id), classicKey) {
|
||||
ns = classicKey
|
||||
metricSpecs = azureClassicMetricsSpec
|
||||
}
|
||||
metricNameArr := make([]string, 0)
|
||||
for metricName, _ := range azureMetricSpecs {
|
||||
for metricName := range metricSpecs {
|
||||
metricNameArr = append(metricNameArr, metricName)
|
||||
}
|
||||
metricNames := strings.Join(metricNameArr, ",")
|
||||
rtnMetrics, err := azureReg.GetMonitorData(metricNames, "Microsoft.Compute/virtualMachines", external_id, since, until)
|
||||
azureReg.GetClient().Debug(true)
|
||||
rtnMetrics, err := azureReg.GetMonitorData(metricNames, ns, external_id, since, until, self.Args.MetricInterval)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
log.Errorf("get metrics for server %s error: %v", srvPrefix, err)
|
||||
continue
|
||||
}
|
||||
if rtnMetrics == nil || rtnMetrics.Value == nil {
|
||||
log.Warningf("server %s metrics is nil", srvPrefix)
|
||||
continue
|
||||
}
|
||||
for metricName, influxDbSpecs := range azureMetricSpecs {
|
||||
for metricName, influxDbSpecs := range metricSpecs {
|
||||
for _, value := range *rtnMetrics.Value {
|
||||
if value.Name.LocalizedValue != nil {
|
||||
if metricName == *(value.Name.LocalizedValue) {
|
||||
if metricName == *(value.Name.LocalizedValue) || (value.Name.Value != nil && *value.Name.Value == metricName) {
|
||||
metric, err := common.FillVMCapacity(server.(*jsonutils.JSONDict))
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "fill vm %q capacity", srvPrefix)
|
||||
}
|
||||
dataList = append(dataList, metric)
|
||||
if value.Timeseries != nil {
|
||||
for _, timeserie := range *value.Timeseries {
|
||||
serverMetric, err := self.collectMetricFromThisServer(server, timeserie, influxDbSpecs)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrapf(err, "collect metrics from server %q", srvPrefix)
|
||||
}
|
||||
dataList = append(dataList, serverMetric...)
|
||||
}
|
||||
@@ -82,7 +95,7 @@ func (self *SAzureCloudReport) collectRegionMetricOfHost(region cloudprovider.IC
|
||||
}
|
||||
err = common.SendMetrics(self.Session, dataList, self.Args.Debug, "")
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
log.Errorf("send %q metrics error: %v", srvName, err)
|
||||
}
|
||||
dataList = dataList[:0]
|
||||
}
|
||||
|
||||
@@ -119,13 +119,38 @@ const (
|
||||
KEY_USABLE = "usable"
|
||||
)
|
||||
|
||||
//multiCloud查询指标列表组装
|
||||
// multiCloud查询指标列表组装
|
||||
const (
|
||||
MetricKeyPercentageCPU = "Percentage CPU"
|
||||
MetricKeyNetworkInTotal = "Network In Total"
|
||||
MetricKeyNetworkOutTotal = "Network Out Total"
|
||||
MetricKeyDiskReadBytes = "Disk Read Bytes"
|
||||
MetricKeyDiskWriteBytes = "Disk Write Bytes"
|
||||
MetricKeyDiskReadOPS = "Disk Read Operations/Sec"
|
||||
MetricKeyDiskWriteOPS = "Disk Write Operations/Sec"
|
||||
|
||||
MetricKeyClassicNetworkIn = "Network In"
|
||||
MetricKeyClassicNetworkOut = "Network Out"
|
||||
MetricKeyClassicDiskReadBPS = "Disk Read Bytes/Sec"
|
||||
MetricKeyClassicDiskWriteBPS = "Disk Write Bytes/Sec"
|
||||
)
|
||||
|
||||
var azureMetricSpecs = map[string][]string{
|
||||
"Percentage CPU": {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_CPU_USAGE},
|
||||
"Network In Total": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_NET_BPS_RX},
|
||||
"Network Out Total": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_NET_BPS_TX},
|
||||
"Disk Read Bytes": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
"Disk Write Bytes": {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
"Disk Read Operations/Sec": {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
"Disk Write Operations/Sec": {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
MetricKeyPercentageCPU: {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_CPU_USAGE},
|
||||
MetricKeyNetworkInTotal: {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_NET_BPS_RX},
|
||||
MetricKeyNetworkOutTotal: {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_NET_BPS_TX},
|
||||
MetricKeyDiskReadBytes: {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
MetricKeyDiskWriteBytes: {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
MetricKeyDiskReadOPS: {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
MetricKeyDiskWriteOPS: {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_DISK_WRITE_IOPS},
|
||||
}
|
||||
|
||||
var azureClassicMetricsSpec = map[string][]string{
|
||||
MetricKeyPercentageCPU: {DEFAULT_STATISTICS, UNIT_PERCENT, INFLUXDB_FIELD_CPU_USAGE},
|
||||
MetricKeyClassicNetworkIn: {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_NET_BPS_RX},
|
||||
MetricKeyClassicNetworkOut: {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_NET_BPS_TX},
|
||||
MetricKeyClassicDiskReadBPS: {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_READ_BPS},
|
||||
MetricKeyClassicDiskWriteBPS: {DEFAULT_STATISTICS, UNIT_MEM, INFLUXDB_FIELD_DISK_WRITE_BPS},
|
||||
MetricKeyDiskReadOPS: {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_DISK_READ_IOPS},
|
||||
MetricKeyDiskWriteOPS: {DEFAULT_STATISTICS, UNIT_COUNT_SEC, INFLUXDB_FIELD_DISK_WRITE_IOPS},
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ import (
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/azure/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/esxi/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/google/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/hcso/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/huawei/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/huaweistack/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/jdcloud/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/qcloud/provider"
|
||||
_ "yunion.io/x/onecloud/pkg/multicloud/zstack/provider"
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/http/httpproxy"
|
||||
|
||||
@@ -123,31 +124,19 @@ func (self *CloudReportBase) InitProviderInstance() (cloudprovider.ICloudProvide
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getCloudAccount error")
|
||||
}
|
||||
endpoints := cloudprovider.SApsaraEndpoints{}
|
||||
hwendpoints := cloudprovider.SHuaweiCloudStackEndpoints{}
|
||||
options, err := cloudAccout.Get("options")
|
||||
if err == nil {
|
||||
err := options.Unmarshal(&endpoints)
|
||||
if err != nil {
|
||||
log.Errorf("Unmarshal SApsaraEndpoints err:%v", err)
|
||||
}
|
||||
err = options.Unmarshal(&hwendpoints)
|
||||
if err != nil {
|
||||
log.Errorf("Unmarshal SHuaweiCloudStackEndpoints err:%v", err)
|
||||
}
|
||||
} else {
|
||||
if err != nil {
|
||||
log.Errorf("get cloudAccout options err:%v", err)
|
||||
}
|
||||
cfg := cloudprovider.ProviderConfig{
|
||||
Id: self.SProvider.Id,
|
||||
Name: self.SProvider.Name,
|
||||
URL: self.SProvider.AccessUrl,
|
||||
Account: self.SProvider.Account,
|
||||
Secret: secretDe,
|
||||
Vendor: self.SProvider.Provider,
|
||||
ProxyFunc: proxyFunc,
|
||||
SApsaraEndpoints: endpoints,
|
||||
SHuaweiCloudStackEndpoints: hwendpoints,
|
||||
Id: self.SProvider.Id,
|
||||
Name: self.SProvider.Name,
|
||||
URL: self.SProvider.AccessUrl,
|
||||
Account: self.SProvider.Account,
|
||||
Secret: secretDe,
|
||||
Vendor: self.SProvider.Provider,
|
||||
ProxyFunc: proxyFunc,
|
||||
Options: options.(*jsonutils.JSONDict),
|
||||
}
|
||||
return cloudprovider.GetProvider(cfg)
|
||||
}
|
||||
@@ -232,12 +221,25 @@ func (self *CloudReportBase) CollectRegionMetric(region cloudprovider.ICloudRegi
|
||||
|
||||
func (self *CloudReportBase) ListAllResources(manager modulebase.Manager,
|
||||
query *jsonutils.JSONDict) ([]jsonutils.JSONObject, error) {
|
||||
|
||||
return ListAllResources(manager, self.Session, query)
|
||||
}
|
||||
|
||||
func ListAllResources(manager modulebase.Manager, session *mcclient.ClientSession,
|
||||
query *jsonutils.JSONDict) ([]jsonutils.JSONObject, error) {
|
||||
offsetIndex := 0
|
||||
resources := make([]jsonutils.JSONObject, 0)
|
||||
tryTimes := 5
|
||||
i := 0
|
||||
for {
|
||||
i++
|
||||
query.Add(jsonutils.NewInt(int64(offsetIndex)), "offset")
|
||||
resList, err := manager.List(self.Session, query)
|
||||
resList, err := manager.List(session, query)
|
||||
if err != nil {
|
||||
if i <= tryTimes {
|
||||
time.Sleep(3 * time.Second)
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
resources = append(resources, resList.Data...)
|
||||
|
||||
@@ -75,13 +75,14 @@ var OtherHostTag = map[string]string{
|
||||
}
|
||||
|
||||
type ReportOptions struct {
|
||||
Batch int `help:"batch"`
|
||||
Count int `help:"count" json:"count"`
|
||||
Interval string `help:"interval""`
|
||||
Timeout int64 `help:"command timeout unit:second" default:"10"`
|
||||
SinceTime string `help:"sinceTime"`
|
||||
EndTime string `help:"endTime"`
|
||||
Provider []string `help:"List objects from the provider" choices:"VMware|Aliyun|Qcloud|Azure|Aws|Huawei|ZStack|Google|Apsara|JDcloud|Ecloud|HuaweiCloudStack" json:"provider,omitempty"`
|
||||
Batch int `help:"batch"`
|
||||
Count int `help:"count" json:"count"`
|
||||
Interval string `help:"interval"`
|
||||
Timeout int64 `help:"command timeout unit:second" default:"10"`
|
||||
SinceTime string `help:"sinceTime"`
|
||||
EndTime string `help:"endTime"`
|
||||
Provider []string `help:"List objects from the provider" choices:"VMware|Aliyun|Qcloud|Azure|Aws|Huawei|ZStack|Google|Apsara|JDcloud|Ecloud|HCSO" json:"provider,omitempty"`
|
||||
MetricInterval string `help:"metric interval eg:PT1M"`
|
||||
PingProbeOptions
|
||||
}
|
||||
|
||||
@@ -326,7 +327,7 @@ func TimeRangeFromArgs(args *ReportOptions) (since, until time.Time, err error)
|
||||
return since, until, err
|
||||
}
|
||||
} else {
|
||||
period64, err := strconv.ParseInt(args.Interval, 10, 8)
|
||||
period64, err := strconv.ParseInt(args.Interval, 10, 32)
|
||||
if err != nil {
|
||||
return since, until, err
|
||||
}
|
||||
@@ -415,7 +416,7 @@ func SendMetrics(s *mcclient.ClientSession, metrics []influxdb.SMetricData, debu
|
||||
|
||||
func ReportCloudMetricOfoperatorType(operatorType string, session *mcclient.ClientSession, args *ReportOptions) error {
|
||||
query := jsonutils.NewDict()
|
||||
query.Add(jsonutils.NewString("0"), KEY_LIMIT)
|
||||
query.Add(jsonutils.NewString("10"), KEY_LIMIT)
|
||||
query.Add(jsonutils.NewString("true"), KEY_ADMIN)
|
||||
//query.Add(jsonutils.NewString("true"), KEY_USABLE)
|
||||
if len(args.Provider) > 0 {
|
||||
@@ -423,7 +424,7 @@ func ReportCloudMetricOfoperatorType(operatorType string, session *mcclient.Clie
|
||||
query.Add(jsonutils.NewString(val), "provider")
|
||||
}
|
||||
}
|
||||
cloudProviderList, err := (&modules.Cloudproviders).List(session, query)
|
||||
cloudProviderList, err := ListAllResources(&modules.Cloudproviders, session, query)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cloudProviders get list error")
|
||||
}
|
||||
@@ -432,8 +433,8 @@ func ReportCloudMetricOfoperatorType(operatorType string, session *mcclient.Clie
|
||||
if args.Count == 0 {
|
||||
args.Count = 1
|
||||
}
|
||||
for i := 0; i < len(cloudProviderList.Data); i++ {
|
||||
provider := cloudProviderList.Data[i]
|
||||
for i := 0; i < len(cloudProviderList); i++ {
|
||||
provider := cloudProviderList[i]
|
||||
status, err := provider.GetString("status")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "provider get status error")
|
||||
|
||||
@@ -108,5 +108,5 @@ type SHwStackCloudReportFactory struct {
|
||||
}
|
||||
|
||||
func (self *SHwStackCloudReportFactory) GetId() string {
|
||||
return compute.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK
|
||||
return compute.CLOUD_PROVIDER_HCSO
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/collectors/common"
|
||||
"yunion.io/x/onecloud/pkg/cloudprovider"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/hcso"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/huawei"
|
||||
hw_moudules "yunion.io/x/onecloud/pkg/multicloud/huawei/client/modules"
|
||||
"yunion.io/x/onecloud/pkg/multicloud/huaweistack"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
)
|
||||
|
||||
@@ -134,7 +134,6 @@ func (self *SHwCloudReport) collectRegionMetricOfRds(region cloudprovider.ICloud
|
||||
servers []jsonutils.JSONObject) error {
|
||||
dataList := make([]influxdb.SMetricData, 0)
|
||||
|
||||
hwReg := region.(*huawei.SRegion)
|
||||
since, until, err := common.TimeRangeFromArgs(self.Args)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -173,9 +172,10 @@ func (self *SHwCloudReport) collectRegionMetricOfRds(region cloudprovider.ICloud
|
||||
if tmp > len(metas) {
|
||||
tmp = len(metas)
|
||||
}
|
||||
metricDatas, err := hwReg.GetMetricsData(metas[index:tmp], since, until)
|
||||
metricDatas, err := self.GetMetricData(region, metas[index:tmp], since, until)
|
||||
if err != nil {
|
||||
return err
|
||||
log.Errorln(err)
|
||||
continue
|
||||
}
|
||||
if len(metricDatas) > 0 {
|
||||
for _, metricData := range metricDatas {
|
||||
@@ -343,8 +343,8 @@ func (self *SHwCloudReport) collectMetricFromThisServer(server jsonutils.JSONObj
|
||||
func (self *SHwCloudReport) GetMetricData(region cloudprovider.ICloudRegion, metrics []hw_moudules.SMetricMeta,
|
||||
since time.Time, until time.Time) ([]hw_moudules.SMetricData, error) {
|
||||
switch self.SProvider.Provider {
|
||||
case compute.CLOUD_PROVIDER_HUAWEI_CLOUD_STACK:
|
||||
hwReg := region.(*huaweistack.SRegion)
|
||||
case compute.CLOUD_PROVIDER_HCSO:
|
||||
hwReg := region.(*hcso.SRegion)
|
||||
return hwReg.GetMetricsData(metrics, since, until)
|
||||
default:
|
||||
hwReg := region.(*huawei.SRegion)
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
package collectors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -79,6 +81,12 @@ func reportUsage(session *mcclient.ClientSession, args *common.ReportOptions) er
|
||||
}
|
||||
//查询host-type==""的情况,对应onecloud-控制面板-全部 要展示的内容
|
||||
dataList, err = packMetricList(session, dataList, imageUsageFieldsDict, "host-type", "", nowTime)
|
||||
//获取域/项目 虚拟机usage
|
||||
data, err := getDomainAndProjectServerUsage(session, nowTime)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getDomainAndProjectServerUsage err")
|
||||
}
|
||||
dataList = append(dataList, data...)
|
||||
//写入influDb
|
||||
return sendMetrics(session, dataList, args.Debug)
|
||||
}
|
||||
@@ -162,3 +170,51 @@ func jsonTometricData(obj *jsonutils.JSONDict, metric *influxdb.SMetricData,
|
||||
metric.Metrics = append(metric.Metrics, metricPairs...)
|
||||
return metric, nil
|
||||
}
|
||||
|
||||
type resourceUsage struct {
|
||||
Count string
|
||||
Id string
|
||||
Name string
|
||||
}
|
||||
|
||||
func getDomainAndProjectServerUsage(session *mcclient.ClientSession, nowTime time.Time) ([]influxdb.SMetricData, error) {
|
||||
metrics := make([]influxdb.SMetricData, 0)
|
||||
param := jsonutils.NewDict()
|
||||
param.Set("scope", jsonutils.NewString("system"))
|
||||
for urlKey, tag := range map[string]string{
|
||||
"domain-statistics": "domain_id.project_domain",
|
||||
"project-statistics": "tenant_id.tenant",
|
||||
} {
|
||||
jsonObject, err := modules.Servers.GetById(session, urlKey, param)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "get server-%s err", urlKey)
|
||||
}
|
||||
usageArr := jsonObject.(*jsonutils.JSONArray)
|
||||
for i := 0; i < usageArr.Size(); i++ {
|
||||
metric := influxdb.SMetricData{Name: measureMent, Timestamp: nowTime}
|
||||
usageObj, _ := usageArr.GetAt(i)
|
||||
usage := new(resourceUsage)
|
||||
usageObj.Unmarshal(usage)
|
||||
key := ""
|
||||
if strings.Contains(urlKey, "domain") {
|
||||
key = "domain"
|
||||
} else {
|
||||
key = "project"
|
||||
}
|
||||
metric.Metrics = append(metric.Metrics, influxdb.SKeyValue{
|
||||
Key: fmt.Sprintf("%s.servers", key),
|
||||
Value: usage.Count,
|
||||
})
|
||||
tagArr := strings.Split(tag, ".")
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: tagArr[0],
|
||||
Value: usage.Id,
|
||||
}, influxdb.SKeyValue{
|
||||
Key: tagArr[1],
|
||||
Value: usage.Name,
|
||||
})
|
||||
metrics = append(metrics, metric)
|
||||
}
|
||||
}
|
||||
return metrics, nil
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user