mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-20 16:13:56 +08:00
Compare commits
197 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e7af6e2e7 | ||
|
|
df8982747a | ||
|
|
08c836ad1c | ||
|
|
5a47ca5da4 | ||
|
|
1e992cc145 | ||
|
|
1c45f1c6a4 | ||
|
|
128bf89ba8 | ||
|
|
7055459cc0 | ||
|
|
f0a65e5b5f | ||
|
|
34c865ce22 | ||
|
|
51911362ab | ||
|
|
28c6abd0e8 | ||
|
|
d3c1bfd21d | ||
|
|
df2deb61c4 | ||
|
|
38be2488be | ||
|
|
c781346225 | ||
|
|
60ba1ffc20 | ||
|
|
87bba5ae4f | ||
|
|
836ac8e00e | ||
|
|
4bdf62cb81 | ||
|
|
1d2b64d62e | ||
|
|
67230151a0 | ||
|
|
08b60b4c6f | ||
|
|
9e81cae902 | ||
|
|
020f3dee57 | ||
|
|
4ab5051c04 | ||
|
|
e39ce07331 | ||
|
|
3259b1b2c4 | ||
|
|
2934f6c15b | ||
|
|
84c7341b7f | ||
|
|
5cff334188 | ||
|
|
987ba6079b | ||
|
|
60df899d5d | ||
|
|
39c033e0c5 | ||
|
|
01908aebdb | ||
|
|
472a2f9ebb | ||
|
|
4919226d0d | ||
|
|
769dd28a51 | ||
|
|
2b7373608d | ||
|
|
6a81f78a4d | ||
|
|
05d5bd6c9f | ||
|
|
48000786cc | ||
|
|
fae1c3d542 | ||
|
|
ba87528561 | ||
|
|
03d393cca4 | ||
|
|
51131f9c75 | ||
|
|
b7b5e5666e | ||
|
|
3c9ca461d9 | ||
|
|
f874a02c05 | ||
|
|
f7b31c08cb | ||
|
|
08c2864b71 | ||
|
|
b25e4dfb31 | ||
|
|
35cdcbe0ff | ||
|
|
8e440f9390 | ||
|
|
40a903a56f | ||
|
|
2d4d76cdd6 | ||
|
|
3e2eeb9e6e | ||
|
|
447f41a40f | ||
|
|
95f59d0a59 | ||
|
|
40ee6d6d44 | ||
|
|
f978973c7e | ||
|
|
8f5634eafc | ||
|
|
eda171ced0 | ||
|
|
c3a81ca793 | ||
|
|
abfa4a5a4d | ||
|
|
e77eb6e8ba | ||
|
|
9d35818660 | ||
|
|
fe28b8d6c6 | ||
|
|
bccc16c4c5 | ||
|
|
8f3a9fe611 | ||
|
|
dce47bbb22 | ||
|
|
15a809e744 | ||
|
|
ba7af63d59 | ||
|
|
c808ca89e6 | ||
|
|
d2b28e04c9 | ||
|
|
b9908acaae | ||
|
|
fec72492b7 | ||
|
|
1a0974ae83 | ||
|
|
51197b837f | ||
|
|
dcfa17492b | ||
|
|
b982ff47f3 | ||
|
|
d9035e9cba | ||
|
|
c4f14c7f42 | ||
|
|
60bcb757fb | ||
|
|
40bffa5d12 | ||
|
|
22e7aa2f79 | ||
|
|
b34f6dbd8c | ||
|
|
fdc918a0ee | ||
|
|
7609ef53df | ||
|
|
ee173b3397 | ||
|
|
4e22ff4805 | ||
|
|
aaa3d498a5 | ||
|
|
a2bcbb83cd | ||
|
|
068662e36e | ||
|
|
9c141930c2 | ||
|
|
d27574e832 | ||
|
|
8641803302 | ||
|
|
6feeff2009 | ||
|
|
60cdc3fdda | ||
|
|
6bed7639b0 | ||
|
|
aa9a5896c8 | ||
|
|
24f4b91955 | ||
|
|
185c780faf | ||
|
|
b3588b48a2 | ||
|
|
98a0d39a0a | ||
|
|
f7fde18f46 | ||
|
|
0cb69b7fb6 | ||
|
|
8637b1fa04 | ||
|
|
9a6362cd6b | ||
|
|
e0b523ba65 | ||
|
|
74037b56ca | ||
|
|
a898351061 | ||
|
|
21f1486001 | ||
|
|
8ec7fd93dc | ||
|
|
f3b2f3d93e | ||
|
|
a75554ed40 | ||
|
|
3452b85d69 | ||
|
|
ef47ad9807 | ||
|
|
063ac404f0 | ||
|
|
1425da2ccd | ||
|
|
c857ca4410 | ||
|
|
8bb60ea439 | ||
|
|
f59f5cb4bf | ||
|
|
c8e986d077 | ||
|
|
2878cc81e8 | ||
|
|
b3b26475cc | ||
|
|
bd2a4e2832 | ||
|
|
cacd42ee15 | ||
|
|
a90e6eac8c | ||
|
|
95413e8a02 | ||
|
|
639e4fb87f | ||
|
|
7ffb1c969f | ||
|
|
a1a96f35fe | ||
|
|
a06b9c7884 | ||
|
|
fd788b15b3 | ||
|
|
2ccc45df92 | ||
|
|
4abbfd9932 | ||
|
|
8fd53d0db5 | ||
|
|
5775c13fbf | ||
|
|
c9998c8b47 | ||
|
|
43000c7d77 | ||
|
|
bce22f04d4 | ||
|
|
7f98ec2a30 | ||
|
|
4e735f8972 | ||
|
|
21650e61f9 | ||
|
|
406cc01b7c | ||
|
|
d8d8256b0a | ||
|
|
75576e17dc | ||
|
|
479b309160 | ||
|
|
d3ecbd98f8 | ||
|
|
a957815041 | ||
|
|
bf2d727933 | ||
|
|
231a3a9fdd | ||
|
|
ada6d9e00c | ||
|
|
6a10d8a66a | ||
|
|
9fd612c5ac | ||
|
|
18cb393ba3 | ||
|
|
4e6bb13c52 | ||
|
|
2989ecfe8a | ||
|
|
a91e8230f3 | ||
|
|
e8592d9158 | ||
|
|
a765271c55 | ||
|
|
6181ce84b3 | ||
|
|
51c4a420ae | ||
|
|
735461541e | ||
|
|
804d987dc0 | ||
|
|
f44f6532dd | ||
|
|
a4968259e7 | ||
|
|
97b6bcd9f0 | ||
|
|
48326f46dc | ||
|
|
1fb12fe81f | ||
|
|
8c6db4e81a | ||
|
|
18edd50fe3 | ||
|
|
50338788c8 | ||
|
|
447616f779 | ||
|
|
3e0344dc0d | ||
|
|
df44eb8082 | ||
|
|
9443fe7b42 | ||
|
|
d196db034f | ||
|
|
90e3bcd5d0 | ||
|
|
7f052c0a79 | ||
|
|
3022a121ef | ||
|
|
a3cda0ca59 | ||
|
|
3d8ef5d442 | ||
|
|
ce64a499bb | ||
|
|
191f0dcb88 | ||
|
|
fb20a846f8 | ||
|
|
7f8549cd4b | ||
|
|
14716b64da | ||
|
|
42fe1cbfe2 | ||
|
|
57df58aa43 | ||
|
|
8149573a80 | ||
|
|
daa0621bcd | ||
|
|
18e8d68c9d | ||
|
|
3712a3a077 | ||
|
|
388b152517 | ||
|
|
e70d7f4357 |
@@ -1,3 +1,3 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/ansibleserver-base:latest
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/ansibleserver-base:1.0.0
|
||||
|
||||
ADD ./_output/bin/ansibleserver /opt/yunion/bin/ansibleserver
|
||||
ADD ./_output/alpine-build/bin/ansibleserver /opt/yunion/bin/ansibleserver
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
FROM frolvlad/alpine-glibc:glibc-2.28
|
||||
FROM alpine:3.11.6
|
||||
|
||||
MAINTAINER "Zexi Li <lizexi@yunionyun.com>"
|
||||
MAINTAINER "Yousong Zhou <zhouyousong@yunionyun.com>"
|
||||
|
||||
ENV TZ Asia/Shanghai
|
||||
|
||||
RUN mkdir -p /opt/yunion/bin
|
||||
|
||||
RUN apk update && \
|
||||
apk add --no-cache tzdata ansible ca-certificates && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
# openssh-client, for ansible ssh connection
|
||||
RUN set -x \
|
||||
&& apk update \
|
||||
&& apk add openssh-client \
|
||||
&& apk add ansible \
|
||||
&& apk add tzdata ca-certificates \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:latest
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.1
|
||||
|
||||
ADD ./_output/bin/apigateway /opt/yunion/bin/apigateway
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:latest
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.1
|
||||
|
||||
ADD ./_output/bin/cloudevent /opt/yunion/bin/cloudevent
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:latest
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.1
|
||||
|
||||
ADD ./_output/bin/cloudnet /opt/yunion/bin/cloudnet
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:latest
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.1
|
||||
|
||||
ADD ./_output/bin/devtool /opt/yunion/bin/devtool
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:latest
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.1
|
||||
|
||||
COPY ./build/esxi-agent/root/opt/ /opt/
|
||||
ADD ./_output/bin/esxi-agent /opt/yunion/bin/esxi-agent
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:latest
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.1
|
||||
|
||||
ADD ./_output/bin/keystone /opt/yunion/bin/keystone
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:latest
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.1
|
||||
|
||||
ADD ./_output/bin/logger /opt/yunion/bin/logger
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:latest
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.1
|
||||
|
||||
ADD ./_output/bin/monitor /opt/yunion/bin/monitor
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:latest
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.1
|
||||
|
||||
COPY ./build/notify/root/opt/ /opt/
|
||||
ADD ./_output/bin/notify /opt/yunion/bin/notify
|
||||
|
||||
@@ -7,7 +7,7 @@ ENV TZ Asia/Shanghai
|
||||
RUN mkdir -p /opt/yunion/bin
|
||||
|
||||
RUN apk update && \
|
||||
apk add --no-cache tzdata ca-certificates && \
|
||||
apk add --no-cache tzdata curl busybox-extras tcpdump strace ca-certificates && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:latest
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.1
|
||||
|
||||
COPY ./build/region/root/opt/ /opt/
|
||||
ADD ./_output/bin/region /opt/yunion/bin/region
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:latest
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.1
|
||||
|
||||
ADD ./_output/bin/s3gateway /opt/yunion/bin/s3gateway
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:latest
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.1
|
||||
|
||||
ADD ./_output/bin/scheduler /opt/yunion/bin/scheduler
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:latest
|
||||
FROM registry.cn-beijing.aliyuncs.com/yunionio/onecloud-base:v0.1
|
||||
|
||||
ADD ./_output/bin/yunionconf /opt/yunion/bin/yunionconf
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<table style="margin-left: 20px;">
|
||||
<tr>
|
||||
<td>
|
||||
<img src="data:{{.logo_format}};base64,{{.logo}}" alt="" style="color: #fff; width: 80px; vertical-align: middle;">
|
||||
<img src="data:{{.login_logo_format}};base64,{{.login_logo}}" alt="" style="color: #fff; height: 32px; vertical-align: middle;">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -56,10 +56,10 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="width: 96%;">
|
||||
<td colspan="2" style="border-top: 1px dashed #ccc; color: #ccc; font-size: 12px; padding-bottom: 10px; font-weight: 100;">*为了确保您的帐号安全,该链接仅48小时内访问有效,请勿直接回复此邮件。</td>
|
||||
<td colspan="2" style="border-top: 1px dashed #ccc; color: #333; font-size: 12px; padding-bottom: 10px; font-weight: 100;">*为了确保您的帐号安全,该链接仅48小时内访问有效,请勿直接回复此邮件。</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" style="background: #333; text-align: right; padding-right: 20px; font-size: 12px; color: #949494; height: 50px;">版权所有 © {{.copyright}} 保留一切权利</td>
|
||||
<td colspan="2" style="background: #333; text-align: right; padding-right: 20px; font-size: 12px; color: #fff; height: 50px;">版权所有 © {{.copyright}} 保留一切权利</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
|
||||
@@ -299,7 +299,9 @@ func init() {
|
||||
IDP string `help:"identity provider name or ID"`
|
||||
}
|
||||
R(&IdentityProviderConfigEditOptions{}, "idp-config-edit", "Edit config yaml of an identity provider", func(s *mcclient.ClientSession, args *IdentityProviderConfigEditOptions) error {
|
||||
conf, err := modules.IdentityProviders.GetSpecific(s, args.IDP, "config", nil)
|
||||
params := jsonutils.NewDict()
|
||||
params.Add(jsonutils.JSONTrue, "sensitive")
|
||||
conf, err := modules.IdentityProviders.GetSpecific(s, args.IDP, "config", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -288,12 +288,30 @@ func init() {
|
||||
if err != nil {
|
||||
log.Fatalf("Set log level %q: %v", "debug", err)
|
||||
}
|
||||
if args.Debug {
|
||||
rbacutils.ShowMatchRuleDebug = true
|
||||
}
|
||||
auth.InitFromClientSession(s)
|
||||
policy.EnableGlobalRbac(15*time.Second, 15*time.Second, false)
|
||||
if args.Debug {
|
||||
consts.EnableRbacDebug()
|
||||
}
|
||||
|
||||
findPolicy := false
|
||||
for !findPolicy {
|
||||
all := policy.PolicyManager.AllPolicies()
|
||||
for _, allP := range all {
|
||||
if len(allP) > 0 {
|
||||
findPolicy = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if findPolicy {
|
||||
break
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
|
||||
req := jsonutils.NewDict()
|
||||
for i := 0; i < len(args.Request); i += 1 {
|
||||
parts := strings.Split(args.Request[i], ":")
|
||||
@@ -359,6 +377,7 @@ func init() {
|
||||
Context: mcclient.SAuthContext{
|
||||
Ip: args.Ip,
|
||||
},
|
||||
Token: "faketoken",
|
||||
}
|
||||
} else {
|
||||
token = s.GetToken()
|
||||
@@ -370,6 +389,10 @@ func init() {
|
||||
}
|
||||
printObject(result)
|
||||
|
||||
for _, r := range args.Role {
|
||||
fmt.Println("role", r, "matched policies:", policy.PolicyManager.RoleMatchPolicies(r))
|
||||
}
|
||||
|
||||
fmt.Println("userCred:", token)
|
||||
for _, scope := range []rbacutils.TRbacScope{
|
||||
rbacutils.ScopeSystem,
|
||||
|
||||
@@ -25,33 +25,20 @@ import (
|
||||
func init() {
|
||||
type SecGroupRulesListOptions struct {
|
||||
options.BaseListOptions
|
||||
Secgroup string `help:"Secgroup ID or Name"`
|
||||
Direction string `help:"filter Direction of rule" choices:"in|out"`
|
||||
Protocol string `help:"filter Protocol of rule" choices:"any|tcp|udp|icmp"`
|
||||
Action string `help:"filter Actin of rule" choices:"allow|deny"`
|
||||
Secgroup string `help:"Secgroup ID or Name"`
|
||||
SecgroupName string `help:"Search rules by fuzzy secgroup name"`
|
||||
Project string `help:"Filter rules by project"`
|
||||
Direction string `help:"filter Direction of rule" choices:"in|out"`
|
||||
Protocol string `help:"filter Protocol of rule" choices:"any|tcp|udp|icmp"`
|
||||
Action string `help:"filter Actin of rule" choices:"allow|deny"`
|
||||
Ports string `help:"filter Ports of rule"`
|
||||
Ip string `help:"filter cidr of rule"`
|
||||
}
|
||||
|
||||
R(&SecGroupRulesListOptions{}, "secgroup-rule-list", "List all security group", func(s *mcclient.ClientSession, args *SecGroupRulesListOptions) error {
|
||||
var params *jsonutils.JSONDict
|
||||
{
|
||||
var err error
|
||||
params, err = args.BaseListOptions.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
}
|
||||
}
|
||||
if len(args.Secgroup) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Secgroup), "secgroup")
|
||||
}
|
||||
if len(args.Direction) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Direction), "direction")
|
||||
}
|
||||
if len(args.Protocol) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Protocol), "protocol")
|
||||
}
|
||||
if len(args.Action) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Action), "action")
|
||||
params, err := options.ListStructToParams(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.SecGroupRules.List(s, params)
|
||||
if err != nil {
|
||||
|
||||
@@ -29,23 +29,15 @@ func init() {
|
||||
Equals string `help:"Secgroup ID or Name, filter secgroups whose rules equals the specified one"`
|
||||
Server string `help:"Filter secgroups bound to specified server"`
|
||||
options.BaseListOptions
|
||||
Ip string `help:"Filter secgroup by ip"`
|
||||
Ports string `help:"Filter secgroup by ports"`
|
||||
Direction string `help:"Filter secgroup by ports" choices:"all|in|out"`
|
||||
}
|
||||
|
||||
R(&SecGroupsListOptions{}, "secgroup-list", "List all security group", func(s *mcclient.ClientSession, args *SecGroupsListOptions) error {
|
||||
var params *jsonutils.JSONDict
|
||||
{
|
||||
var err error
|
||||
params, err = args.BaseListOptions.Params()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
}
|
||||
}
|
||||
if len(args.Equals) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Equals), "equals")
|
||||
}
|
||||
if len(args.Server) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Server), "server")
|
||||
params, err := options.ListStructToParams(args)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := modules.SecGroups.List(s, params)
|
||||
if err != nil {
|
||||
|
||||
8
go.mod
8
go.mod
@@ -127,12 +127,12 @@ require (
|
||||
k8s.io/cluster-bootstrap v0.17.3
|
||||
k8s.io/kubernetes v1.16.0
|
||||
yunion.io/x/executor v0.0.0-20200227030256-a18417815e74
|
||||
yunion.io/x/jsonutils v0.0.0-20200415132054-2bf8a5e94501
|
||||
yunion.io/x/jsonutils v0.0.0-20200710080709-7ca71cdb9383
|
||||
yunion.io/x/log v0.0.0-20200313080802-57a4ce5966b3
|
||||
yunion.io/x/pkg v0.0.0-20200516092703-0a53bc9270aa
|
||||
yunion.io/x/pkg v0.0.0-20200713121502-18154120c49b
|
||||
yunion.io/x/s3cli v0.0.0-20190917004522-13ac36d8687e
|
||||
yunion.io/x/sqlchemy v0.0.0-20200312002602-1177cd8fbc57
|
||||
yunion.io/x/structarg v0.0.0-20200423163001-168d0687be7e
|
||||
yunion.io/x/sqlchemy v0.0.0-20200702064124-195445bc4b11
|
||||
yunion.io/x/structarg v0.0.0-20200708124353-ea9a441ecaf8
|
||||
)
|
||||
|
||||
replace (
|
||||
|
||||
19
go.sum
19
go.sum
@@ -1106,8 +1106,8 @@ vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj
|
||||
yunion.io/x/executor v0.0.0-20200227030256-a18417815e74 h1:A15C6VdVRWvmQ9pAJHrUs9yan5qKlYH7uaRxHg1kRbk=
|
||||
yunion.io/x/executor v0.0.0-20200227030256-a18417815e74/go.mod h1:Uxuou9WQIeJXNpy7t2fPLL0BYLvLiMvGQwY7Qc6aSws=
|
||||
yunion.io/x/jsonutils v0.0.0-20190625054549-a964e1e8a051/go.mod h1:4N0/RVzsYL3kH3WE/H1BjUQdFiWu50JGCFQuuy+Z634=
|
||||
yunion.io/x/jsonutils v0.0.0-20200415132054-2bf8a5e94501 h1:i1r9XvbdxH3FgTCLmTaRi3MzQqhiQimXJRlUOPgrxnU=
|
||||
yunion.io/x/jsonutils v0.0.0-20200415132054-2bf8a5e94501/go.mod h1:T7kxQJR13+t7z0TuT+Wzd7MTxBOk2H9c0pO1ONQSv90=
|
||||
yunion.io/x/jsonutils v0.0.0-20200710080709-7ca71cdb9383 h1:XEhTD+FGjBjEIWwcY0Ez1lY3oTTzjUOcRgH/i4eFM5A=
|
||||
yunion.io/x/jsonutils v0.0.0-20200710080709-7ca71cdb9383/go.mod h1:3U5hspYn9apQHaXKY+fJ4Qgwjey32Kc+Mq+mUe9NamQ=
|
||||
yunion.io/x/log v0.0.0-20190514041436-04ce53b17c6b/go.mod h1:+gauLs73omeJAPlsXcevLsJLKixV+sR/E7WSYTSx1fE=
|
||||
yunion.io/x/log v0.0.0-20190629062853-9f6483a7103d h1:59zrDL7Ft+hDukguJRmLr/Gdu/9V75x+yX99ovZwfaA=
|
||||
yunion.io/x/log v0.0.0-20190629062853-9f6483a7103d/go.mod h1:LC6f/4FozL0iaAbnFt2eDX9jlsyo3WiOUPm03d7+U4U=
|
||||
@@ -1115,12 +1115,13 @@ yunion.io/x/log v0.0.0-20200313080802-57a4ce5966b3 h1:5Wc5hkB8PtMudmHuzCyok960Ru
|
||||
yunion.io/x/log v0.0.0-20200313080802-57a4ce5966b3/go.mod h1:LC6f/4FozL0iaAbnFt2eDX9jlsyo3WiOUPm03d7+U4U=
|
||||
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-20200302034534-fdf44d54b070/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v0.0.0-20200516092703-0a53bc9270aa h1:VizPfW8+mLFEE7W/97zxQJbfdxchi2dn1M/Y7YBwTTc=
|
||||
yunion.io/x/pkg v0.0.0-20200516092703-0a53bc9270aa/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v0.0.0-20200708071451-a663dc94e16b h1:wwPzH8iMRYjtaSM2pBN7nOqeZxR4XW5wdz2VE1KH/Ug=
|
||||
yunion.io/x/pkg v0.0.0-20200708071451-a663dc94e16b/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/pkg v0.0.0-20200713121502-18154120c49b h1:Ov/eKwwNeQje7SggkopExzcCW/GfaUouvXkcY6RUEcM=
|
||||
yunion.io/x/pkg v0.0.0-20200713121502-18154120c49b/go.mod h1:t6rEGG2sQ4J7DhFxSZVOTjNd0YO/KlfWQyK1W4tog+E=
|
||||
yunion.io/x/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-20200312002602-1177cd8fbc57 h1:KtQAuLJ00RSUVqkiRmJ1DiDABiw0U3xxXnzD3lGavaY=
|
||||
yunion.io/x/sqlchemy v0.0.0-20200312002602-1177cd8fbc57/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI=
|
||||
yunion.io/x/structarg v0.0.0-20200423163001-168d0687be7e h1:pctCe/EPel3F1B83pJ2q9b34Umd1NdbLW1Yd+Lzur2s=
|
||||
yunion.io/x/structarg v0.0.0-20200423163001-168d0687be7e/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng=
|
||||
yunion.io/x/sqlchemy v0.0.0-20200702064124-195445bc4b11 h1:srrssomGJLh4OaDaY/1so+2FUBjZxdwQx/1pZ6403YU=
|
||||
yunion.io/x/sqlchemy v0.0.0-20200702064124-195445bc4b11/go.mod h1:FTdwPdGhMgh4E+UFXc9klI1Ok34fMuybTT+jLhOaIjI=
|
||||
yunion.io/x/structarg v0.0.0-20200708124353-ea9a441ecaf8 h1:35Q2ce/gI2cuVhsuLS7WsL2K9SxwMEtWTopt/99iYsk=
|
||||
yunion.io/x/structarg v0.0.0-20200708124353-ea9a441ecaf8/go.mod h1:EP6NSv2C0zzqBDTKumv8hPWLb3XvgMZDHQRfyuOrQng=
|
||||
|
||||
@@ -39,6 +39,7 @@ func InitHandlers(app *appsrv.Application) {
|
||||
db.InitAllManagers()
|
||||
|
||||
db.RegisterModelManager(db.OpsLog)
|
||||
db.RegisterModelManager(db.Metadata)
|
||||
db.RegisterModelManager(db.UserCacheManager)
|
||||
db.RegisterModelManager(db.TenantCacheManager)
|
||||
for _, manager := range []db.IModelManager{
|
||||
|
||||
@@ -42,6 +42,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
"yunion.io/x/onecloud/pkg/util/netutils2"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
func AppContextToken(ctx context.Context) mcclient.TokenCredential {
|
||||
@@ -271,7 +272,7 @@ func (h *AuthHandlers) doCredentialLogin(ctx context.Context, req *http.Request,
|
||||
return nil, httperrors.NewInputParameterError("get password in body")
|
||||
}
|
||||
// try base64 decryption
|
||||
if decPasswd, err := base64.StdEncoding.DecodeString(passwd); err == nil {
|
||||
if decPasswd, err := base64.StdEncoding.DecodeString(passwd); err == nil && stringutils2.IsPrintableAsciiString(string(decPasswd)) {
|
||||
passwd = string(decPasswd)
|
||||
}
|
||||
if len(uname) == 0 || len(passwd) == 0 {
|
||||
@@ -395,7 +396,7 @@ func isUserAllowWebconsole(ctx context.Context, w http.ResponseWriter, req *http
|
||||
return false
|
||||
}
|
||||
if !jsonutils.QueryBoolean(usr, "allow_web_console", true) {
|
||||
httperrors.ForbiddenError(w, "forbidden user %q login from web", usr.String())
|
||||
httperrors.ForbiddenError(w, "user forbidden login from web")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
@@ -297,18 +297,6 @@ func (mh *MiscHandler) DoBatchUserRegister(ctx context.Context, w http.ResponseW
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := names[name]; ok {
|
||||
e := httperrors.NewClientError("row %d duplicate name %s", rowIdx, name)
|
||||
httperrors.JsonClientError(w, e)
|
||||
return
|
||||
} else {
|
||||
names[name] = true
|
||||
_, err := modules.UsersV3.Get(s, name, nil)
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
domainId, ok := domains[domain]
|
||||
if !ok {
|
||||
if len(domain) == 0 {
|
||||
@@ -327,6 +315,18 @@ func (mh *MiscHandler) DoBatchUserRegister(ctx context.Context, w http.ResponseW
|
||||
domains[domain] = id
|
||||
}
|
||||
|
||||
if _, ok := names[name+"/"+domainId]; ok {
|
||||
e := httperrors.NewClientError("row %d duplicate name %s", rowIdx, name)
|
||||
httperrors.JsonClientError(w, e)
|
||||
return
|
||||
} else {
|
||||
names[name+"/"+domainId] = true
|
||||
_, err := modules.UsersV3.Get(s, name, nil)
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
user := jsonutils.NewDict()
|
||||
user.Add(jsonutils.NewString(name), "name")
|
||||
user.Add(jsonutils.NewString(domainId), "domain_id")
|
||||
|
||||
@@ -26,7 +26,7 @@ type GatewayOptions struct {
|
||||
|
||||
DisableModuleApiVersion bool `help:"Disable each modules default api version" default:"false"`
|
||||
|
||||
EnableTotp bool `help:"Enable two-factor authentication" default:"false"`
|
||||
EnableTotp bool `help:"Enable two-factor authentication" default:"false"`
|
||||
|
||||
SqlitePath string `help:"sqlite db path" default:"/etc/yunion/data/yunionapi.db"`
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ const (
|
||||
CITY_FU_ZHOU = "Fuzhou" //福州
|
||||
CITY_WU_HAN = "Wuhan" //武汉
|
||||
CITY_CHANG_SHA = "Changsha" //长沙
|
||||
CITY_SHU_ZHOU = "Shuzhou" //苏州
|
||||
CITY_SU_ZHOU = "Suzhou" //苏州
|
||||
CITY_BAO_DING = "Baoding" //保定
|
||||
CITY_NAN_JING = "Nanjing" //南京
|
||||
CITY_FO_SHAN = "Foshan" //佛山
|
||||
|
||||
@@ -103,6 +103,10 @@ const (
|
||||
HUAWEI_DBINSTANCE_CATEGORY_SINGLE = "single" //单机
|
||||
HUAWEI_DBINSTANCE_CATEGORY_REPLICA = "replica" //只读
|
||||
|
||||
//谷歌云实例类型
|
||||
GOOGLE_DBINSTANCE_CATEGORY_REGIONAL = "Regional" // 高可用性(区域级)
|
||||
GOOGLE_DBINSTANCE_CATEGORY_ZONAL = "Zonal" // 单个地区
|
||||
|
||||
//阿里云存储类型
|
||||
ALIYUN_DBINSTANCE_STORAGE_TYPE_LOCAL_SSD = "local_ssd" //本地盘SSD盘
|
||||
ALIYUN_DBINSTANCE_STORAGE_TYPE_CLOUD_ESSD = "cloud_essd" //ESSD云盘
|
||||
|
||||
@@ -16,9 +16,16 @@ package compute
|
||||
|
||||
import "yunion.io/x/onecloud/pkg/apis"
|
||||
|
||||
const (
|
||||
EXTERNAL_PROJECT_STATUS_AVAILABLE = "available" // 可用
|
||||
EXTERNAL_PROJECT_STATUS_UNAVAILABLE = "unavailable" // 不可用
|
||||
EXTERNAL_PROJECT_STATUS_CREATING = "creating" // 创建中
|
||||
EXTERNAL_PROJECT_STATUS_DELETING = "deleting" // 删除中
|
||||
EXTERNAL_PROJECT_STATUS_UNKNOWN = "unknown" // 未知
|
||||
)
|
||||
|
||||
type ExternalProjectDetails struct {
|
||||
apis.StandaloneResourceDetails
|
||||
apis.ProjectizedResourceInfo
|
||||
apis.VirtualResourceDetails
|
||||
ManagedResourceInfo
|
||||
|
||||
SExternalProject
|
||||
|
||||
@@ -71,8 +71,8 @@ type ServerListInput struct {
|
||||
// 按主机资源类型进行排序
|
||||
// enum: shared,prepaid,dedicated
|
||||
ResourceType string `json:"resource_type"`
|
||||
// 返回开启主备机功能的主机
|
||||
GetBackupGuestsOnHost *bool `json:"get_backup_guests_on_host"`
|
||||
// 返回该宿主机上的所有虚拟机,包括备份机
|
||||
GetAllGuestsOnHost string `json:"get_all_guests_on_host"`
|
||||
|
||||
// 根据宿主机 SN 过滤
|
||||
// HostSn string `json:"host_sn"`
|
||||
|
||||
@@ -164,7 +164,8 @@ type HostDetails struct {
|
||||
CanPrepare bool `json:"can_prepare"`
|
||||
PrepareFailReason string `json:"prepare_fail_reason"`
|
||||
// 允许开启宿主机健康检查
|
||||
AllowHealthCheck bool `json:"allow_health_check"`
|
||||
AllowHealthCheck bool `json:"allow_health_check"`
|
||||
AutoMigrateOnHostDown bool `json:"auto_migrate_on_host_down"`
|
||||
|
||||
// 标签
|
||||
Metadata map[string]string `json:"metadata"`
|
||||
|
||||
@@ -66,8 +66,7 @@ type CachedimageListInput struct {
|
||||
}
|
||||
|
||||
type ExternalProjectListInput struct {
|
||||
apis.StandaloneResourceListInput
|
||||
apis.ProjectizedResourceListInput
|
||||
apis.VirtualResourceListInput
|
||||
apis.ExternalizedResourceBaseListInput
|
||||
|
||||
ManagedResourceListInput
|
||||
|
||||
@@ -48,6 +48,8 @@ type LoadbalancerListenerListInput struct {
|
||||
|
||||
Scheduler []string `json:"scheduler"`
|
||||
|
||||
Certificate []string `json:"certificate_id"`
|
||||
|
||||
SendProxy []string `json:"send_proxy"`
|
||||
|
||||
AclStatus []string `json:"acl_status"`
|
||||
@@ -168,6 +170,8 @@ type LoadbalancerDetails struct {
|
||||
ManagedResourceInfo
|
||||
CloudregionResourceInfo
|
||||
|
||||
LoadbalancerClusterResourceInfo
|
||||
|
||||
VpcResourceInfoBase
|
||||
ZoneResourceInfoBase
|
||||
NetworkResourceInfoBase
|
||||
|
||||
@@ -145,8 +145,18 @@ type SecgroupListInput struct {
|
||||
// pattern:asc|desc
|
||||
OrderByGuestCnt string `json:"order_by_guest_cnt"`
|
||||
|
||||
// 是否被修改
|
||||
IsDirty *bool `json:"is_dirty"`
|
||||
// 模糊过滤规则中含有指定ip的安全组
|
||||
// example: 10.10.2.1
|
||||
Ip string `json:"ip"`
|
||||
|
||||
// 精确匹配规则中含有指定端口的安全组
|
||||
// example: 100-200
|
||||
Ports string `json:"ports"`
|
||||
|
||||
// 指定过滤规则的方向(仅在指定ip或ports时生效) choices: all|in|out
|
||||
// default: all
|
||||
// example: in
|
||||
Direction string `json:"direction"`
|
||||
}
|
||||
|
||||
type SecurityGroupCacheListInput struct {
|
||||
@@ -170,6 +180,10 @@ type SecurityGroupRuleListInput struct {
|
||||
Action string `json:"action"`
|
||||
// 以protocol字段过滤安全组规则
|
||||
Protocol string `json:"protocol"`
|
||||
// 以ports字段过滤安全组规则
|
||||
Ports string `json:"ports"`
|
||||
// 根据ip模糊匹配安全组规则
|
||||
Ip string `json:"ip"`
|
||||
}
|
||||
|
||||
type SecgroupResourceInput struct {
|
||||
@@ -179,6 +193,11 @@ type SecgroupResourceInput struct {
|
||||
// Deprecated
|
||||
// filter by secgroup_id
|
||||
SecgroupId string `json:"secgroup_id" "yunion:deprecated-by":"secgroup"`
|
||||
|
||||
// 模糊匹配安全组规则名称
|
||||
SecgroupName string `json:"secgroup_name"`
|
||||
|
||||
apis.ProjectizedResourceInput
|
||||
}
|
||||
|
||||
type SecgroupFilterListInput struct {
|
||||
@@ -193,15 +212,22 @@ type SecgroupDetails struct {
|
||||
SSecurityGroup
|
||||
|
||||
// 关联云主机数量
|
||||
GuestCnt int `json:"guest_cnt"`
|
||||
GuestCnt int `json:"guest_cnt,allowempty"`
|
||||
|
||||
// 关联此安全组的云主机is_system为true数量
|
||||
SystemGuestCnt int `json:"system_guest_cnt,allowempty"`
|
||||
|
||||
// admin_secgrp_id为此安全组的云主机数量
|
||||
AdminGuestCnt int `json:"admin_guest_cnt,allowempty"`
|
||||
|
||||
// 安全组缓存数量
|
||||
CacheCnt int `json:"cache_cnt"`
|
||||
CacheCnt int `json:"cache_cnt,allowempty"`
|
||||
// 规则信息
|
||||
Rules string `json:"rules"`
|
||||
Rules []SSecurityGroupRule `json:"rules"`
|
||||
// 入方向规则信息
|
||||
InRules string `json:"in_rules"`
|
||||
InRules []SSecurityGroupRule `json:"in_rules"`
|
||||
// 出方向规则信息
|
||||
OutRules string `json:"out_rules"`
|
||||
OutRules []SSecurityGroupRule `json:"out_rules"`
|
||||
}
|
||||
|
||||
type SecurityGroupResourceInfo struct {
|
||||
|
||||
@@ -28,6 +28,8 @@ type SLDAPIdpConfigBaseOptions struct {
|
||||
Suffix string `json:"suffix,omitempty" required:"true"`
|
||||
User string `json:"user,omitempty" required:"true"`
|
||||
Password string `json:"password,omitempty" required:"true"`
|
||||
|
||||
DisableUserOnImport bool `json:"disable_user_on_import"`
|
||||
}
|
||||
|
||||
type SLDAPIdpConfigSingleDomainOptions struct {
|
||||
@@ -51,6 +53,8 @@ type SLDAPIdpConfigOptions struct {
|
||||
User string `json:"user,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
|
||||
DisableUserOnImport bool `json:"disable_user_on_import"`
|
||||
|
||||
DomainTreeDN string `json:"domain_tree_dn,omitempty" help:"Domain tree root node dn(distinguished name)"`
|
||||
DomainFilter string `json:"domain_filter,omitempty"`
|
||||
DomainObjectclass string `json:"domain_objectclass,omitempty"`
|
||||
|
||||
@@ -151,6 +151,9 @@ type ProjectListInput struct {
|
||||
|
||||
UserFilterListInput
|
||||
GroupFilterListInput
|
||||
|
||||
// 过滤出指定用户或者组可以加入的项目
|
||||
Jointable *bool `json:"jointable"`
|
||||
}
|
||||
|
||||
type DomainListInput struct {
|
||||
|
||||
@@ -25,10 +25,12 @@ type Ring struct {
|
||||
}
|
||||
|
||||
func NewRing(size int) *Ring {
|
||||
r := Ring{buffer: make([]interface{}, size+1),
|
||||
r := Ring{
|
||||
buffer: make([]interface{}, size+1),
|
||||
header: 0,
|
||||
tail: 0,
|
||||
lock: &sync.Mutex{}}
|
||||
lock: &sync.Mutex{},
|
||||
}
|
||||
return &r
|
||||
}
|
||||
|
||||
@@ -58,6 +60,7 @@ func (r *Ring) Pop() interface{} {
|
||||
return nil
|
||||
}
|
||||
ret := r.buffer[r.tail]
|
||||
r.buffer[r.tail] = nil
|
||||
r.tail = nextPointer(r.tail, len(r.buffer))
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -19,28 +19,33 @@ import (
|
||||
)
|
||||
|
||||
func TestRing(t *testing.T) {
|
||||
r := NewRing(10)
|
||||
var v int32 = 10
|
||||
r.Push(v)
|
||||
v = 20
|
||||
r.Push(v)
|
||||
v = 30
|
||||
r.Push(v)
|
||||
v1 := r.Pop().(int32)
|
||||
if v1 != 10 {
|
||||
t.Error("Fail")
|
||||
}
|
||||
v2 := r.Pop().(int32)
|
||||
if v2 != 20 {
|
||||
t.Error("Fail")
|
||||
}
|
||||
v3 := r.Pop().(int32)
|
||||
if v3 != 30 {
|
||||
t.Error("Fail")
|
||||
}
|
||||
v4 := r.Pop()
|
||||
if v4 != nil {
|
||||
t.Error("Fail")
|
||||
var (
|
||||
r = NewRing(10)
|
||||
push = func(v int32) {
|
||||
r.Push(v)
|
||||
}
|
||||
pop = func(want int32) {
|
||||
got := r.Pop().(int32)
|
||||
if got != want {
|
||||
t.Fatalf("got %d, want %d", got, want)
|
||||
}
|
||||
for i := r.header; i != r.tail; i = nextPointer(i, len(r.buffer)) {
|
||||
if r.buffer[i] != nil {
|
||||
t.Fatalf("head %d, tail %d, index %d not nil",
|
||||
r.header, r.tail, i)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
push(10)
|
||||
push(20)
|
||||
push(30)
|
||||
|
||||
pop(10)
|
||||
pop(20)
|
||||
pop(30)
|
||||
if v := r.Pop(); v != nil {
|
||||
t.Fatalf("want nil, got %#v", v)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,8 +87,9 @@ func InitAuth(options *common_options.CommonOptions, authComplete auth.AuthCompl
|
||||
|
||||
func InitBaseAuth(options *common_options.BaseOptions) {
|
||||
if options.EnableRbac {
|
||||
policy.EnableGlobalRbac(time.Duration(options.RbacPolicySyncPeriodSeconds)*time.Second,
|
||||
time.Duration(options.RbacPolicySyncFailedRetrySeconds)*time.Second,
|
||||
policy.EnableGlobalRbac(
|
||||
time.Second*time.Duration(options.RbacPolicySyncPeriodSeconds),
|
||||
time.Second*time.Duration(options.RbacPolicySyncFailedRetrySeconds),
|
||||
options.RbacDebug,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -66,7 +66,14 @@ func SetExternalId(model IExternalizedModel, userCred mcclient.TokenCredential,
|
||||
}
|
||||
|
||||
func FetchByExternalId(manager IModelManager, idStr string) (IExternalizedModel, error) {
|
||||
return FetchByExternalIdAndManagerId(manager, idStr, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q
|
||||
})
|
||||
}
|
||||
|
||||
func FetchByExternalIdAndManagerId(manager IModelManager, idStr string, filter func(q *sqlchemy.SQuery) *sqlchemy.SQuery) (IExternalizedModel, error) {
|
||||
q := manager.Query().Equals("external_id", idStr)
|
||||
q = filter(q)
|
||||
count, err := q.CountWithError()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
51
pkg/cloudcommon/db/lockman/base.go
Normal file
51
pkg/cloudcommon/db/lockman/base.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package lockman
|
||||
|
||||
import "context"
|
||||
|
||||
type SBaseLockManager struct {
|
||||
manager ILockManager
|
||||
}
|
||||
|
||||
func NewBaseLockManger(m ILockManager) *SBaseLockManager {
|
||||
return &SBaseLockManager{manager: m}
|
||||
}
|
||||
|
||||
func (m *SBaseLockManager) LockClass(ctx context.Context, manager ILockedClass, projectId string) {
|
||||
key := getClassKey(manager, projectId)
|
||||
m.manager.LockKey(ctx, key)
|
||||
}
|
||||
|
||||
func (m *SBaseLockManager) ReleaseClass(ctx context.Context, manager ILockedClass, projectId string) {
|
||||
key := getClassKey(manager, projectId)
|
||||
m.manager.UnlockKey(ctx, key)
|
||||
}
|
||||
|
||||
func (m *SBaseLockManager) LockObject(ctx context.Context, model ILockedObject) {
|
||||
key := getObjectKey(model)
|
||||
m.manager.LockKey(ctx, key)
|
||||
}
|
||||
|
||||
func (m *SBaseLockManager) ReleaseObject(ctx context.Context, model ILockedObject) {
|
||||
key := getObjectKey(model)
|
||||
m.manager.UnlockKey(ctx, key)
|
||||
}
|
||||
|
||||
func (m *SBaseLockManager) LockRawObject(ctx context.Context, resName string, resId string) {
|
||||
key := getRawObjectKey(resName, resId)
|
||||
m.manager.LockKey(ctx, key)
|
||||
}
|
||||
|
||||
func (m *SBaseLockManager) ReleaseRawObject(ctx context.Context, resName string, resId string) {
|
||||
key := getRawObjectKey(resName, resId)
|
||||
m.manager.UnlockKey(ctx, key)
|
||||
}
|
||||
|
||||
func (m *SBaseLockManager) LockJointObject(ctx context.Context, model ILockedObject, model2 ILockedObject) {
|
||||
key := getJointObjectKey(model, model2)
|
||||
m.manager.LockKey(ctx, key)
|
||||
}
|
||||
|
||||
func (m *SBaseLockManager) ReleaseJointObject(ctx context.Context, model ILockedObject, model2 ILockedObject) {
|
||||
key := getJointObjectKey(model, model2)
|
||||
m.manager.UnlockKey(ctx, key)
|
||||
}
|
||||
@@ -167,6 +167,7 @@ type SLockTableIndex struct {
|
||||
}
|
||||
|
||||
type SEtcdLockManager struct {
|
||||
*SBaseLockManager
|
||||
tableLock *sync.Mutex
|
||||
lockTable map[SLockTableIndex]*SEtcdLockRecord
|
||||
|
||||
@@ -203,6 +204,7 @@ func NewEtcdLockManager(config *SEtcdLockManagerConfig) (ILockManager, error) {
|
||||
Value: lockman,
|
||||
Func: atexit.ExitHandlerFunc(lockman.destroyAtExit),
|
||||
})
|
||||
lockman.SBaseLockManager = NewBaseLockManger(&lockman)
|
||||
return &lockman, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -135,12 +135,17 @@ func (rec *SInMemoryLockRecord) unlockContext(ctx context.Context) (needClean bo
|
||||
}
|
||||
|
||||
type SInMemoryLockManager struct {
|
||||
*SBaseLockManager
|
||||
tableLock *sync.Mutex
|
||||
lockTable map[string]*SInMemoryLockRecord
|
||||
}
|
||||
|
||||
func NewInMemoryLockManager() ILockManager {
|
||||
lockMan := SInMemoryLockManager{tableLock: &sync.Mutex{}, lockTable: make(map[string]*SInMemoryLockRecord)}
|
||||
lockMan := SInMemoryLockManager{
|
||||
tableLock: &sync.Mutex{},
|
||||
lockTable: make(map[string]*SInMemoryLockRecord),
|
||||
}
|
||||
lockMan.SBaseLockManager = NewBaseLockManger(&lockMan)
|
||||
return &lockMan
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,15 @@ type ILockedObject interface {
|
||||
type ILockManager interface {
|
||||
LockKey(ctx context.Context, key string)
|
||||
UnlockKey(ctx context.Context, key string)
|
||||
|
||||
LockClass(ctx context.Context, manager ILockedClass, projectId string)
|
||||
ReleaseClass(ctx context.Context, manager ILockedClass, projectId string)
|
||||
LockObject(ctx context.Context, model ILockedObject)
|
||||
ReleaseObject(ctx context.Context, model ILockedObject)
|
||||
LockRawObject(ctx context.Context, resName string, resId string)
|
||||
ReleaseRawObject(ctx context.Context, resName string, resId string)
|
||||
LockJointObject(ctx context.Context, model ILockedObject, model2 ILockedObject)
|
||||
ReleaseJointObject(ctx context.Context, model ILockedObject, model2 ILockedObject)
|
||||
}
|
||||
|
||||
func getClassKey(manager ILockedClass, projectId string) string {
|
||||
@@ -64,41 +73,33 @@ func Init(man ILockManager) {
|
||||
}
|
||||
|
||||
func LockClass(ctx context.Context, manager ILockedClass, projectId string) {
|
||||
key := getClassKey(manager, projectId)
|
||||
_lockman.LockKey(ctx, key)
|
||||
_lockman.LockClass(ctx, manager, projectId)
|
||||
}
|
||||
|
||||
func ReleaseClass(ctx context.Context, manager ILockedClass, projectId string) {
|
||||
key := getClassKey(manager, projectId)
|
||||
_lockman.UnlockKey(ctx, key)
|
||||
_lockman.ReleaseClass(ctx, manager, projectId)
|
||||
}
|
||||
|
||||
func LockObject(ctx context.Context, model ILockedObject) {
|
||||
key := getObjectKey(model)
|
||||
_lockman.LockKey(ctx, key)
|
||||
_lockman.LockObject(ctx, model)
|
||||
}
|
||||
|
||||
func ReleaseObject(ctx context.Context, model ILockedObject) {
|
||||
key := getObjectKey(model)
|
||||
_lockman.UnlockKey(ctx, key)
|
||||
_lockman.ReleaseObject(ctx, model)
|
||||
}
|
||||
|
||||
func LockRawObject(ctx context.Context, resName string, resId string) {
|
||||
key := getRawObjectKey(resName, resId)
|
||||
_lockman.LockKey(ctx, key)
|
||||
_lockman.LockRawObject(ctx, resName, resId)
|
||||
}
|
||||
|
||||
func ReleaseRawObject(ctx context.Context, resName string, resId string) {
|
||||
key := getRawObjectKey(resName, resId)
|
||||
_lockman.UnlockKey(ctx, key)
|
||||
_lockman.ReleaseRawObject(ctx, resName, resId)
|
||||
}
|
||||
|
||||
func LockJointObject(ctx context.Context, model ILockedObject, model2 ILockedObject) {
|
||||
key := getJointObjectKey(model, model2)
|
||||
_lockman.LockKey(ctx, key)
|
||||
_lockman.LockJointObject(ctx, model, model2)
|
||||
}
|
||||
|
||||
func ReleaseJointObject(ctx context.Context, model ILockedObject, model2 ILockedObject) {
|
||||
key := getJointObjectKey(model, model2)
|
||||
_lockman.UnlockKey(ctx, key)
|
||||
_lockman.ReleaseJointObject(ctx, model, model2)
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
)
|
||||
|
||||
type SNoopLockManager struct {
|
||||
*SBaseLockManager
|
||||
}
|
||||
|
||||
func (lockman *SNoopLockManager) LockKey(ctx context.Context, key string) {
|
||||
@@ -33,5 +34,6 @@ func (lockman *SNoopLockManager) UnlockKey(ctx context.Context, key string) {
|
||||
|
||||
func NewNoopLockManager() ILockManager {
|
||||
lockMan := SNoopLockManager{}
|
||||
lockMan.SBaseLockManager = NewBaseLockManger(&lockMan)
|
||||
return &lockMan
|
||||
}
|
||||
|
||||
@@ -621,17 +621,11 @@ func (self *SOpsLogManager) FilterByOwner(q *sqlchemy.SQuery, ownerId mcclient.I
|
||||
}
|
||||
case rbacutils.ScopeProject:
|
||||
if len(ownerId.GetProjectId()) > 0 {
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
sqlchemy.Equals(q.Field("owner_tenant_id"), ownerId.GetProjectId()),
|
||||
sqlchemy.Equals(q.Field("tenant_id"), ownerId.GetProjectId()),
|
||||
))
|
||||
q = q.Filter(sqlchemy.Equals(q.Field("tenant_id"), ownerId.GetProjectId()))
|
||||
}
|
||||
case rbacutils.ScopeDomain:
|
||||
if len(ownerId.GetProjectDomainId()) > 0 {
|
||||
q = q.Filter(sqlchemy.OR(
|
||||
sqlchemy.Equals(q.Field("owner_domain_id"), ownerId.GetProjectDomainId()),
|
||||
sqlchemy.Equals(q.Field("domain_id"), ownerId.GetProjectDomainId()),
|
||||
))
|
||||
q = q.Filter(sqlchemy.Equals(q.Field("domain_id"), ownerId.GetProjectDomainId()))
|
||||
}
|
||||
default:
|
||||
// systemScope, no filter
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -481,7 +482,7 @@ func (manager *SQuotaBaseManager) listDomainQuotaHandler(ctx context.Context, w
|
||||
httperrors.GeneralServerError(w, err)
|
||||
return
|
||||
}
|
||||
manager.sendQuotaList(w, quotaList)
|
||||
manager.sendQuotaList(w, sortQuotaByUsage(quotaList))
|
||||
}
|
||||
|
||||
func (manager *SQuotaBaseManager) sendQuotaList(w http.ResponseWriter, quotaList []jsonutils.JSONObject) {
|
||||
@@ -524,7 +525,7 @@ func (manager *SQuotaBaseManager) listProjectQuotaHandler(ctx context.Context, w
|
||||
httperrors.GeneralServerError(w, err)
|
||||
return
|
||||
}
|
||||
manager.sendQuotaList(w, quotaList)
|
||||
manager.sendQuotaList(w, sortQuotaByUsage(quotaList))
|
||||
}
|
||||
|
||||
func (manager *SQuotaBaseManager) listQuotas(ctx context.Context, userCred mcclient.TokenCredential, targetDomainId string, targetProjectId string, domainOnly bool, primaryOnly bool, refresh bool) ([]jsonutils.JSONObject, error) {
|
||||
@@ -616,3 +617,33 @@ func (manager *SQuotaBaseManager) listQuotas(ctx context.Context, userCred mccli
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
type tQuotaResultList []jsonutils.JSONObject
|
||||
|
||||
func (a tQuotaResultList) Len() int { return len(a) }
|
||||
func (a tQuotaResultList) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
||||
func (a tQuotaResultList) Less(i, j int) bool { return usageRateOfQuota(a[i]) > usageRateOfQuota(a[j]) }
|
||||
|
||||
func usageRateOfQuota(quota jsonutils.JSONObject) float32 {
|
||||
maxRate := float32(0)
|
||||
quotaMap, _ := quota.GetMap()
|
||||
for k, v := range quotaMap {
|
||||
usageK := fmt.Sprintf("usage.%s", k)
|
||||
if usageV, ok := quotaMap[usageK]; ok {
|
||||
intV, _ := v.Int()
|
||||
if intV > 0 {
|
||||
intUsageV, _ := usageV.Int()
|
||||
rate := float32(intUsageV) / float32(intV)
|
||||
if maxRate < rate {
|
||||
maxRate = rate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxRate
|
||||
}
|
||||
|
||||
func sortQuotaByUsage(quotaList []jsonutils.JSONObject) []jsonutils.JSONObject {
|
||||
sort.Sort(tQuotaResultList(quotaList))
|
||||
return quotaList
|
||||
}
|
||||
|
||||
@@ -162,8 +162,14 @@ func SharableManagerValidateCreateData(
|
||||
input.IsPublic = &isPublic
|
||||
reqScope = rbacutils.ScopeSystem
|
||||
} else if input.PublicScope == string(rbacutils.ScopeDomain) {
|
||||
input.IsPublic = &isPublic
|
||||
reqScope = rbacutils.ScopeDomain
|
||||
if consts.GetNonDefaultDomainProjects() {
|
||||
// only if non_default_domain_projects turned on, allow sharing to domain
|
||||
input.IsPublic = &isPublic
|
||||
reqScope = rbacutils.ScopeDomain
|
||||
} else {
|
||||
input.IsPublic = &isPublic
|
||||
reqScope = rbacutils.ScopeSystem
|
||||
}
|
||||
} else if input.IsPublic != nil && *input.IsPublic && len(input.PublicScope) == 0 {
|
||||
// backward compatible, if only is_public is true, make it share to system
|
||||
input.IsPublic = &isPublic
|
||||
@@ -171,17 +177,23 @@ func SharableManagerValidateCreateData(
|
||||
reqScope = rbacutils.ScopeSystem
|
||||
} else {
|
||||
input.IsPublic = nil
|
||||
input.PublicScope = string(rbacutils.ScopeNone)
|
||||
input.PublicScope = "" // string(rbacutils.ScopeNone)
|
||||
}
|
||||
case rbacutils.ScopeDomain:
|
||||
if input.PublicScope == string(rbacutils.ScopeSystem) {
|
||||
input.IsPublic = &isPublic
|
||||
reqScope = rbacutils.ScopeSystem
|
||||
} else if input.IsPublic != nil && *input.IsPublic && len(input.PublicScope) == 0 {
|
||||
// backward compatible, if only is_public is true, make it share to system
|
||||
input.IsPublic = &isPublic
|
||||
input.PublicScope = string(rbacutils.ScopeSystem)
|
||||
reqScope = rbacutils.ScopeSystem
|
||||
if consts.GetNonDefaultDomainProjects() {
|
||||
// only if non_default_domain_projects turned on, allow sharing domain resources
|
||||
if input.PublicScope == string(rbacutils.ScopeSystem) {
|
||||
input.IsPublic = &isPublic
|
||||
reqScope = rbacutils.ScopeSystem
|
||||
} else if input.IsPublic != nil && *input.IsPublic && len(input.PublicScope) == 0 {
|
||||
// backward compatible, if only is_public is true, make it share to system
|
||||
input.IsPublic = &isPublic
|
||||
input.PublicScope = string(rbacutils.ScopeSystem)
|
||||
reqScope = rbacutils.ScopeSystem
|
||||
} else {
|
||||
input.IsPublic = nil
|
||||
input.PublicScope = "" // string(rbacutils.ScopeNone)
|
||||
}
|
||||
} else {
|
||||
input.IsPublic = nil
|
||||
input.PublicScope = string(rbacutils.ScopeNone)
|
||||
@@ -423,6 +435,9 @@ func SharablePerformPublic(model ISharableBaseModel, ctx context.Context, userCr
|
||||
targetScope = rbacutils.ScopeNone
|
||||
}
|
||||
case rbacutils.ScopeDomain:
|
||||
if !consts.GetNonDefaultDomainProjects() {
|
||||
return errors.Wrap(httperrors.ErrForbidden, "not allow to share to domain when non_default_domain_projects turned off")
|
||||
}
|
||||
if len(requireIds) == 0 {
|
||||
return errors.Wrap(httperrors.ErrForbidden, "require to be shared to system")
|
||||
}
|
||||
@@ -555,7 +570,8 @@ func SharableModelIsShared(model ISharableBaseModel) bool {
|
||||
func SharableModelCustomizeCreate(model ISharableBaseModel, ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
|
||||
if !data.Contains("public_scope") {
|
||||
resScope := model.GetModelManager().ResourceScope()
|
||||
if resScope == rbacutils.ScopeDomain {
|
||||
if resScope == rbacutils.ScopeDomain && consts.GetNonDefaultDomainProjects() {
|
||||
// only if non_default_domain_projects turned on, do the following
|
||||
isManaged := false
|
||||
if managedModel, ok := model.(IManagedResourceBase); ok {
|
||||
isManaged = managedModel.IsManaged()
|
||||
|
||||
@@ -488,6 +488,10 @@ func (manager *SStandaloneResourceBaseManager) ValidateCreateData(ctx context.Co
|
||||
if err != nil {
|
||||
return input, errors.Wrap(err, "SResourceBaseManager.ValidateCreateData")
|
||||
}
|
||||
input.Name = strings.TrimSpace(input.Name)
|
||||
if strings.ContainsAny(input.Name, "\n\r\t") {
|
||||
return input, errors.Wrap(httperrors.ErrInputParameter, "name should not contains any \\n\\r\\t")
|
||||
}
|
||||
return input, nil
|
||||
}
|
||||
|
||||
@@ -578,6 +582,10 @@ func (model *SStandaloneResourceBase) ValidateUpdateData(ctx context.Context, us
|
||||
}
|
||||
|
||||
if len(input.Name) > 0 {
|
||||
input.Name = strings.TrimSpace(input.Name)
|
||||
if strings.ContainsAny(input.Name, "\n\r\t") {
|
||||
return input, errors.Wrap(httperrors.ErrInputParameter, "name should not contains any \\n\\r\\t")
|
||||
}
|
||||
err = alterNameValidator(model.GetIStandaloneModel(), input.Name)
|
||||
if err != nil {
|
||||
return input, errors.Wrap(err, "alterNameValidator")
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -186,16 +187,38 @@ func (manager *SPolicyManager) start(refreshInterval time.Duration, retryInterva
|
||||
policiesMap[policy.Scope] = policies
|
||||
}
|
||||
manager.defaultPolicies = policiesMap
|
||||
log.Debugf("%#v", manager.defaultPolicies)
|
||||
// log.Debugf("%#v", manager.defaultPolicies)
|
||||
}
|
||||
|
||||
manager.cache = hashcache.NewCache(2048, manager.refreshInterval/2)
|
||||
|
||||
manager.SyncOnce()
|
||||
manager.syncByInterval()
|
||||
}
|
||||
|
||||
func (manager *SPolicyManager) syncByInterval() {
|
||||
syncWorkerManager.Run(manager.syncByInterval_, nil, nil)
|
||||
}
|
||||
|
||||
func (manager *SPolicyManager) syncByInterval_() {
|
||||
err := manager.doSync()
|
||||
var interval time.Duration
|
||||
if err != nil {
|
||||
interval = manager.failedRetryInterval
|
||||
} else {
|
||||
interval = manager.refreshInterval
|
||||
}
|
||||
time.AfterFunc(interval, manager.syncByInterval)
|
||||
}
|
||||
|
||||
var syncOnce int32
|
||||
|
||||
func (manager *SPolicyManager) SyncOnce() {
|
||||
syncWorkerManager.Run(manager.sync, nil, nil)
|
||||
if atomic.CompareAndSwapInt32(&syncOnce, 0, 1) {
|
||||
syncWorkerManager.Run(func() {
|
||||
atomic.StoreInt32(&syncOnce, 0)
|
||||
manager.doSync()
|
||||
}, nil, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SPolicyManager) doSync() error {
|
||||
@@ -223,17 +246,6 @@ func (manager *SPolicyManager) doSync() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SPolicyManager) sync() {
|
||||
err := manager.doSync()
|
||||
var interval time.Duration
|
||||
if err != nil {
|
||||
interval = manager.failedRetryInterval
|
||||
} else {
|
||||
interval = manager.refreshInterval
|
||||
}
|
||||
time.AfterFunc(interval, manager.SyncOnce)
|
||||
}
|
||||
|
||||
func queryKey(scope rbacutils.TRbacScope, userCred mcclient.TokenCredential, service string, resource string, action string, extra ...string) string {
|
||||
queryKeys := []string{string(scope)}
|
||||
queryKeys = append(queryKeys, userCred.GetProjectId(), userCred.GetDomainId(), userCred.GetUserId())
|
||||
@@ -403,8 +415,15 @@ func (manager *SPolicyManager) allowWithoutCache(scope rbacutils.TRbacScope, use
|
||||
|
||||
var result rbacutils.TRbacResult
|
||||
if len(matchRules) > 0 {
|
||||
rule := rbacutils.GetMatchRule(matchRules, service, resource, action, extra...)
|
||||
result = rule.Result
|
||||
result = rbacutils.Deny
|
||||
for _, rule := range matchRules {
|
||||
if rule.Result == rbacutils.Allow {
|
||||
result = rbacutils.Allow
|
||||
break
|
||||
}
|
||||
}
|
||||
// rule := rbacutils.GetMatchRule(matchRules, service, resource, action, extra...)
|
||||
// result = rule.Result
|
||||
} else if findMatchPolicy {
|
||||
// if find matched policy, but no rule matching, allow anyway
|
||||
result = rbacutils.Allow
|
||||
|
||||
@@ -49,6 +49,7 @@ type SImage struct {
|
||||
Status string
|
||||
// UpdatedAt time.Time
|
||||
PublicScope string
|
||||
ExternalId string
|
||||
}
|
||||
|
||||
func CloudImage2Image(image ICloudImage) SImage {
|
||||
|
||||
@@ -20,7 +20,6 @@ import (
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/tristate"
|
||||
"yunion.io/x/pkg/util/secrules"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/billing"
|
||||
@@ -346,10 +345,10 @@ type ICloudSecurityGroup interface {
|
||||
ICloudResource
|
||||
|
||||
GetDescription() string
|
||||
GetRules() ([]secrules.SecurityRule, error)
|
||||
GetRules() ([]SecurityRule, error)
|
||||
GetVpcId() string
|
||||
|
||||
SyncRules(rules []secrules.SecurityRule) error
|
||||
SyncRules(common, inAdds, outAdds, inDels, outDels []SecurityRule) error
|
||||
Delete() error
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,15 @@
|
||||
|
||||
package cloudprovider
|
||||
|
||||
import "yunion.io/x/pkg/util/secrules"
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/util/secrules"
|
||||
)
|
||||
|
||||
const DEFAULT_CLOUD_RULE_ID = "default_cloud_rule_id"
|
||||
|
||||
type SecurityGroupCreateInput struct {
|
||||
Name string
|
||||
@@ -22,3 +30,268 @@ type SecurityGroupCreateInput struct {
|
||||
VpcId string
|
||||
Rules []secrules.SecurityRule
|
||||
}
|
||||
|
||||
type SecurityRule struct {
|
||||
secrules.SecurityRule
|
||||
Name string
|
||||
ExternalId string
|
||||
}
|
||||
|
||||
type TPriorityOrder int
|
||||
|
||||
var (
|
||||
PriorityOrderByDesc = TPriorityOrder(1)
|
||||
PriorityOrderByAsc = TPriorityOrder(-1)
|
||||
)
|
||||
|
||||
func (r SecurityRule) String() string {
|
||||
return r.SecurityRule.String()
|
||||
}
|
||||
|
||||
type SecurityRuleSet []SecurityRule
|
||||
|
||||
func (srs SecurityRuleSet) Len() int {
|
||||
return len(srs)
|
||||
}
|
||||
|
||||
func (srs SecurityRuleSet) Swap(i, j int) {
|
||||
srs[i], srs[j] = srs[j], srs[i]
|
||||
}
|
||||
|
||||
func (srs SecurityRuleSet) Less(i, j int) bool {
|
||||
return srs[i].Priority < srs[j].Priority || (srs[i].Priority == srs[j].Priority && srs[i].String() < srs[j].String())
|
||||
}
|
||||
|
||||
func (srs SecurityRuleSet) AllowList() secrules.SecurityRuleSet {
|
||||
rules := secrules.SecurityRuleSet{}
|
||||
for _, r := range srs {
|
||||
rules = append(rules, r.SecurityRule)
|
||||
}
|
||||
return rules.AllowList()
|
||||
}
|
||||
|
||||
func AddDefaultRule(rules []SecurityRule, defaultRule SecurityRule, localRuleStr string, order TPriorityOrder, min, max int, onlyAllowRules bool) []SecurityRule {
|
||||
if defaultRule.String() == localRuleStr {
|
||||
return rules
|
||||
}
|
||||
defaultRule.ExternalId = DEFAULT_CLOUD_RULE_ID
|
||||
if order == PriorityOrderByDesc {
|
||||
defaultRule.Priority = min
|
||||
} else {
|
||||
defaultRule.Priority = max
|
||||
}
|
||||
defaultRule.Priority -= int(order)
|
||||
if onlyAllowRules {
|
||||
defaultRule.Priority = -1
|
||||
}
|
||||
return append(rules, defaultRule)
|
||||
}
|
||||
|
||||
func SortSecurityRule(rules SecurityRuleSet, order TPriorityOrder, onlyAllowRules bool) {
|
||||
if onlyAllowRules {
|
||||
sort.Sort(rules)
|
||||
return
|
||||
}
|
||||
if order == PriorityOrderByAsc {
|
||||
sort.Sort(sort.Reverse(rules))
|
||||
return
|
||||
}
|
||||
sort.Sort(rules)
|
||||
}
|
||||
|
||||
func CompareRules(
|
||||
minPriority, maxPriority int, order TPriorityOrder,
|
||||
localRules secrules.SecurityRuleSet, remoteRules []SecurityRule,
|
||||
defaultInRule, defaultOutRule SecurityRule,
|
||||
onlyAllowRules bool, debug bool,
|
||||
) (common, inAdds, outAdds, inDels, outDels []SecurityRule) {
|
||||
localInRules := secrules.SecurityRuleSet{}
|
||||
localOutRules := secrules.SecurityRuleSet{}
|
||||
for i := range localRules {
|
||||
if localRules[i].Direction == secrules.DIR_IN {
|
||||
localInRules = append(localInRules, localRules[i])
|
||||
} else {
|
||||
localOutRules = append(localOutRules, localRules[i])
|
||||
}
|
||||
}
|
||||
inRules := SecurityRuleSet{}
|
||||
outRules := SecurityRuleSet{}
|
||||
for i := 0; i < len(remoteRules); i++ {
|
||||
if remoteRules[i].Direction == secrules.DIR_IN {
|
||||
inRules = append(inRules, remoteRules[i])
|
||||
} else {
|
||||
outRules = append(outRules, remoteRules[i])
|
||||
}
|
||||
}
|
||||
var inCommon, outCommon = inRules, outRules
|
||||
|
||||
defaultLocalInRule := *secrules.MustParseSecurityRule("in:deny any")
|
||||
defaultLocalOutRule := *secrules.MustParseSecurityRule("out:allow any")
|
||||
|
||||
inRules = AddDefaultRule(inRules, defaultInRule, defaultLocalInRule.String(), order, minPriority, maxPriority, onlyAllowRules)
|
||||
outRules = AddDefaultRule(outRules, defaultOutRule, defaultLocalOutRule.String(), order, minPriority, maxPriority, onlyAllowRules)
|
||||
|
||||
if defaultLocalInRule.String() != defaultInRule.String() {
|
||||
localInRules = append(localInRules, defaultLocalInRule)
|
||||
}
|
||||
if defaultLocalOutRule.String() != defaultOutRule.String() {
|
||||
localOutRules = append(localOutRules, defaultLocalOutRule)
|
||||
}
|
||||
|
||||
sort.Sort(localInRules)
|
||||
sort.Sort(localOutRules)
|
||||
|
||||
localInAllowList := localInRules.AllowList()
|
||||
localOutAllowList := localOutRules.AllowList()
|
||||
if onlyAllowRules {
|
||||
localInRules = localInAllowList
|
||||
localOutRules = localOutAllowList
|
||||
}
|
||||
|
||||
SortSecurityRule(inRules, order, onlyAllowRules)
|
||||
SortSecurityRule(outRules, order, onlyAllowRules)
|
||||
|
||||
inAllowList := inRules.AllowList()
|
||||
outAllowList := outRules.AllowList()
|
||||
inEquals, outEquals := inAllowList.Equals(localInAllowList), outAllowList.Equals(localOutAllowList)
|
||||
if inEquals && outEquals {
|
||||
return
|
||||
}
|
||||
|
||||
// priority从小到大排列(从默认规则开始对比)
|
||||
sort.Sort(sort.Reverse(localInRules))
|
||||
sort.Sort(sort.Reverse(localOutRules))
|
||||
|
||||
sort.Sort(sort.Reverse(inRules))
|
||||
sort.Sort(sort.Reverse(outRules))
|
||||
|
||||
startPriority := minPriority - 1
|
||||
if order == PriorityOrderByAsc {
|
||||
startPriority = maxPriority + 1
|
||||
}
|
||||
|
||||
var addPriority = func(priority int, order TPriorityOrder, inc int, min, max int, onlyAllowRules bool) int {
|
||||
if onlyAllowRules {
|
||||
return 0
|
||||
}
|
||||
inc = inc * int(order) //+ int(order)
|
||||
priority += inc
|
||||
if priority < min {
|
||||
return min
|
||||
}
|
||||
if priority > max {
|
||||
return max
|
||||
}
|
||||
return priority
|
||||
}
|
||||
|
||||
var getInitPriority = func(init, min, max int) int {
|
||||
if init < min || init > max {
|
||||
return (min + max) / 2
|
||||
}
|
||||
return init
|
||||
}
|
||||
|
||||
var compare = func(localRules secrules.SecurityRuleSet, remoteRules SecurityRuleSet) (common, add, del []SecurityRule) {
|
||||
i, j, inc, prePriority := 0, 0, 1, 0
|
||||
for i < len(localRules) || j < len(remoteRules) {
|
||||
if i < len(localRules) && j < len(remoteRules) {
|
||||
ruleStr := remoteRules[j].String()
|
||||
localRuleStr := localRules[i].String()
|
||||
if debug {
|
||||
log.Debugf("compare local priority(%d) %s -> remote name(%s) priority(%d) %s\n", localRules[i].Priority, localRules[i].String(), remoteRules[j].Name, remoteRules[j].Priority, remoteRules[j].String())
|
||||
}
|
||||
cmp := strings.Compare(ruleStr, localRuleStr)
|
||||
if cmp == 0 {
|
||||
prePriority = remoteRules[j].Priority
|
||||
if remoteRules[j].ExternalId == DEFAULT_CLOUD_RULE_ID {
|
||||
remoteRules[j].Priority = addPriority(remoteRules[j].Priority, order, 1, minPriority, maxPriority, onlyAllowRules)
|
||||
}
|
||||
common = append(common, remoteRules[j])
|
||||
i++
|
||||
j++
|
||||
} else if cmp < 0 {
|
||||
if remoteRules[j].ExternalId != DEFAULT_CLOUD_RULE_ID {
|
||||
del = append(del, remoteRules[j])
|
||||
}
|
||||
j++
|
||||
} else {
|
||||
initPriority := getInitPriority(prePriority, minPriority, maxPriority)
|
||||
localRules[i].Priority = addPriority(initPriority, order, inc, minPriority, maxPriority, onlyAllowRules)
|
||||
add = append(add, SecurityRule{SecurityRule: localRules[i]})
|
||||
i++
|
||||
inc++
|
||||
}
|
||||
} else if i >= len(localRules) {
|
||||
if remoteRules[j].ExternalId != DEFAULT_CLOUD_RULE_ID {
|
||||
del = append(del, remoteRules[j])
|
||||
}
|
||||
j++
|
||||
} else if j >= len(remoteRules) {
|
||||
initPriority := startPriority
|
||||
if len(remoteRules) > 0 {
|
||||
initPriority = remoteRules[len(remoteRules)-1].Priority
|
||||
}
|
||||
initPriority = getInitPriority(initPriority, minPriority, maxPriority) // 若是初始添加规则,尽量以中间为节点,避免仅出现天地规则
|
||||
localRules[i].Priority = addPriority(initPriority, order, inc, minPriority, maxPriority, onlyAllowRules)
|
||||
add = append(add, SecurityRule{SecurityRule: localRules[i]})
|
||||
i++
|
||||
inc++
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type rulePair struct {
|
||||
localRules []secrules.SecurityRule
|
||||
remoteRules []SecurityRule
|
||||
protocol string
|
||||
}
|
||||
|
||||
var splitRules = func(localRules []secrules.SecurityRule, remoteRules []SecurityRule) []rulePair {
|
||||
rules := map[string]rulePair{}
|
||||
for _, r := range localRules {
|
||||
pair, ok := rules[r.Protocol]
|
||||
if !ok {
|
||||
pair = rulePair{localRules: []secrules.SecurityRule{}, remoteRules: []SecurityRule{}, protocol: r.Protocol}
|
||||
}
|
||||
pair.localRules = append(pair.localRules, r)
|
||||
rules[r.Protocol] = pair
|
||||
}
|
||||
|
||||
for _, r := range remoteRules {
|
||||
pair, ok := rules[r.Protocol]
|
||||
if !ok {
|
||||
pair = rulePair{localRules: []secrules.SecurityRule{}, remoteRules: []SecurityRule{}, protocol: r.Protocol}
|
||||
}
|
||||
pair.remoteRules = append(pair.remoteRules, r)
|
||||
rules[r.Protocol] = pair
|
||||
}
|
||||
|
||||
ret := []rulePair{}
|
||||
for _, r := range rules {
|
||||
ret = append(ret, r)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
var compareRules = func(localRules []secrules.SecurityRule, remoteRules []SecurityRule) (common, add, dels []SecurityRule) {
|
||||
pairs := splitRules(localRules, remoteRules)
|
||||
for _, r := range pairs {
|
||||
_common, _add, _dels := compare(r.localRules, r.remoteRules)
|
||||
common = append(common, _common...)
|
||||
add = append(add, _add...)
|
||||
dels = append(dels, _dels...)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if !inEquals {
|
||||
inCommon, inAdds, inDels = compareRules(localInRules, inRules)
|
||||
}
|
||||
if !outEquals {
|
||||
outCommon, outAdds, outDels = compareRules(localOutRules, outRules)
|
||||
}
|
||||
common = append(inCommon, outCommon...)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -124,6 +124,30 @@ func (self *SAzureGuestDriver) ValidateResizeDisk(guest *models.SGuest, disk *mo
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAzureGuestDriver) ValidateImage(ctx context.Context, image *cloudprovider.SImage) error {
|
||||
if len(image.ExternalId) == 0 {
|
||||
s := auth.GetAdminSession(ctx, options.Options.Region, "")
|
||||
result, err := modules.Images.GetSpecific(s, image.Id, "subformats", nil)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "get subformats")
|
||||
}
|
||||
subFormats := []struct {
|
||||
Format string
|
||||
}{}
|
||||
err = result.Unmarshal(&subFormats)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Unmarshal subformats")
|
||||
}
|
||||
for i := range subFormats {
|
||||
if subFormats[i].Format == "vhd" {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return httperrors.NewResourceNotFoundError("failed to find subformat vhd for image %s, please append 'vhd' for glance options(target_image_formats)", image.Name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SAzureGuestDriver) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, input *api.ServerCreateInput) (*api.ServerCreateInput, error) {
|
||||
input, err := self.SManagedVirtualizedGuestDriver.ValidateCreateData(ctx, userCred, input)
|
||||
if err != nil {
|
||||
@@ -137,59 +161,45 @@ func (self *SAzureGuestDriver) ValidateCreateData(ctx context.Context, userCred
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "FetchById")
|
||||
}
|
||||
image := _image.(*models.SCachedimage)
|
||||
if len(image.ExternalId) == 0 {
|
||||
s := auth.GetAdminSession(ctx, options.Options.Region, "")
|
||||
result, err := modules.Images.GetSpecific(s, image.Id, "subformats", nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get subformats")
|
||||
}
|
||||
subFormats := []struct {
|
||||
Format string
|
||||
}{}
|
||||
err = result.Unmarshal(&subFormats)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Unmarshal subformats")
|
||||
}
|
||||
find := false
|
||||
for i := range subFormats {
|
||||
if subFormats[i].Format == "vhd" {
|
||||
find = true
|
||||
break
|
||||
|
||||
cachedimage := _image.(*models.SCachedimage)
|
||||
image, err := cachedimage.GetImage()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetImage")
|
||||
}
|
||||
|
||||
err = self.ValidateImage(ctx, image)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(image.ExternalId) > 0 && len(input.InstanceType) > 0 {
|
||||
if cachedimage.UEFI.IsFalse() {
|
||||
if strings.HasPrefix(input.InstanceType, "Standard_M") && strings.HasSuffix(input.InstanceType, "v2") {
|
||||
return nil, httperrors.NewNotSupportedError("Azure Mv2-series instance sku only support UEFI image")
|
||||
}
|
||||
}
|
||||
if !find {
|
||||
return nil, httperrors.NewResourceNotFoundError("failed to find subformat vhd for image %s, please append 'vhd' for glance options(target_image_formats)", image.Name)
|
||||
}
|
||||
} else {
|
||||
if len(input.InstanceType) > 0 {
|
||||
if image.UEFI.IsFalse() {
|
||||
if strings.HasPrefix(input.InstanceType, "Standard_M") && strings.HasSuffix(input.InstanceType, "v2") {
|
||||
return nil, httperrors.NewNotSupportedError("Azure Mv2-series instance sku only support UEFI image")
|
||||
}
|
||||
} else {
|
||||
// https://docs.microsoft.com/en-us/azure/virtual-machines/windows/generation-2
|
||||
if !(strings.HasPrefix(input.InstanceType, "Standard_B") || // B-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_DC") && strings.HasSuffix(input.InstanceType, "s_v2") || input.InstanceType == "Standard_DC8_v2") || // DCsv2-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_DS") && strings.HasSuffix(input.InstanceType, "v2")) || // DSv2-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_DS") && strings.HasSuffix(input.InstanceType, "s_v3")) || // Dsv3-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_D") && strings.HasSuffix(input.InstanceType, "as_v4")) || // Dasv4-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_E") && strings.HasSuffix(input.InstanceType, "s_v3")) || // Esv3-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_E") && strings.HasSuffix(input.InstanceType, "as_v4")) || // Easv4-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_F") && strings.HasSuffix(input.InstanceType, "s_v2")) || // Fsv2-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_GS")) || // GS-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_HB")) || // HB-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_HC")) || // HC-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_L") && strings.HasSuffix(input.InstanceType, "s")) || // Ls-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_L") && strings.HasSuffix(input.InstanceType, "s_v2")) || // Ls-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_M")) || // M-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_M") && strings.HasSuffix(input.InstanceType, "s_v2")) || // Mv2-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_NC") && strings.HasSuffix(input.InstanceType, "s_v2")) || // NCv2-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_NC") && strings.HasSuffix(input.InstanceType, "s_v3")) || // NCv3-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_ND")) || // ND-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_NV") && strings.HasSuffix(input.InstanceType, "s_v3"))) { // NVv3-series
|
||||
return nil, httperrors.NewUnsupportOperationError("Azure UEFI image %s not support this instance sku", image.Name)
|
||||
}
|
||||
} else {
|
||||
// https://docs.microsoft.com/en-us/azure/virtual-machines/windows/generation-2
|
||||
if !(strings.HasPrefix(input.InstanceType, "Standard_B") || // B-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_DC") && strings.HasSuffix(input.InstanceType, "s_v2") || input.InstanceType == "Standard_DC8_v2") || // DCsv2-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_DS") && strings.HasSuffix(input.InstanceType, "v2")) || // DSv2-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_DS") && strings.HasSuffix(input.InstanceType, "s_v3")) || // Dsv3-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_D") && strings.HasSuffix(input.InstanceType, "as_v4")) || // Dasv4-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_E") && strings.HasSuffix(input.InstanceType, "s_v3")) || // Esv3-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_E") && strings.HasSuffix(input.InstanceType, "as_v4")) || // Easv4-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_F") && strings.HasSuffix(input.InstanceType, "s_v2")) || // Fsv2-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_GS")) || // GS-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_HB")) || // HB-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_HC")) || // HC-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_L") && strings.HasSuffix(input.InstanceType, "s")) || // Ls-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_L") && strings.HasSuffix(input.InstanceType, "s_v2")) || // Ls-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_M")) || // M-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_M") && strings.HasSuffix(input.InstanceType, "s_v2")) || // Mv2-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_NC") && strings.HasSuffix(input.InstanceType, "s_v2")) || // NCv2-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_NC") && strings.HasSuffix(input.InstanceType, "s_v3")) || // NCv3-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_ND")) || // ND-series
|
||||
(strings.HasPrefix(input.InstanceType, "Standard_NV") && strings.HasSuffix(input.InstanceType, "s_v3"))) { // NVv3-series
|
||||
return nil, httperrors.NewUnsupportOperationError("Azure UEFI image %s not support this instance sku", image.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,10 @@ func (self *SBaseGuestDriver) StartDeleteGuestTask(ctx context.Context, userCred
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) ValidateImage(ctx context.Context, image *cloudprovider.SImage) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SBaseGuestDriver) RequestDetachDisksFromGuestForDelete(ctx context.Context, guest *models.SGuest, task taskman.ITask) error {
|
||||
task.ScheduleRun(nil)
|
||||
return nil
|
||||
|
||||
@@ -172,7 +172,7 @@ func (self *SESXiGuestDriver) GetJsonDescAtHost(ctx context.Context, userCred mc
|
||||
if img.ImageType != cloudprovider.CachedImageTypeSystem {
|
||||
return desc
|
||||
}
|
||||
sciSubQ := models.StoragecachedimageManager.Query("storagecache_id").Equals("cachedimage_id", templateId).SubQuery()
|
||||
sciSubQ := models.StoragecachedimageManager.Query("storagecache_id").Equals("cachedimage_id", templateId).Equals("status", api.CACHED_IMAGE_STATUS_READY).SubQuery()
|
||||
scQ := models.StoragecacheManager.Query().In("id", sciSubQ)
|
||||
storageCaches := make([]models.SStoragecache, 0, 1)
|
||||
err = db.FetchModelObjects(models.StoragecacheManager, scQ, &storageCaches)
|
||||
@@ -234,10 +234,32 @@ func (self *SESXiGuestDriver) RequestDeployGuestOnHost(ctx context.Context, gues
|
||||
}
|
||||
config.Add(jsonutils.NewString(extId), "guest_ext_id")
|
||||
|
||||
accessInfo, err := host.GetCloudaccount().GetVCenterAccessInfo(storage.ExternalId)
|
||||
account := host.GetCloudaccount()
|
||||
accessInfo, err := account.GetVCenterAccessInfo(storage.ExternalId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
action, _ := config.GetString("action")
|
||||
if action == "create" {
|
||||
project, err := db.TenantCacheManager.FetchTenantById(ctx, guest.ProjectId)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "FetchTenantById(%s)", guest.ProjectId)
|
||||
}
|
||||
|
||||
projects, err := account.GetExternalProjectsByProjectIdOrName(project.Id, project.Name)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetExternalProjectsByProjectIdOrName(%s,%s)", project.Id, project.Name)
|
||||
}
|
||||
|
||||
extProj := account.GetAvailableExternalProject(project, projects)
|
||||
if extProj != nil {
|
||||
config.Add(jsonutils.NewString(extProj.Name), "desc", "resource_pool")
|
||||
} else {
|
||||
config.Add(jsonutils.NewString(project.Name), "desc", "resource_pool")
|
||||
}
|
||||
}
|
||||
|
||||
config.Add(jsonutils.Marshal(accessInfo), "datastore")
|
||||
|
||||
url := "/disks/agent/deploy"
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/osprofile"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
billing_api "yunion.io/x/onecloud/pkg/apis/billing"
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
@@ -449,7 +450,9 @@ func (self *SManagedVirtualizedGuestDriver) RemoteDeployGuestForCreate(ctx conte
|
||||
}
|
||||
|
||||
if hostId := iVM.GetIHostId(); len(hostId) > 0 {
|
||||
host, err := db.FetchByExternalId(models.HostManager, hostId)
|
||||
host, err := db.FetchByExternalIdAndManagerId(models.HostManager, hostId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", host.ManagerId)
|
||||
})
|
||||
if err != nil {
|
||||
log.Warningf("failed to found new hostId(%s) for ivm %s(%s) error: %v", hostId, guest.Name, guest.Id, err)
|
||||
} else if host.GetId() != guest.HostId {
|
||||
@@ -886,7 +889,13 @@ func (self *SManagedVirtualizedGuestDriver) OnGuestDeployTaskDataReceived(ctx co
|
||||
}
|
||||
|
||||
if len(diskInfo[i].StorageExternalId) > 0 {
|
||||
storage, err := db.FetchByExternalId(models.StorageManager, diskInfo[i].StorageExternalId)
|
||||
storage, err := db.FetchByExternalIdAndManagerId(models.StorageManager, diskInfo[i].StorageExternalId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
host := guest.GetHost()
|
||||
if host != nil {
|
||||
return q.Equals("manager_id", host.ManagerId)
|
||||
}
|
||||
return q
|
||||
})
|
||||
if err != nil {
|
||||
log.Warningf("failed to found storage by externalId %s error: %v", diskInfo[i].StorageExternalId, err)
|
||||
} else if disk.StorageId != storage.GetId() {
|
||||
|
||||
@@ -275,7 +275,7 @@ func (self *SManagedVirtualizationHostDriver) RequestAllocateDiskOnStorage(ctx c
|
||||
|
||||
cloudprovider.WaitStatus(iDisk, api.DISK_READY, time.Second*5, time.Minute*5)
|
||||
|
||||
models.SyncMetadata(ctx, task.GetUserCred(), disk, iDisk)
|
||||
models.SyncVirtualResourceMetadata(ctx, task.GetUserCred(), disk, iDisk)
|
||||
|
||||
data := jsonutils.NewDict()
|
||||
data.Add(jsonutils.NewInt(int64(iDisk.GetDiskSizeMB())), "disk_size")
|
||||
|
||||
@@ -175,7 +175,9 @@ func (self *SCachedimage) getStoragecacheCount() (int, error) {
|
||||
}
|
||||
|
||||
func (self *SCachedimage) GetImage() (*cloudprovider.SImage, error) {
|
||||
image := cloudprovider.SImage{}
|
||||
image := cloudprovider.SImage{
|
||||
ExternalId: self.ExternalId,
|
||||
}
|
||||
|
||||
err := self.Info.Unmarshal(&image)
|
||||
if err != nil {
|
||||
|
||||
@@ -315,10 +315,10 @@ type StorageInfo struct {
|
||||
Name string
|
||||
VirtualCapacity int64
|
||||
Capacity int64
|
||||
Reserved int64
|
||||
Reserved sql.NullInt64
|
||||
StorageType string
|
||||
MediumType string
|
||||
Cmtbound float32
|
||||
Cmtbound sql.NullFloat64
|
||||
UsedCapacity sql.NullInt64
|
||||
WasteCapacity sql.NullInt64
|
||||
FreeCapacity int64
|
||||
@@ -440,7 +440,7 @@ func getStorageTypes(
|
||||
addStorageInfo = func(storage *StorageInfo, simpleStorage *SimpleStorageInfo) {
|
||||
simpleStorage.VirtualCapacity += storage.VirtualCapacity
|
||||
simpleStorage.FreeCapacity += storage.FreeCapacity
|
||||
simpleStorage.Reserved += storage.Reserved
|
||||
simpleStorage.Reserved += storage.Reserved.Int64
|
||||
simpleStorage.Capacity += storage.Capacity
|
||||
simpleStorage.WasteCapacity += storage.WasteCapacity.Int64
|
||||
simpleStorage.UsedCapacity += storage.UsedCapacity.Int64
|
||||
@@ -493,10 +493,10 @@ func getStorageTypes(
|
||||
}
|
||||
allStorageTypes = append(allStorageTypes, storageType)
|
||||
}
|
||||
if storage.Cmtbound == 0 {
|
||||
storage.Cmtbound = options.Options.DefaultStorageOvercommitBound
|
||||
if storage.Cmtbound.Float64 == 0 {
|
||||
storage.Cmtbound.Float64 = float64(options.Options.DefaultStorageOvercommitBound)
|
||||
}
|
||||
storage.VirtualCapacity = int64(float32((storage.Capacity - storage.Reserved)) * storage.Cmtbound)
|
||||
storage.VirtualCapacity = int64(float64(storage.Capacity-storage.Reserved.Int64) * storage.Cmtbound.Float64)
|
||||
storage.FreeCapacity = storage.VirtualCapacity - storage.UsedCapacity.Int64 - storage.WasteCapacity.Int64
|
||||
addStorageInfo(&storage, simpleStorage)
|
||||
storageInfos[storageType] = simpleStorage
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -728,9 +729,9 @@ func (self *SCloudaccount) MarkEndSyncWithLock(ctx context.Context, userCred mcc
|
||||
lockman.LockObject(ctx, self)
|
||||
defer lockman.ReleaseObject(ctx, self)
|
||||
|
||||
if self.SyncStatus == api.CLOUD_PROVIDER_SYNC_STATUS_IDLE {
|
||||
return nil
|
||||
}
|
||||
// if self.SyncStatus == api.CLOUD_PROVIDER_SYNC_STATUS_IDLE {
|
||||
// return nil
|
||||
// }
|
||||
|
||||
providers := self.GetCloudproviders()
|
||||
for i := range providers {
|
||||
@@ -1742,6 +1743,18 @@ func (manager *SCloudaccountManager) initAllRecords() {
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SCloudaccount) CanSync() bool {
|
||||
if self.SyncStatus == api.CLOUD_PROVIDER_SYNC_STATUS_QUEUED || self.SyncStatus == api.CLOUD_PROVIDER_SYNC_STATUS_SYNCING || self.getSyncStatus2() == api.CLOUD_PROVIDER_SYNC_STATUS_SYNCING {
|
||||
if self.LastSync.IsZero() || time.Now().Sub(self.LastSync) > 1800*time.Second {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SCloudaccountManager) AutoSyncCloudaccountTask(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
if isStart && !options.Options.IsSlaveNode {
|
||||
// mark all the records to be idle
|
||||
@@ -1777,7 +1790,7 @@ func (account *SCloudaccount) probeAccountStatus(ctx context.Context, userCred m
|
||||
manager, err := account.getProviderInternal()
|
||||
if err != nil {
|
||||
log.Errorf("account.GetProvider failed: %s", err)
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "account.getProviderInternal")
|
||||
}
|
||||
balance, status, err := manager.GetBalance()
|
||||
if err != nil {
|
||||
@@ -1795,7 +1808,7 @@ func (account *SCloudaccount) probeAccountStatus(ctx context.Context, userCred m
|
||||
sysInfo, err := manager.GetSysInfo()
|
||||
if err != nil {
|
||||
log.Errorf("manager.GetSysInfo fail %s", err)
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "manager.GetSysInfo")
|
||||
}
|
||||
factory := manager.GetFactory()
|
||||
diff, err := db.Update(account, func() error {
|
||||
@@ -1848,7 +1861,7 @@ func (account *SCloudaccount) syncAccountStatus(ctx context.Context, userCred mc
|
||||
if err != nil {
|
||||
account.markAllProvidersDicconnected(ctx, userCred)
|
||||
account.markAccountDiscconected(ctx, userCred)
|
||||
return err
|
||||
return errors.Wrap(err, "account.probeAccountStatus")
|
||||
}
|
||||
account.markAccountConnected(ctx, userCred)
|
||||
providers := account.importAllSubaccounts(ctx, userCred, subaccounts)
|
||||
@@ -1857,7 +1870,7 @@ func (account *SCloudaccount) syncAccountStatus(ctx context.Context, userCred mc
|
||||
_, err := providers[i].prepareCloudproviderRegions(ctx, userCred)
|
||||
if err != nil {
|
||||
log.Errorf("syncCloudproviderRegion fail %s", err)
|
||||
return err
|
||||
return errors.Wrap(err, "providers[i].prepareCloudproviderRegions")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1876,13 +1889,37 @@ func (account *SCloudaccount) markAutoSync(userCred mcclient.TokenCredential) er
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
cloudaccountPendingSyncs = map[string]struct{}{}
|
||||
cloudaccountPendingSyncsMutex = &sync.Mutex{}
|
||||
)
|
||||
|
||||
func (account *SCloudaccount) SubmitSyncAccountTask(ctx context.Context, userCred mcclient.TokenCredential, waitChan chan error, autoSync bool) {
|
||||
cloudaccountPendingSyncsMutex.Lock()
|
||||
defer cloudaccountPendingSyncsMutex.Unlock()
|
||||
if _, ok := cloudaccountPendingSyncs[account.Id]; ok {
|
||||
if waitChan != nil {
|
||||
// an active cloudaccount sync task is running, return with conflict error
|
||||
log.Errorf("an active cloudaccount sync task is running, early return with conflict error")
|
||||
waitChan <- errors.Wrap(httperrors.ErrConflict, "cloudaccountPendingSyncs")
|
||||
}
|
||||
return
|
||||
}
|
||||
cloudaccountPendingSyncs[account.Id] = struct{}{}
|
||||
|
||||
RunSyncCloudAccountTask(func() {
|
||||
func() {
|
||||
cloudaccountPendingSyncsMutex.Lock()
|
||||
defer cloudaccountPendingSyncsMutex.Unlock()
|
||||
delete(cloudaccountPendingSyncs, account.Id)
|
||||
}()
|
||||
|
||||
log.Debugf("syncAccountStatus %s %s", account.Id, account.Name)
|
||||
err := account.syncAccountStatus(ctx, userCred)
|
||||
if waitChan != nil {
|
||||
if err != nil {
|
||||
account.markEndSync(userCred)
|
||||
err = errors.Wrap(err, "account.syncAccountStatus")
|
||||
}
|
||||
waitChan <- err
|
||||
} else {
|
||||
@@ -1892,7 +1929,8 @@ func (account *SCloudaccount) SubmitSyncAccountTask(ctx context.Context, userCre
|
||||
account.markAutoSync(userCred)
|
||||
providers := account.GetEnabledCloudproviders()
|
||||
for i := range providers {
|
||||
providers[i].syncCloudproviderRegions(ctx, userCred, syncRange, nil, autoSync)
|
||||
provider := &providers[i]
|
||||
provider.syncCloudproviderRegions(ctx, userCred, syncRange, nil, autoSync)
|
||||
syncCnt += 1
|
||||
}
|
||||
}
|
||||
@@ -1918,6 +1956,16 @@ func (self *SCloudaccount) Delete(ctx context.Context, userCred mcclient.TokenCr
|
||||
|
||||
func (self *SCloudaccount) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
self.SetStatus(userCred, api.CLOUD_PROVIDER_DELETED, "real delete")
|
||||
projects, err := self.GetExternalProjects()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetExternalProjects")
|
||||
}
|
||||
for i := range projects {
|
||||
err = projects[i].Delete(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "project %s Delete", projects[i].Id)
|
||||
}
|
||||
}
|
||||
return self.SEnabledStatusInfrasResourceBase.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
@@ -2248,6 +2296,32 @@ func (account *SCloudaccount) PerformSyncSkus(ctx context.Context, userCred mccl
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SCloudaccount) GetExternalProjects() ([]SExternalProject, error) {
|
||||
projects := []SExternalProject{}
|
||||
q := ExternalProjectManager.Query().Equals("cloudaccount_id", self.Id)
|
||||
err := db.FetchModelObjects(ExternalProjectManager, q, &projects)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "db.FetchModelObjects")
|
||||
}
|
||||
return projects, nil
|
||||
}
|
||||
|
||||
func (self *SCloudaccount) GetExternalProjectsByProjectIdOrName(projectId, name string) ([]SExternalProject, error) {
|
||||
projects := []SExternalProject{}
|
||||
q := ExternalProjectManager.Query().Equals("cloudaccount_id", self.Id)
|
||||
q = q.Filter(
|
||||
sqlchemy.OR(
|
||||
sqlchemy.Equals(q.Field("name"), name),
|
||||
sqlchemy.Equals(q.Field("tenant_id"), projectId),
|
||||
),
|
||||
)
|
||||
err := db.FetchModelObjects(ExternalProjectManager, q, &projects)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "db.FetchModelObjects")
|
||||
}
|
||||
return projects, nil
|
||||
}
|
||||
|
||||
func (manager *SCloudaccountManager) queryCloudAccountByCapability(region *SCloudregion, zone *SZone, domainId string, enabled tristate.TriState, capability string) *sqlchemy.SQuery {
|
||||
providers := CloudproviderManager.Query().SubQuery()
|
||||
q := manager.Query()
|
||||
@@ -2339,3 +2413,78 @@ func (account *SCloudaccount) GetUsages() []db.IUsage {
|
||||
&usage,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SCloudaccount) GetAvailableExternalProject(local *db.STenant, projects []SExternalProject) *SExternalProject {
|
||||
var ret *SExternalProject = nil
|
||||
for i := 0; i < len(projects); i++ {
|
||||
if projects[i].Status == api.EXTERNAL_PROJECT_STATUS_AVAILABLE {
|
||||
if projects[i].ProjectId == local.Id {
|
||||
return &projects[i]
|
||||
}
|
||||
if projects[i].Name == local.Name {
|
||||
ret = &projects[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// 若本地项目映射了多个云上项目,则在云上随机找一个项目
|
||||
// 若本地项目没有映射云上任何项目,则在云上新建一个同名项目
|
||||
// 若本地项目a映射云上项目b,但b项目不可用,则看云上是否有a项目,有则直接使用,若没有则在云上创建a-1, a-2类似项目
|
||||
func (self *SCloudaccount) SyncProject(ctx context.Context, userCred mcclient.TokenCredential, projectId string) (string, error) {
|
||||
lockman.LockRawObject(ctx, self.Id, projectId)
|
||||
defer lockman.ReleaseRawObject(ctx, self.Id, projectId)
|
||||
|
||||
provider, err := self.GetProvider()
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "GetProvider")
|
||||
}
|
||||
|
||||
if !cloudprovider.IsSupportProject(provider) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
project, err := db.TenantCacheManager.FetchTenantById(ctx, projectId)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "FetchTenantById(%s)", projectId)
|
||||
}
|
||||
|
||||
projects, err := self.GetExternalProjectsByProjectIdOrName(projectId, project.Name)
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "GetExternalProjectsByProjectIdOrName(%s,%s)", projectId, project.Name)
|
||||
}
|
||||
|
||||
extProj := self.GetAvailableExternalProject(project, projects)
|
||||
if extProj != nil {
|
||||
return extProj.ExternalId, nil
|
||||
}
|
||||
|
||||
retry := 1
|
||||
if len(projects) > 0 {
|
||||
retry = 10
|
||||
}
|
||||
|
||||
var iProject cloudprovider.ICloudProject = nil
|
||||
projectName := project.Name
|
||||
for i := 0; i < retry; i++ {
|
||||
iProject, err = provider.CreateIProject(projectName)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
projectName = fmt.Sprintf("%s-%d", project.Name, i)
|
||||
}
|
||||
if err != nil {
|
||||
if errors.Cause(err) != cloudprovider.ErrNotImplemented && errors.Cause(err) != cloudprovider.ErrNotSupported {
|
||||
logclient.AddSimpleActionLog(self, logclient.ACT_CREATE, err, userCred, false)
|
||||
}
|
||||
return "", errors.Wrapf(err, "CreateIProject(%s)", projectName)
|
||||
}
|
||||
|
||||
extProj, err = ExternalProjectManager.newFromCloudProject(ctx, userCred, self, project, iProject)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "newFromCloudProject")
|
||||
}
|
||||
|
||||
return extProj.ExternalId, nil
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ func (self *SCloudproviderregion) GetAccount() *SCloudaccount {
|
||||
func (self *SCloudproviderregion) GetRegion() *SCloudregion {
|
||||
regionObj, err := CloudregionManager.FetchById(self.CloudregionId)
|
||||
if err != nil {
|
||||
log.Errorf("CloudproviderManager.FetchById fail %s", err)
|
||||
log.Errorf("CloudregionManager.FetchById(%s) fail %s", self.CloudregionId, err)
|
||||
return nil
|
||||
}
|
||||
return regionObj.(*SCloudregion)
|
||||
|
||||
@@ -1128,7 +1128,8 @@ func (manager *SCloudproviderManager) ListItemFilter(
|
||||
sqlchemy.Equals(vpcs.Field("manager_id"), providers.Field("id")),
|
||||
))
|
||||
if zone != nil {
|
||||
sq = sq.Filter(sqlchemy.Equals(wires.Field("zone_id"), zone.GetId()))
|
||||
zoneFilter := sqlchemy.OR(sqlchemy.Equals(wires.Field("zone_id"), zone.GetId()), sqlchemy.IsNullOrEmpty(wires.Field("zone_id")))
|
||||
sq = sq.Filter(zoneFilter)
|
||||
} else if region != nil {
|
||||
sq = sq.Filter(sqlchemy.Equals(vpcs.Field("cloudregion_id"), region.GetId()))
|
||||
}
|
||||
@@ -1372,7 +1373,6 @@ func (self *SCloudprovider) RealDelete(ctx context.Context, userCred mcclient.To
|
||||
ElasticipManager,
|
||||
NetworkInterfaceManager,
|
||||
CloudproviderRegionManager,
|
||||
ExternalProjectManager,
|
||||
CloudregionManager,
|
||||
CloudproviderQuotaManager,
|
||||
} {
|
||||
@@ -1405,6 +1405,14 @@ func (self *SCloudprovider) StartCloudproviderDeleteTask(ctx context.Context, us
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) GetRegionDriver() (IRegionDriver, error) {
|
||||
driver := GetRegionDriver(self.Provider)
|
||||
if driver == nil {
|
||||
return nil, fmt.Errorf("failed to found region driver for %s", self.Provider)
|
||||
}
|
||||
return driver, nil
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) ClearSchedDescCache() error {
|
||||
hosts := make([]SHost, 0)
|
||||
q := HostManager.Query().Equals("manager_id", self.Id)
|
||||
@@ -1620,51 +1628,10 @@ func (provider *SCloudprovider) GetChangeOwnerCandidateDomainIds() []string {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) GetExternalProjects() ([]SExternalProject, error) {
|
||||
q := ExternalProjectManager.Query().Equals("manager_id", self.Id)
|
||||
projects := []SExternalProject{}
|
||||
err := db.FetchModelObjects(ExternalProjectManager, q, &projects)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "FetchModelObjects")
|
||||
}
|
||||
return projects, nil
|
||||
}
|
||||
|
||||
func (self *SCloudprovider) SyncProject(ctx context.Context, userCred mcclient.TokenCredential, id string) (string, error) {
|
||||
lockman.LockRawObject(ctx, self.Id, id)
|
||||
defer lockman.ReleaseRawObject(ctx, self.Id, id)
|
||||
|
||||
projects, err := self.GetExternalProjects()
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "GetExternalProjects")
|
||||
account := self.GetCloudaccount()
|
||||
if account == nil {
|
||||
return "", fmt.Errorf("failed to get cloudprovider %s account", self.Name)
|
||||
}
|
||||
for _, project := range projects {
|
||||
if project.ProjectId == id {
|
||||
return project.ExternalId, nil
|
||||
}
|
||||
}
|
||||
|
||||
project, err := db.TenantCacheManager.FetchById(id)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "TenantCacheManager.FetchById")
|
||||
}
|
||||
|
||||
for _, extProj := range projects {
|
||||
if extProj.Name == project.GetName() {
|
||||
return extProj.ExternalId, nil
|
||||
}
|
||||
}
|
||||
provider, err := self.GetProvider()
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "GetProvider")
|
||||
}
|
||||
iProject, err := provider.CreateIProject(project.GetName())
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "CreateIProject")
|
||||
}
|
||||
extProj, err := ExternalProjectManager.newFromCloudProject(ctx, userCred, self, iProject)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "newFromCloudProject")
|
||||
}
|
||||
return extProj.ExternalId, nil
|
||||
return account.SyncProject(ctx, userCred, id)
|
||||
}
|
||||
|
||||
@@ -226,15 +226,38 @@ func (self *SCloudregion) getGuestCountInternal(increment bool) (int, error) {
|
||||
return query.CountWithError()
|
||||
}
|
||||
|
||||
func (self *SCloudregion) GetVpcCount() (int, error) {
|
||||
func (self *SCloudregion) GetVpcQuery() *sqlchemy.SQuery {
|
||||
vpcs := VpcManager.Query()
|
||||
if self.Id == api.DEFAULT_REGION_ID {
|
||||
return vpcs.Filter(sqlchemy.OR(sqlchemy.IsNull(vpcs.Field("cloudregion_id")),
|
||||
sqlchemy.IsEmpty(vpcs.Field("cloudregion_id")),
|
||||
sqlchemy.Equals(vpcs.Field("cloudregion_id"), self.Id))).CountWithError()
|
||||
} else {
|
||||
return vpcs.Equals("cloudregion_id", self.Id).CountWithError()
|
||||
sqlchemy.Equals(vpcs.Field("cloudregion_id"), self.Id)))
|
||||
}
|
||||
return vpcs.Equals("cloudregion_id", self.Id)
|
||||
}
|
||||
|
||||
func (self *SCloudregion) GetVpcCount() (int, error) {
|
||||
return self.GetVpcQuery().CountWithError()
|
||||
}
|
||||
|
||||
func (self *SCloudregion) GetVpcs() ([]SVpc, error) {
|
||||
vpcs := []SVpc{}
|
||||
q := self.GetVpcQuery()
|
||||
err := db.FetchModelObjects(VpcManager, q, &vpcs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "db.FetchModelObjects")
|
||||
}
|
||||
return vpcs, nil
|
||||
}
|
||||
|
||||
func (self *SCloudregion) GetCloudproviderVpcs(managerId string) ([]SVpc, error) {
|
||||
vpcs := []SVpc{}
|
||||
q := self.GetVpcQuery().Equals("manager_id", managerId)
|
||||
err := db.FetchModelObjects(VpcManager, q, &vpcs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "db.FetchModelObjects")
|
||||
}
|
||||
return vpcs, nil
|
||||
}
|
||||
|
||||
func (self *SCloudregion) GetDriver() IRegionDriver {
|
||||
@@ -497,7 +520,7 @@ func (self *SCloudregion) AllowPerformDefaultVpc(ctx context.Context, userCred m
|
||||
}
|
||||
|
||||
func (self *SCloudregion) PerformDefaultVpc(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
vpcs, err := VpcManager.getVpcsByRegion(self, nil)
|
||||
vpcs, err := self.GetVpcs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -172,28 +172,6 @@ func syncRegionSkus(ctx context.Context, userCred mcclient.TokenCredential, loca
|
||||
}
|
||||
}
|
||||
|
||||
func syncProjects(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, driver cloudprovider.ICloudProvider, provider *SCloudprovider) {
|
||||
projects, err := driver.GetIProjects()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("GetIProjects for provider %s failed %s", provider.GetName(), err)
|
||||
log.Errorf(msg)
|
||||
// logSyncFailed(provider, task, msg)
|
||||
return
|
||||
}
|
||||
|
||||
result := ExternalProjectManager.SyncProjects(ctx, userCred, provider, projects)
|
||||
|
||||
syncResults.Add(ExternalProjectManager, result)
|
||||
|
||||
msg := result.Result()
|
||||
log.Infof("SyncProjects for provider %s result: %s", provider.Name, msg)
|
||||
if result.IsError() {
|
||||
// logSyncFailed(provider, task, msg)
|
||||
return
|
||||
}
|
||||
// db.OpsLog.LogEvent(provider, db.ACT_SYNC_PROJECT_COMPLETE, msg, task.UserCred)
|
||||
}
|
||||
|
||||
func syncRegionEips(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localRegion *SCloudregion, remoteRegion cloudprovider.ICloudRegion, syncRange *SSyncRange) {
|
||||
eips, err := remoteRegion.GetIEips()
|
||||
if err != nil {
|
||||
@@ -658,7 +636,7 @@ func syncHostVMs(ctx context.Context, userCred mcclient.TokenCredential, syncRes
|
||||
}
|
||||
|
||||
func syncVMPeripherals(ctx context.Context, userCred mcclient.TokenCredential, local *SGuest, remote cloudprovider.ICloudVM, host *SHost, provider *SCloudprovider, driver cloudprovider.ICloudProvider) {
|
||||
syncMetadata(ctx, userCred, local, remote)
|
||||
syncVirtualResourceMetadata(ctx, userCred, local, remote)
|
||||
err := syncVMNics(ctx, userCred, provider, host, local, remote)
|
||||
if err != nil {
|
||||
log.Errorf("syncVMNics error %s", err)
|
||||
@@ -1027,10 +1005,6 @@ func syncPublicCloudProviderInfo(
|
||||
|
||||
storageCachePairs := make([]sStoragecacheSyncPair, 0)
|
||||
|
||||
if cloudprovider.IsSupportProject(driver) {
|
||||
syncProjects(ctx, userCred, syncResults, driver, provider)
|
||||
}
|
||||
|
||||
syncRegionQuotas(ctx, userCred, syncResults, driver, provider, localRegion, remoteRegion)
|
||||
|
||||
localZones, remoteZones, _ := syncRegionZones(ctx, userCred, syncResults, provider, localRegion, remoteRegion)
|
||||
@@ -1124,10 +1098,6 @@ func syncOnPremiseCloudProviderInfo(
|
||||
) error {
|
||||
log.Debugf("Start sync on-premise provider %s(%s)", provider.Name, provider.Provider)
|
||||
|
||||
if cloudprovider.IsSupportProject(driver) {
|
||||
syncProjects(ctx, userCred, syncResults, driver, provider)
|
||||
}
|
||||
|
||||
iregion, err := driver.GetOnPremiseIRegion()
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("GetOnPremiseIRegion for provider %s failed %s", provider.GetName(), err)
|
||||
@@ -1221,7 +1191,7 @@ func SyncCloudProject(userCred mcclient.TokenCredential, model db.IVirtualModel,
|
||||
if extProjectId := extModel.GetProjectId(); len(extProjectId) > 0 {
|
||||
extProject, err := ExternalProjectManager.GetProject(extProjectId, managerId)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
log.Errorf("sync project for %s %s error: %v", model.Keyword(), model.GetName(), err)
|
||||
} else {
|
||||
newOwnerId = extProject.GetOwnerId()
|
||||
}
|
||||
|
||||
@@ -437,7 +437,9 @@ func (self *SDBInstanceBackup) SyncWithCloudDBInstanceBackup(
|
||||
|
||||
if dbinstanceId := extBackup.GetDBInstanceId(); len(dbinstanceId) > 0 {
|
||||
//有可能云上删除了实例,未删除备份
|
||||
_instance, err := db.FetchByExternalId(DBInstanceManager, dbinstanceId)
|
||||
_instance, err := db.FetchByExternalIdAndManagerId(DBInstanceManager, dbinstanceId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", provider.Id)
|
||||
})
|
||||
if err == sql.ErrNoRows {
|
||||
self.DBInstanceId = ""
|
||||
}
|
||||
@@ -493,7 +495,9 @@ func (manager *SDBInstanceBackupManager) newFromCloudDBInstanceBackup(
|
||||
backup.ExternalId = extBackup.GetGlobalId()
|
||||
|
||||
if dbinstanceId := extBackup.GetDBInstanceId(); len(dbinstanceId) > 0 {
|
||||
_dbinstance, err := db.FetchByExternalId(DBInstanceManager, dbinstanceId)
|
||||
_dbinstance, err := db.FetchByExternalIdAndManagerId(DBInstanceManager, dbinstanceId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", provider.Id)
|
||||
})
|
||||
if err != nil {
|
||||
log.Warningf("failed to found dbinstance for backup %s by externalId: %s error: %v", backup.Name, dbinstanceId, err)
|
||||
} else {
|
||||
|
||||
@@ -165,15 +165,20 @@ func (manager *SDBInstanceSkuManager) ListItemFilter(
|
||||
q = q.In("engine_version", query.EngineVersion)
|
||||
}
|
||||
|
||||
zones := ZoneManager.Query().SubQuery()
|
||||
for k, v := range map[string][]string{"zone1": query.Zone1, "zone2": query.Zone2, "zone3": query.Zone3} {
|
||||
if len(v) > 0 {
|
||||
q = q.Join(zones, sqlchemy.Equals(zones.Field("id"), q.Field(k))).Filter(
|
||||
sqlchemy.OR(
|
||||
sqlchemy.In(zones.Field("name"), v),
|
||||
sqlchemy.In(zones.Field("id"), v),
|
||||
),
|
||||
)
|
||||
for k, zoneIds := range map[string][]string{"zone1": query.Zone1, "zone2": query.Zone2, "zone3": query.Zone3} {
|
||||
ids := []string{}
|
||||
for _, zoneId := range zoneIds {
|
||||
zone, err := ZoneManager.FetchByIdOrName(userCred, zoneId)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError2("zone", zoneId)
|
||||
}
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
ids = append(ids, zone.GetId())
|
||||
}
|
||||
if len(ids) > 0 {
|
||||
q = q.In(k, ids)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
@@ -162,9 +163,15 @@ func (manager *SDBInstanceNetworkManager) SyncDBInstanceNetwork(ctx context.Cont
|
||||
|
||||
func (self *SDBInstanceNetwork) syncWithCloudDBNetwork(ctx context.Context, userCred mcclient.TokenCredential, dbinstance *SDBInstance, network *cloudprovider.SDBInstanceNetwork) error {
|
||||
_, err := db.UpdateWithLock(ctx, self, func() error {
|
||||
_localnetwork, err := db.FetchByExternalId(NetworkManager, network.NetworkId)
|
||||
_localnetwork, err := db.FetchByExternalIdAndManagerId(NetworkManager, network.NetworkId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
wire := WireManager.Query().SubQuery()
|
||||
vpc := VpcManager.Query().SubQuery()
|
||||
return q.Join(wire, sqlchemy.Equals(wire.Field("id"), q.Field("wire_id"))).
|
||||
Join(vpc, sqlchemy.Equals(vpc.Field("id"), wire.Field("vpc_id"))).
|
||||
Filter(sqlchemy.Equals(vpc.Field("manager_id"), dbinstance.ManagerId))
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "FetchByExternalId")
|
||||
return errors.Wrapf(err, "FetchByExternalIdAndManagerId")
|
||||
}
|
||||
localnetwork := _localnetwork.(*SNetwork)
|
||||
self.NetworkId = localnetwork.Id
|
||||
@@ -194,9 +201,15 @@ func (manager *SDBInstanceNetworkManager) newFromCloudDBNetwork(ctx context.Cont
|
||||
dbNetwork.SetModelManager(manager, &dbNetwork)
|
||||
|
||||
dbNetwork.DBInstanceId = dbinstance.Id
|
||||
_localnetwork, err := db.FetchByExternalId(NetworkManager, network.NetworkId)
|
||||
_localnetwork, err := db.FetchByExternalIdAndManagerId(NetworkManager, network.NetworkId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
wire := WireManager.Query().SubQuery()
|
||||
vpc := VpcManager.Query().SubQuery()
|
||||
return q.Join(wire, sqlchemy.Equals(wire.Field("id"), q.Field("wire_id"))).
|
||||
Join(vpc, sqlchemy.Equals(vpc.Field("id"), wire.Field("vpc_id"))).
|
||||
Filter(sqlchemy.Equals(vpc.Field("manager_id"), dbinstance.ManagerId))
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "newFromCloudDBNetwork.FetchByExternalId")
|
||||
return errors.Wrapf(err, "newFromCloudDBNetwork.FetchByExternalIdAndManagerId")
|
||||
}
|
||||
|
||||
localnetwork := _localnetwork.(*SNetwork)
|
||||
|
||||
@@ -1236,12 +1236,16 @@ func (manager *SDBInstanceManager) SyncDBInstanceMasterId(ctx context.Context, u
|
||||
for _, instance := range cloudDBInstances {
|
||||
masterId := instance.GetMasterInstanceId()
|
||||
if len(masterId) > 0 {
|
||||
master, err := db.FetchByExternalId(manager, masterId)
|
||||
master, err := db.FetchByExternalIdAndManagerId(manager, masterId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", provider.Id)
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("failed to found master dbinstance by externalId: %s error: %v", masterId, err)
|
||||
continue
|
||||
}
|
||||
slave, err := db.FetchByExternalId(manager, instance.GetGlobalId())
|
||||
slave, err := db.FetchByExternalIdAndManagerId(manager, instance.GetGlobalId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", provider.Id)
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("failed to found local dbinstance by externalId %s error: %v", instance.GetGlobalId(), err)
|
||||
continue
|
||||
@@ -1296,7 +1300,7 @@ func (manager *SDBInstanceManager) SyncDBInstances(ctx context.Context, userCred
|
||||
syncResult.UpdateError(err)
|
||||
continue
|
||||
}
|
||||
syncMetadata(ctx, userCred, &commondb[i], commonext[i])
|
||||
syncVirtualResourceMetadata(ctx, userCred, &commondb[i], commonext[i])
|
||||
localDBInstances = append(localDBInstances, commondb[i])
|
||||
remoteDBInstances = append(remoteDBInstances, commonext[i])
|
||||
syncResult.Update()
|
||||
@@ -1308,7 +1312,7 @@ func (manager *SDBInstanceManager) SyncDBInstances(ctx context.Context, userCred
|
||||
syncResult.AddError(err)
|
||||
continue
|
||||
}
|
||||
syncMetadata(ctx, userCred, instance, added[i])
|
||||
syncVirtualResourceMetadata(ctx, userCred, instance, added[i])
|
||||
localDBInstances = append(localDBInstances, *instance)
|
||||
remoteDBInstances = append(remoteDBInstances, added[i])
|
||||
syncResult.Add()
|
||||
@@ -1320,9 +1324,12 @@ func (self *SDBInstance) syncRemoveCloudDBInstance(ctx context.Context, userCred
|
||||
lockman.LockObject(ctx, self)
|
||||
defer lockman.ReleaseObject(ctx, self)
|
||||
|
||||
self.DeletePreventionOff(self, userCred)
|
||||
|
||||
err := self.ValidateDeleteCondition(ctx)
|
||||
if err != nil { // cannot delete
|
||||
return self.SetStatus(userCred, api.VPC_STATUS_UNKNOWN, "sync to delete")
|
||||
self.SetStatus(userCred, api.VPC_STATUS_UNKNOWN, "sync to delete")
|
||||
return errors.Wrap(err, "ValidateDeleteCondition")
|
||||
}
|
||||
return self.RealDelete(ctx, userCred)
|
||||
}
|
||||
@@ -1492,7 +1499,9 @@ func (self *SDBInstance) SyncWithCloudDBInstance(ctx context.Context, userCred m
|
||||
|
||||
if len(self.VpcId) == 0 {
|
||||
if vpcId := extInstance.GetIVpcId(); len(vpcId) > 0 {
|
||||
vpc, err := db.FetchByExternalId(VpcManager, vpcId)
|
||||
vpc, err := db.FetchByExternalIdAndManagerId(VpcManager, vpcId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", provider.Id)
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "SyncWithCloudDBInstance.FetchVpcId")
|
||||
}
|
||||
@@ -1577,7 +1586,9 @@ func (manager *SDBInstanceManager) newFromCloudDBInstance(ctx context.Context, u
|
||||
}
|
||||
|
||||
if vpcId := extInstance.GetIVpcId(); len(vpcId) > 0 {
|
||||
vpc, err := db.FetchByExternalId(VpcManager, vpcId)
|
||||
vpc, err := db.FetchByExternalIdAndManagerId(VpcManager, vpcId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", provider.Id)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "newFromCloudDBInstance.FetchVpcId")
|
||||
}
|
||||
|
||||
@@ -1138,6 +1138,14 @@ func (self *SDisk) IsLocal() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self *SDisk) GetCloudproviderId() string {
|
||||
storage := self.GetStorage()
|
||||
if storage != nil {
|
||||
return storage.GetCloudproviderId()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SDisk) GetStorage() *SStorage {
|
||||
store, _ := StorageManager.FetchById(self.StorageId)
|
||||
if store != nil {
|
||||
@@ -1209,18 +1217,26 @@ func (manager *SDiskManager) getDisksByStorage(storage *SStorage) ([]SDisk, erro
|
||||
return disks, nil
|
||||
}
|
||||
|
||||
func (manager *SDiskManager) syncCloudDisk(ctx context.Context, userCred mcclient.TokenCredential, provider cloudprovider.ICloudProvider, vdisk cloudprovider.ICloudDisk, index int, syncOwnerId mcclient.IIdentityProvider) (*SDisk, error) {
|
||||
func (manager *SDiskManager) syncCloudDisk(ctx context.Context, userCred mcclient.TokenCredential, provider cloudprovider.ICloudProvider, vdisk cloudprovider.ICloudDisk, index int, syncOwnerId mcclient.IIdentityProvider, managerId string) (*SDisk, error) {
|
||||
// ownerProjId := projectId
|
||||
|
||||
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, syncOwnerId))
|
||||
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, syncOwnerId))
|
||||
|
||||
diskObj, err := db.FetchByExternalId(manager, vdisk.GetGlobalId())
|
||||
diskObj, err := db.FetchByExternalIdAndManagerId(manager, vdisk.GetGlobalId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
sq := StorageManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("storage_id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), managerId))
|
||||
})
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
vstorage, _ := vdisk.GetIStorage()
|
||||
vstorage, err := vdisk.GetIStorage()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "unable to GetIStorage of vdisk %q", vdisk.GetName())
|
||||
}
|
||||
|
||||
storageObj, err := db.FetchByExternalId(StorageManager, vstorage.GetGlobalId())
|
||||
storageObj, err := db.FetchByExternalIdAndManagerId(StorageManager, vstorage.GetGlobalId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", managerId)
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("cannot find storage of vdisk %s", err)
|
||||
return nil, err
|
||||
@@ -1232,7 +1248,7 @@ func (manager *SDiskManager) syncCloudDisk(ctx context.Context, userCred mcclien
|
||||
}
|
||||
} else {
|
||||
disk := diskObj.(*SDisk)
|
||||
err = disk.syncWithCloudDisk(ctx, userCred, provider, vdisk, index, syncOwnerId)
|
||||
err = disk.syncWithCloudDisk(ctx, userCred, provider, vdisk, index, syncOwnerId, managerId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1277,11 +1293,11 @@ func (manager *SDiskManager) SyncDisks(ctx context.Context, userCred mcclient.To
|
||||
}
|
||||
|
||||
for i := 0; i < len(commondb); i += 1 {
|
||||
err = commondb[i].syncWithCloudDisk(ctx, userCred, provider, commonext[i], -1, syncOwnerId)
|
||||
err = commondb[i].syncWithCloudDisk(ctx, userCred, provider, commonext[i], -1, syncOwnerId, storage.ManagerId)
|
||||
if err != nil {
|
||||
syncResult.UpdateError(err)
|
||||
} else {
|
||||
syncMetadata(ctx, userCred, &commondb[i], commonext[i])
|
||||
syncVirtualResourceMetadata(ctx, userCred, &commondb[i], commonext[i])
|
||||
localDisks = append(localDisks, commondb[i])
|
||||
remoteDisks = append(remoteDisks, commonext[i])
|
||||
syncResult.Update()
|
||||
@@ -1290,7 +1306,10 @@ func (manager *SDiskManager) SyncDisks(ctx context.Context, userCred mcclient.To
|
||||
|
||||
for i := 0; i < len(added); i += 1 {
|
||||
extId := added[i].GetGlobalId()
|
||||
_disk, err := db.FetchByExternalId(manager, extId)
|
||||
_disk, err := db.FetchByExternalIdAndManagerId(manager, extId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
sq := StorageManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("storage_id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), storage.ManagerId))
|
||||
})
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
//主要是显示duplicate err及 general err,方便排错
|
||||
msg := fmt.Errorf("failed to found disk by external Id %s error: %v", extId, err)
|
||||
@@ -1299,7 +1318,7 @@ func (manager *SDiskManager) SyncDisks(ctx context.Context, userCred mcclient.To
|
||||
}
|
||||
if _disk != nil {
|
||||
disk := _disk.(*SDisk)
|
||||
err = disk.syncDiskStorage(ctx, userCred, added[i])
|
||||
err = disk.syncDiskStorage(ctx, userCred, added[i], storage.ManagerId)
|
||||
if err != nil {
|
||||
syncResult.UpdateError(err)
|
||||
} else {
|
||||
@@ -1311,7 +1330,7 @@ func (manager *SDiskManager) SyncDisks(ctx context.Context, userCred mcclient.To
|
||||
if err != nil {
|
||||
syncResult.AddError(err)
|
||||
} else {
|
||||
syncMetadata(ctx, userCred, new, added[i])
|
||||
syncVirtualResourceMetadata(ctx, userCred, new, added[i])
|
||||
localDisks = append(localDisks, *new)
|
||||
remoteDisks = append(remoteDisks, added[i])
|
||||
syncResult.Add()
|
||||
@@ -1321,7 +1340,7 @@ func (manager *SDiskManager) SyncDisks(ctx context.Context, userCred mcclient.To
|
||||
return localDisks, remoteDisks, syncResult
|
||||
}
|
||||
|
||||
func (self *SDisk) syncDiskStorage(ctx context.Context, userCred mcclient.TokenCredential, idisk cloudprovider.ICloudDisk) error {
|
||||
func (self *SDisk) syncDiskStorage(ctx context.Context, userCred mcclient.TokenCredential, idisk cloudprovider.ICloudDisk, managerId string) error {
|
||||
extId := idisk.GetGlobalId()
|
||||
istorage, err := idisk.GetIStorage()
|
||||
if err != nil {
|
||||
@@ -1329,7 +1348,9 @@ func (self *SDisk) syncDiskStorage(ctx context.Context, userCred mcclient.TokenC
|
||||
return err
|
||||
}
|
||||
storageExtId := istorage.GetGlobalId()
|
||||
storage, err := db.FetchByExternalId(StorageManager, storageExtId)
|
||||
storage, err := db.FetchByExternalIdAndManagerId(StorageManager, storageExtId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", managerId)
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("failed to found storage by istorage %s error: %v", storageExtId, err)
|
||||
return err
|
||||
@@ -1381,7 +1402,12 @@ func (self *SDisk) syncRemoveCloudDisk(ctx context.Context, userCred mcclient.To
|
||||
iDisk, err := iregion.GetIDiskById(self.ExternalId)
|
||||
if err == nil {
|
||||
if storageId := iDisk.GetIStorageId(); len(storageId) > 0 {
|
||||
storage, err := db.FetchByExternalId(StorageManager, storageId)
|
||||
storage, err := db.FetchByExternalIdAndManagerId(StorageManager, storageId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
if s := self.GetStorage(); s != nil {
|
||||
return q.Equals("manager_id", s.ManagerId)
|
||||
}
|
||||
return q
|
||||
})
|
||||
if err == nil {
|
||||
_, err = db.Update(self, func() error {
|
||||
self.StorageId = storage.GetId()
|
||||
@@ -1407,7 +1433,7 @@ func (self *SDisk) syncRemoveCloudDisk(ctx context.Context, userCred mcclient.To
|
||||
return self.RealDelete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (self *SDisk) syncWithCloudDisk(ctx context.Context, userCred mcclient.TokenCredential, provider cloudprovider.ICloudProvider, extDisk cloudprovider.ICloudDisk, index int, syncOwnerId mcclient.IIdentityProvider) error {
|
||||
func (self *SDisk) syncWithCloudDisk(ctx context.Context, userCred mcclient.TokenCredential, provider cloudprovider.ICloudProvider, extDisk cloudprovider.ICloudDisk, index int, syncOwnerId mcclient.IIdentityProvider, managerId string) error {
|
||||
recycle := false
|
||||
guests := self.GetGuests()
|
||||
if provider.GetFactory().IsSupportPrepaidResources() && len(guests) == 1 && guests[0].IsPrepaidRecycle() {
|
||||
|
||||
@@ -472,7 +472,7 @@ func (manager *SElasticcacheManager) SyncElasticcaches(ctx context.Context, user
|
||||
syncResult.UpdateError(err)
|
||||
continue
|
||||
}
|
||||
syncMetadata(ctx, userCred, &commondb[i], commonext[i])
|
||||
syncVirtualResourceMetadata(ctx, userCred, &commondb[i], commonext[i])
|
||||
localElasticcaches = append(localElasticcaches, commondb[i])
|
||||
remoteElasticcaches = append(remoteElasticcaches, commonext[i])
|
||||
syncResult.Update()
|
||||
@@ -484,7 +484,7 @@ func (manager *SElasticcacheManager) SyncElasticcaches(ctx context.Context, user
|
||||
syncResult.AddError(err)
|
||||
continue
|
||||
}
|
||||
syncMetadata(ctx, userCred, instance, added[i])
|
||||
syncVirtualResourceMetadata(ctx, userCred, instance, added[i])
|
||||
localElasticcaches = append(localElasticcaches, *instance)
|
||||
remoteElasticcaches = append(remoteElasticcaches, added[i])
|
||||
syncResult.Add()
|
||||
@@ -496,9 +496,12 @@ func (self *SElasticcache) syncRemoveCloudElasticcache(ctx context.Context, user
|
||||
lockman.LockObject(ctx, self)
|
||||
defer lockman.ReleaseObject(ctx, self)
|
||||
|
||||
self.DeletePreventionOff(self, userCred)
|
||||
|
||||
err := self.ValidateDeleteCondition(ctx)
|
||||
if err != nil {
|
||||
return self.SetStatus(userCred, api.ELASTIC_CACHE_STATUS_ERROR, "sync to delete")
|
||||
self.SetStatus(userCred, api.ELASTIC_CACHE_STATUS_ERROR, "sync to delete")
|
||||
return errors.Wrap(err, "ValidateDeleteCondition")
|
||||
}
|
||||
return self.Delete(ctx, userCred)
|
||||
}
|
||||
@@ -559,7 +562,6 @@ func (manager *SElasticcacheManager) newFromCloudElasticcache(ctx context.Contex
|
||||
instance.Engine = extInstance.GetEngine()
|
||||
instance.EngineVersion = extInstance.GetEngineVersion()
|
||||
|
||||
instance.NetworkType = extInstance.GetNetworkType()
|
||||
instance.PrivateDNS = extInstance.GetPrivateDNS()
|
||||
instance.PrivateIpAddr = extInstance.GetPrivateIpAddr()
|
||||
instance.PrivateConnectPort = extInstance.GetPrivateConnectPort()
|
||||
@@ -570,28 +572,57 @@ func (manager *SElasticcacheManager) newFromCloudElasticcache(ctx context.Contex
|
||||
instance.MaintainEndTime = extInstance.GetMaintainEndTime()
|
||||
instance.AuthMode = extInstance.GetAuthMode()
|
||||
|
||||
var zone *SZone
|
||||
if zoneId := extInstance.GetZoneId(); len(zoneId) > 0 {
|
||||
zone, err := db.FetchByExternalId(ZoneManager, zoneId)
|
||||
_zone, err := db.FetchByExternalId(ZoneManager, zoneId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "newFromCloudElasticcache.FetchZoneId")
|
||||
}
|
||||
instance.ZoneId = zone.GetId()
|
||||
instance.ZoneId = _zone.GetId()
|
||||
zone = _zone.(*SZone)
|
||||
}
|
||||
|
||||
if vpcId := extInstance.GetVpcId(); len(vpcId) > 0 {
|
||||
vpc, err := db.FetchByExternalId(VpcManager, vpcId)
|
||||
instance.NetworkType = extInstance.GetNetworkType()
|
||||
if instance.NetworkType == api.LB_NETWORK_TYPE_CLASSIC {
|
||||
vpc, err := VpcManager.GetOrCreateVpcForClassicNetwork(region)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "newFromCloudElasticcache.FetchVpcId")
|
||||
return nil, errors.Wrap(err, "NewVpcForClassicNetwork")
|
||||
}
|
||||
instance.VpcId = vpc.GetId()
|
||||
}
|
||||
|
||||
if networkId := extInstance.GetNetworkId(); len(networkId) > 0 {
|
||||
network, err := db.FetchByExternalId(NetworkManager, networkId)
|
||||
wire, err := WireManager.GetOrCreateWireForClassicNetwork(vpc, zone)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "newFromCloudElasticcache.FetchNetworkId")
|
||||
return nil, errors.Wrap(err, "NewWireForClassicNetwork")
|
||||
}
|
||||
network, err := NetworkManager.GetOrCreateClassicNetwork(wire)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetOrCreateClassicNetwork")
|
||||
}
|
||||
instance.NetworkId = network.GetId()
|
||||
} else {
|
||||
if vpcId := extInstance.GetVpcId(); len(vpcId) > 0 {
|
||||
vpc, err := db.FetchByExternalIdAndManagerId(VpcManager, vpcId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", provider.Id)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "newFromCloudElasticcache.FetchVpcId")
|
||||
}
|
||||
instance.VpcId = vpc.GetId()
|
||||
}
|
||||
|
||||
if networkId := extInstance.GetNetworkId(); len(networkId) > 0 {
|
||||
network, err := db.FetchByExternalIdAndManagerId(NetworkManager, networkId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
wire := WireManager.Query().SubQuery()
|
||||
vpc := VpcManager.Query().SubQuery()
|
||||
return q.Join(wire, sqlchemy.Equals(wire.Field("id"), q.Field("wire_id"))).
|
||||
Join(vpc, sqlchemy.Equals(vpc.Field("id"), wire.Field("vpc_id"))).
|
||||
Filter(sqlchemy.Equals(vpc.Field("manager_id"), provider.Id))
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "newFromCloudElasticcache.FetchNetworkId")
|
||||
}
|
||||
instance.NetworkId = network.GetId()
|
||||
}
|
||||
}
|
||||
|
||||
if createdAt := extInstance.GetCreatedAt(); !createdAt.IsZero() {
|
||||
|
||||
@@ -448,6 +448,8 @@ func (self *SElasticcacheSku) syncWithCloudSku(ctx context.Context, userCred mcc
|
||||
_, err := db.Update(self, func() error {
|
||||
self.PrepaidStatus = extSku.PrepaidStatus
|
||||
self.PostpaidStatus = extSku.PostpaidStatus
|
||||
self.ZoneId = extSku.ZoneId
|
||||
self.SlaveZoneId = extSku.SlaveZoneId
|
||||
return nil
|
||||
})
|
||||
return err
|
||||
|
||||
@@ -156,6 +156,8 @@ func (manager *SElasticipManager) ListItemFilter(
|
||||
sq := networks.Query(networks.Field("id")).Join(wires, sqlchemy.Equals(wires.Field("id"), networks.Field("wire_id"))).
|
||||
Filter(sqlchemy.Equals(wires.Field("zone_id"), zone.Id)).SubQuery()
|
||||
q = q.Filter(sqlchemy.In(q.Field("network_id"), sq))
|
||||
gns := GuestnetworkManager.Query("network_id").Equals("guest_id", guest.Id).SubQuery()
|
||||
q = q.Filter(sqlchemy.NotIn(q.Field("network_id"), gns))
|
||||
} else {
|
||||
region := guest.getRegion()
|
||||
q = q.Equals("cloudregion_id", region.Id)
|
||||
@@ -358,7 +360,7 @@ func (manager *SElasticipManager) SyncEips(ctx context.Context, userCred mcclien
|
||||
if err != nil {
|
||||
syncResult.UpdateError(err)
|
||||
} else {
|
||||
syncMetadata(ctx, userCred, &commondb[i], commonext[i])
|
||||
syncVirtualResourceMetadata(ctx, userCred, &commondb[i], commonext[i])
|
||||
syncResult.Update()
|
||||
}
|
||||
}
|
||||
@@ -367,7 +369,7 @@ func (manager *SElasticipManager) SyncEips(ctx context.Context, userCred mcclien
|
||||
if err != nil {
|
||||
syncResult.AddError(err)
|
||||
} else {
|
||||
syncMetadata(ctx, userCred, new, added[i])
|
||||
syncVirtualResourceMetadata(ctx, userCred, new, added[i])
|
||||
syncResult.Add()
|
||||
}
|
||||
}
|
||||
@@ -414,7 +416,16 @@ func (self *SElasticip) SyncInstanceWithCloudEip(ctx context.Context, userCred m
|
||||
return errors.Error("unsupported association type")
|
||||
}
|
||||
|
||||
extRes, err := db.FetchByExternalId(manager, vmExtId)
|
||||
extRes, err := db.FetchByExternalIdAndManagerId(manager, vmExtId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
switch ext.GetAssociationType() {
|
||||
case api.EIP_ASSOCIATE_TYPE_SERVER:
|
||||
sq := HostManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("host_id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), self.ManagerId))
|
||||
case api.EIP_ASSOCIATE_TYPE_NAT_GATEWAY, api.EIP_ASSOCIATE_TYPE_LOADBALANCER:
|
||||
return q.Equals("manager_id", self.ManagerId)
|
||||
}
|
||||
return q
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("fail to find vm by external ID %s", vmExtId)
|
||||
return err
|
||||
@@ -501,7 +512,13 @@ func (manager *SElasticipManager) newFromCloudEip(ctx context.Context, userCred
|
||||
eip.CloudregionId = region.Id
|
||||
eip.ChargeType = extEip.GetInternetChargeType()
|
||||
if networkId := extEip.GetINetworkId(); len(networkId) > 0 {
|
||||
network, err := db.FetchByExternalId(NetworkManager, networkId)
|
||||
network, err := db.FetchByExternalIdAndManagerId(NetworkManager, networkId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
wire := WireManager.Query().SubQuery()
|
||||
vpc := VpcManager.Query().SubQuery()
|
||||
return q.Join(wire, sqlchemy.Equals(wire.Field("id"), q.Field("wire_id"))).
|
||||
Join(vpc, sqlchemy.Equals(vpc.Field("id"), wire.Field("vpc_id"))).
|
||||
Filter(sqlchemy.Equals(vpc.Field("manager_id"), provider.Id))
|
||||
})
|
||||
if err != nil {
|
||||
msg := fmt.Sprintf("failed to found network by externalId %s error: %v", networkId, err)
|
||||
log.Errorf(msg)
|
||||
@@ -759,7 +776,9 @@ func (self *SElasticip) AssociateNatGateway(ctx context.Context, userCred mcclie
|
||||
}
|
||||
|
||||
func (manager *SElasticipManager) getEipByExtEip(ctx context.Context, userCred mcclient.TokenCredential, extEip cloudprovider.ICloudEIP, provider *SCloudprovider, region *SCloudregion, syncOwnerId mcclient.IIdentityProvider) (*SElasticip, error) {
|
||||
eipObj, err := db.FetchByExternalId(manager, extEip.GetGlobalId())
|
||||
eipObj, err := db.FetchByExternalIdAndManagerId(manager, extEip.GetGlobalId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", provider.Id)
|
||||
})
|
||||
if err == nil {
|
||||
return eipObj.(*SElasticip), nil
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -35,8 +36,7 @@ import (
|
||||
)
|
||||
|
||||
type SExternalProjectManager struct {
|
||||
db.SStandaloneResourceBaseManager
|
||||
db.SProjectizedResourceBaseManager
|
||||
db.SVirtualResourceBaseManager
|
||||
db.SExternalizedResourceBaseManager
|
||||
SManagedResourceBaseManager
|
||||
}
|
||||
@@ -45,7 +45,7 @@ var ExternalProjectManager *SExternalProjectManager
|
||||
|
||||
func init() {
|
||||
ExternalProjectManager = &SExternalProjectManager{
|
||||
SStandaloneResourceBaseManager: db.NewStandaloneResourceBaseManager(
|
||||
SVirtualResourceBaseManager: db.NewVirtualResourceBaseManager(
|
||||
SExternalProject{},
|
||||
"externalprojects_tbl",
|
||||
"externalproject",
|
||||
@@ -56,34 +56,22 @@ func init() {
|
||||
}
|
||||
|
||||
type SExternalProject struct {
|
||||
db.SStandaloneResourceBase
|
||||
db.SProjectizedResourceBase
|
||||
db.SVirtualResourceBase
|
||||
db.SExternalizedResourceBase
|
||||
SManagedResourceBase
|
||||
|
||||
// 归属云账号ID
|
||||
CloudaccountId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
|
||||
}
|
||||
|
||||
func (manager *SExternalProjectManager) AllowListItems(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
|
||||
return db.IsAdminAllowList(userCred, manager)
|
||||
return db.IsDomainAllowList(userCred, manager)
|
||||
}
|
||||
|
||||
func (self *SExternalProject) AllowUpdateItem(ctx context.Context, userCred mcclient.TokenCredential) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (manager *SExternalProjectManager) getProjectsByProviderId(providerId string) ([]SExternalProject, error) {
|
||||
projects := []SExternalProject{}
|
||||
err := fetchByManagerId(manager, providerId, &projects)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return projects, nil
|
||||
}
|
||||
|
||||
func (self *SExternalProject) getCloudProviderInfo() SCloudProviderInfo {
|
||||
provider := self.GetCloudprovider()
|
||||
return MakeCloudProviderInfo(nil, nil, provider)
|
||||
}
|
||||
|
||||
func (self *SExternalProject) GetExtraDetails(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
@@ -102,16 +90,28 @@ func (manager *SExternalProjectManager) FetchCustomizeColumns(
|
||||
isList bool,
|
||||
) []api.ExternalProjectDetails {
|
||||
rows := make([]api.ExternalProjectDetails, len(objs))
|
||||
|
||||
stdRows := manager.SStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
manRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
projRows := manager.SProjectizedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
|
||||
virRows := manager.SVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
accountIds := make([]string, len(objs))
|
||||
for i := range rows {
|
||||
rows[i] = api.ExternalProjectDetails{
|
||||
StandaloneResourceDetails: stdRows[i],
|
||||
ManagedResourceInfo: manRows[i],
|
||||
ProjectizedResourceInfo: projRows[i],
|
||||
VirtualResourceDetails: virRows[i],
|
||||
}
|
||||
proj := objs[i].(*SExternalProject)
|
||||
accountIds[i] = proj.CloudaccountId
|
||||
}
|
||||
accounts := make(map[string]SCloudaccount)
|
||||
err := db.FetchStandaloneObjectsByIds(CloudaccountManager, accountIds, &accounts)
|
||||
if err != nil {
|
||||
log.Errorf("FetchStandaloneObjectsByIds (%s) fail %s",
|
||||
CloudaccountManager.KeywordPlural(), err)
|
||||
return rows
|
||||
}
|
||||
|
||||
for i := range rows {
|
||||
if account, ok := accounts[accountIds[i]]; ok {
|
||||
rows[i].Account = account.Name
|
||||
rows[i].Brand = account.Brand
|
||||
rows[i].Provider = account.Provider
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,8 @@ func (manager *SExternalProjectManager) FetchCustomizeColumns(
|
||||
func (manager *SExternalProjectManager) GetProject(externalId string, providerId string) (*SExternalProject, error) {
|
||||
project := &SExternalProject{}
|
||||
project.SetModelManager(manager, project)
|
||||
q := manager.Query().Equals("external_id", externalId).Equals("manager_id", providerId)
|
||||
sq := CloudproviderManager.Query("cloudaccount_id").Equals("id", providerId)
|
||||
q := manager.Query().Equals("external_id", externalId).Equals("cloudaccount_id", sq.SubQuery())
|
||||
count, err := q.CountWithError()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -135,13 +136,13 @@ func (manager *SExternalProjectManager) GetProject(externalId string, providerId
|
||||
return project, q.First(project)
|
||||
}
|
||||
|
||||
func (manager *SExternalProjectManager) SyncProjects(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, projects []cloudprovider.ICloudProject) compare.SyncResult {
|
||||
func (manager *SExternalProjectManager) SyncProjects(ctx context.Context, userCred mcclient.TokenCredential, account *SCloudaccount, projects []cloudprovider.ICloudProject) compare.SyncResult {
|
||||
lockman.LockClass(ctx, manager, db.GetLockClassKey(manager, userCred))
|
||||
defer lockman.ReleaseClass(ctx, manager, db.GetLockClassKey(manager, userCred))
|
||||
|
||||
syncResult := compare.SyncResult{}
|
||||
|
||||
dbProjects, err := manager.getProjectsByProviderId(provider.Id)
|
||||
dbProjects, err := account.GetExternalProjects()
|
||||
if err != nil {
|
||||
syncResult.Error(err)
|
||||
return syncResult
|
||||
@@ -167,7 +168,7 @@ func (manager *SExternalProjectManager) SyncProjects(ctx context.Context, userCr
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(commondb); i++ {
|
||||
err = commondb[i].SyncWithCloudProject(ctx, userCred, provider, commonext[i])
|
||||
err = commondb[i].SyncWithCloudProject(ctx, userCred, account, commonext[i])
|
||||
if err != nil {
|
||||
syncResult.UpdateError(err)
|
||||
} else {
|
||||
@@ -175,7 +176,7 @@ func (manager *SExternalProjectManager) SyncProjects(ctx context.Context, userCr
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(added); i++ {
|
||||
_, err := manager.newFromCloudProject(ctx, userCred, provider, added[i])
|
||||
_, err := manager.newFromCloudProject(ctx, userCred, account, nil, added[i])
|
||||
if err != nil {
|
||||
syncResult.AddError(err)
|
||||
} else {
|
||||
@@ -192,13 +193,14 @@ func (self *SExternalProject) syncRemoveCloudProject(ctx context.Context, userCr
|
||||
return self.Delete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (self *SExternalProject) SyncWithCloudProject(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudProject) error {
|
||||
func (self *SExternalProject) SyncWithCloudProject(ctx context.Context, userCred mcclient.TokenCredential, account *SCloudaccount, ext cloudprovider.ICloudProject) error {
|
||||
diff, err := db.UpdateWithLock(ctx, self, func() error {
|
||||
self.Name = ext.GetName()
|
||||
self.IsEmulated = ext.IsEmulated()
|
||||
if self.DomainId != provider.DomainId {
|
||||
self.ProjectId = provider.ProjectId
|
||||
self.DomainId = provider.DomainId
|
||||
self.Status = ext.GetStatus()
|
||||
if self.DomainId != account.DomainId {
|
||||
self.ProjectId = account.ProjectId
|
||||
self.DomainId = account.DomainId
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@@ -210,20 +212,23 @@ func (self *SExternalProject) SyncWithCloudProject(ctx context.Context, userCred
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SExternalProjectManager) newFromCloudProject(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, extProject cloudprovider.ICloudProject) (*SExternalProject, error) {
|
||||
func (manager *SExternalProjectManager) newFromCloudProject(ctx context.Context, userCred mcclient.TokenCredential, account *SCloudaccount, localProject *db.STenant, extProject cloudprovider.ICloudProject) (*SExternalProject, error) {
|
||||
project := SExternalProject{}
|
||||
project.SetModelManager(manager, &project)
|
||||
|
||||
project.Name = extProject.GetName()
|
||||
project.Status = extProject.GetStatus()
|
||||
project.ExternalId = extProject.GetGlobalId()
|
||||
project.IsEmulated = extProject.IsEmulated()
|
||||
project.ManagerId = provider.Id
|
||||
project.DomainId = provider.DomainId
|
||||
project.ProjectId = provider.ProjectId
|
||||
account := provider.GetCloudaccount()
|
||||
if account != nil && account.AutoCreateProject {
|
||||
project.CloudaccountId = account.Id
|
||||
project.DomainId = account.DomainId
|
||||
project.ProjectId = account.ProjectId
|
||||
if localProject != nil {
|
||||
project.DomainId = localProject.DomainId
|
||||
project.ProjectId = localProject.Id
|
||||
} else if account.AutoCreateProject {
|
||||
desc := fmt.Sprintf("auto create from cloud project %s (%s)", project.Name, project.ExternalId)
|
||||
domainId, projectId, err := getOrCreateTenant(ctx, project.Name, provider.DomainId, "", desc)
|
||||
domainId, projectId, err := getOrCreateTenant(ctx, project.Name, account.DomainId, "", desc)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get or create tenant %s(%s) %v", project.Name, project.ExternalId, err)
|
||||
} else {
|
||||
@@ -303,21 +308,36 @@ func (manager *SExternalProjectManager) ListItemFilter(
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
|
||||
q, err = manager.SStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StandaloneResourceListInput)
|
||||
q, err = manager.SVirtualResourceBaseManager.ListItemFilter(ctx, q, userCred, query.VirtualResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SStandaloneResourceBaseManager.ListItemFilter")
|
||||
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
|
||||
|
||||
if len(query.Cloudprovider) > 0 {
|
||||
p, err := CloudproviderManager.FetchByIdOrName(userCred, query.Cloudprovider)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError2("cloudprovider", query.Cloudprovider)
|
||||
}
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
provider := p.(*SCloudprovider)
|
||||
query.Cloudaccount = provider.CloudaccountId
|
||||
}
|
||||
q, err = manager.SProjectizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ProjectizedResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SProjectizedResourceBaseManager.ListItemFilter")
|
||||
|
||||
if len(query.Cloudaccount) > 0 {
|
||||
account, err := CloudaccountManager.FetchByIdOrName(userCred, query.Cloudaccount)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
return nil, httperrors.NewResourceNotFoundError2("cloudaccount", query.Cloudaccount)
|
||||
}
|
||||
return nil, httperrors.NewGeneralError(err)
|
||||
}
|
||||
q = q.Equals("cloudaccount_id", account.GetId())
|
||||
}
|
||||
|
||||
return q, nil
|
||||
@@ -331,18 +351,14 @@ func (manager *SExternalProjectManager) OrderByExtraFields(
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
|
||||
q, err = manager.SStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StandaloneResourceListInput)
|
||||
q, err = manager.SVirtualResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.VirtualResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SStandaloneResourceBaseManager.OrderByExtraFields")
|
||||
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.OrderByExtraFields")
|
||||
}
|
||||
q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
|
||||
}
|
||||
q, err = manager.SProjectizedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ProjectizedResourceListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SProjectizedResourceBaseManager.OrderByExtraFields")
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
@@ -350,7 +366,7 @@ func (manager *SExternalProjectManager) OrderByExtraFields(
|
||||
func (manager *SExternalProjectManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
|
||||
q, err = manager.SStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
q, err = manager.SVirtualResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
@@ -358,23 +374,35 @@ func (manager *SExternalProjectManager) QueryDistinctExtraField(q *sqlchemy.SQue
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
q, err = manager.SProjectizedResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
|
||||
return q, httperrors.ErrNotFound
|
||||
}
|
||||
|
||||
func (manager *SExternalProjectManager) ListItemExportKeys(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential,
|
||||
keys stringutils2.SSortedStrings) (*sqlchemy.SQuery, error) {
|
||||
q, err := manager.SStandaloneResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
|
||||
q, err := manager.SVirtualResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SStandaloneResourceBaseManager.ListItemExportKeys")
|
||||
}
|
||||
q, err = manager.SProjectizedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SProjectizedResourceBaseManager.ListItemExportKeys")
|
||||
return nil, errors.Wrap(err, "SVirtualResourceBaseManager.ListItemExportKeys")
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SExternalProjectManager) InitializeData() error {
|
||||
eps := []SExternalProject{}
|
||||
q := manager.Query().IsNullOrEmpty("cloudaccount_id")
|
||||
err := db.FetchModelObjects(manager, q, &eps)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range eps {
|
||||
_, err = db.Update(&eps[i], func() error {
|
||||
provider := eps[i].GetCloudprovider()
|
||||
if provider == nil {
|
||||
return fmt.Errorf("failed to get external project %s cloudprovider", eps[i].Id)
|
||||
}
|
||||
eps[i].CloudaccountId = provider.CloudaccountId
|
||||
return nil
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -985,8 +985,11 @@ func (self *SGuest) StartInsertIsoTask(ctx context.Context, imageId string, boot
|
||||
if boot {
|
||||
data.Add(jsonutils.JSONTrue, "boot")
|
||||
}
|
||||
|
||||
task, err := taskman.TaskManager.NewTask(ctx, "GuestInsertIsoTask", self, userCred, data, parentTaskId, "", nil)
|
||||
taskName := "GuestInsertIsoTask"
|
||||
if self.BackupHostId != "" {
|
||||
taskName = "HaGuestInsertIsoTask"
|
||||
}
|
||||
task, err := taskman.TaskManager.NewTask(ctx, taskName, self, userCred, data, parentTaskId, "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1349,6 +1352,10 @@ func (self *SGuest) PerformRebuildRoot(ctx context.Context, userCred mcclient.To
|
||||
if err != nil {
|
||||
return nil, httperrors.NewNotFoundError("failed to find %s", imageId)
|
||||
}
|
||||
err = self.GetDriver().ValidateImage(ctx, img)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
diskCat := self.CategorizeDisks()
|
||||
if img.MinDiskMB == 0 || img.Status != imageapi.IMAGE_STATUS_ACTIVE {
|
||||
return nil, httperrors.NewInputParameterError("invlid image")
|
||||
|
||||
@@ -58,6 +58,7 @@ type IGuestDriver interface {
|
||||
|
||||
GetJsonDescAtHost(ctx context.Context, userCred mcclient.TokenCredential, guest *SGuest, host *SHost) jsonutils.JSONObject
|
||||
|
||||
ValidateImage(ctx context.Context, image *cloudprovider.SImage) error
|
||||
ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, data *api.ServerCreateInput) (*api.ServerCreateInput, error)
|
||||
|
||||
ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error)
|
||||
|
||||
@@ -16,11 +16,9 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
@@ -37,6 +35,7 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/compute/options"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
randutil "yunion.io/x/onecloud/pkg/util/rand"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
@@ -284,17 +283,6 @@ func (manager *SGuestnetworkManager) newGuestNetwork(
|
||||
return &gn, nil
|
||||
}
|
||||
|
||||
func (self *SGuestnetwork) getVirtualRand(width int, randomized bool) string {
|
||||
hash := md5.New()
|
||||
io.WriteString(hash, self.GuestId)
|
||||
io.WriteString(hash, self.NetworkId)
|
||||
if randomized {
|
||||
io.WriteString(hash, fmt.Sprintf("%d", time.Now().Unix()))
|
||||
}
|
||||
hex := fmt.Sprintf("%x", hash.Sum(nil))
|
||||
return hex[:width]
|
||||
}
|
||||
|
||||
func (self *SGuestnetwork) generateIfname(network *SNetwork, virtual bool, randomized bool) string {
|
||||
// It may happen that external networks when synced can miss ifname hint
|
||||
network.ensureIfnameHint()
|
||||
@@ -305,8 +293,7 @@ func (self *SGuestnetwork) generateIfname(network *SNetwork, virtual bool, rando
|
||||
nName = nName[:(MAX_IFNAME_SIZE - 4)]
|
||||
}
|
||||
if virtual {
|
||||
rand := self.getVirtualRand(3, randomized)
|
||||
return fmt.Sprintf("%s-%s", nName, rand)
|
||||
return fmt.Sprintf("%s-%s", nName, randutil.String(3))
|
||||
} else {
|
||||
ip, _ := netutils.NewIPV4Addr(self.IpAddr)
|
||||
cliaddr := ip.CliAddr(network.GuestIpMask)
|
||||
|
||||
@@ -243,18 +243,14 @@ func (manager *SGuestManager) ListItemFilter(
|
||||
q = q.In("host_id", subq.SubQuery())
|
||||
}
|
||||
|
||||
hostFilter := query.Host
|
||||
hostFilter := query.GetAllGuestsOnHost
|
||||
if len(hostFilter) > 0 {
|
||||
host, _ := HostManager.FetchByIdOrName(nil, hostFilter)
|
||||
if host == nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("host %s not found", hostFilter)
|
||||
}
|
||||
if query.GetBackupGuestsOnHost != nil && *query.GetBackupGuestsOnHost {
|
||||
q.Filter(sqlchemy.OR(sqlchemy.Equals(q.Field("host_id"), host.GetId()),
|
||||
sqlchemy.Equals(q.Field("backup_host_id"), host.GetId())))
|
||||
} else {
|
||||
q = q.Equals("host_id", host.GetId())
|
||||
}
|
||||
q.Filter(sqlchemy.OR(sqlchemy.Equals(q.Field("host_id"), host.GetId()),
|
||||
sqlchemy.Equals(q.Field("backup_host_id"), host.GetId())))
|
||||
}
|
||||
|
||||
secgrpFilter := query.Secgroup
|
||||
@@ -771,6 +767,14 @@ func (guest *SGuest) CustomizeCreate(ctx context.Context, userCred mcclient.Toke
|
||||
return guest.SVirtualResourceBase.CustomizeCreate(ctx, userCred, ownerId, query, data)
|
||||
}
|
||||
|
||||
func (guest *SGuest) GetCloudproviderId() string {
|
||||
host := guest.GetHost()
|
||||
if host != nil {
|
||||
return host.GetCloudproviderId()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (guest *SGuest) GetHost() *SHost {
|
||||
if len(guest.HostId) > 0 && regutils.MatchUUID(guest.HostId) {
|
||||
host, _ := HostManager.FetchById(guest.HostId)
|
||||
@@ -2284,7 +2288,13 @@ func (self *SGuest) syncRemoveCloudVM(ctx context.Context, userCred mcclient.Tok
|
||||
iVM, err := iregion.GetIVMById(self.ExternalId)
|
||||
if err == nil { //漂移归位
|
||||
if hostId := iVM.GetIHostId(); len(hostId) > 0 {
|
||||
host, err := db.FetchByExternalId(HostManager, hostId)
|
||||
host, err := db.FetchByExternalIdAndManagerId(HostManager, hostId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
host := self.GetHost()
|
||||
if host != nil {
|
||||
return q.Equals("manager_id", host.ManagerId)
|
||||
}
|
||||
return q
|
||||
})
|
||||
if err == nil {
|
||||
_, err = db.Update(self, func() error {
|
||||
self.HostId = host.GetId()
|
||||
@@ -2692,7 +2702,8 @@ func getCloudNicNetwork(vnic cloudprovider.ICloudNic, host *SHost, ipList []stri
|
||||
vnet := vnic.GetINetwork()
|
||||
if vnet == nil {
|
||||
if vnic.InClassicNetwork() {
|
||||
vpc, err := VpcManager.GetOrCreateVpcForClassicNetwork(host)
|
||||
region := host.GetRegion()
|
||||
vpc, err := VpcManager.GetOrCreateVpcForClassicNetwork(region)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "NewVpcForClassicNetwork")
|
||||
}
|
||||
@@ -2715,7 +2726,13 @@ func getCloudNicNetwork(vnic cloudprovider.ICloudNic, host *SHost, ipList []stri
|
||||
// find network by IP
|
||||
return host.getNetworkOfIPOnHost(ip)
|
||||
}
|
||||
localNetObj, err := db.FetchByExternalId(NetworkManager, vnet.GetGlobalId())
|
||||
localNetObj, err := db.FetchByExternalIdAndManagerId(NetworkManager, vnet.GetGlobalId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
vpc := VpcManager.Query().SubQuery()
|
||||
wire := WireManager.Query().SubQuery()
|
||||
return q.Join(wire, sqlchemy.Equals(q.Field("wire_id"), wire.Field("id"))).
|
||||
Join(vpc, sqlchemy.Equals(wire.Field("vpc_id"), vpc.Field("id"))).
|
||||
Filter(sqlchemy.Equals(vpc.Field("manager_id"), host.ManagerId))
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Cannot find network of external_id %s: %v", vnet.GetGlobalId(), err)
|
||||
}
|
||||
@@ -2915,7 +2932,7 @@ func (self *SGuest) SyncVMDisks(ctx context.Context, userCred mcclient.TokenCred
|
||||
if len(vdisks[i].GetGlobalId()) == 0 {
|
||||
continue
|
||||
}
|
||||
disk, err := DiskManager.syncCloudDisk(ctx, userCred, provider, vdisks[i], i, syncOwnerId)
|
||||
disk, err := DiskManager.syncCloudDisk(ctx, userCred, provider, vdisks[i], i, syncOwnerId, host.ManagerId)
|
||||
if err != nil {
|
||||
log.Errorf("syncCloudDisk error: %v", err)
|
||||
result.Error(err)
|
||||
@@ -5271,7 +5288,9 @@ func (guest *SGuest) GetUsages() []db.IUsage {
|
||||
}
|
||||
|
||||
var (
|
||||
serverNameREG = regexp.MustCompile(`^[a-z$][a-z0-9-${}.]*$`)
|
||||
// `^[a-zA-Z][a-zA-Z0-9._@-]*$`)
|
||||
serverNameREG = regexp.MustCompile(`^[a-zA-Z$][a-zA-Z0-9-${}.]*$`)
|
||||
hostnameREG = regexp.MustCompile(`^[a-z$][a-z0-9-${}.]*$`)
|
||||
)
|
||||
|
||||
func (manager *SGuestManager) ValidateName(name string) error {
|
||||
@@ -5280,3 +5299,10 @@ func (manager *SGuestManager) ValidateName(name string) error {
|
||||
}
|
||||
return httperrors.NewInputParameterError("name starts with letter, and contains letter, number and - only")
|
||||
}
|
||||
|
||||
func (manager *SGuestManager) ValidateNameLoginAccount(name string) error {
|
||||
if hostnameREG.MatchString(name) {
|
||||
return nil
|
||||
}
|
||||
return httperrors.NewInputParameterError("name starts with letter, and contains letter, number and - only")
|
||||
}
|
||||
|
||||
@@ -686,7 +686,7 @@ func (host *SHost) RebuildRecycledGuest(ctx context.Context, userCred mcclient.T
|
||||
log.Errorf("disk.SetExternalId fail %s", err)
|
||||
return err
|
||||
}
|
||||
err = disk.syncWithCloudDisk(ctx, userCred, iprovider, idisks[i], i, guest.GetOwnerId())
|
||||
err = disk.syncWithCloudDisk(ctx, userCred, iprovider, idisks[i], i, guest.GetOwnerId(), host.ManagerId)
|
||||
if err != nil {
|
||||
log.Errorf("disk.syncWithCloudDisk fail %s", err)
|
||||
return err
|
||||
|
||||
@@ -84,7 +84,7 @@ func init() {
|
||||
type SHost struct {
|
||||
db.SEnabledStatusInfrasResourceBase
|
||||
db.SExternalizedResourceBase
|
||||
SZoneResourceBase
|
||||
SZoneResourceBase `update:""`
|
||||
SManagedResourceBase
|
||||
SBillingResourceBase
|
||||
|
||||
@@ -1893,7 +1893,9 @@ func (self *SHost) Attach2Storage(ctx context.Context, userCred mcclient.TokenCr
|
||||
}
|
||||
|
||||
func (self *SHost) newCloudHostStorage(ctx context.Context, userCred mcclient.TokenCredential, extStorage cloudprovider.ICloudStorage, provider *SCloudprovider) (*SStorage, error) {
|
||||
storageObj, err := db.FetchByExternalId(StorageManager, extStorage.GetGlobalId())
|
||||
storageObj, err := db.FetchByExternalIdAndManagerId(StorageManager, extStorage.GetGlobalId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", provider.Id)
|
||||
})
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
// no cloud storage found, this may happen for on-premise host
|
||||
@@ -2008,7 +2010,10 @@ func (self *SHost) Attach2Wire(ctx context.Context, userCred mcclient.TokenCrede
|
||||
}
|
||||
|
||||
func (self *SHost) newCloudHostWire(ctx context.Context, userCred mcclient.TokenCredential, extWire cloudprovider.ICloudWire) error {
|
||||
wireObj, err := db.FetchByExternalId(WireManager, extWire.GetGlobalId())
|
||||
wireObj, err := db.FetchByExternalIdAndManagerId(WireManager, extWire.GetGlobalId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
sq := VpcManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("vpc_id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), self.ManagerId))
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("%s", err)
|
||||
return nil
|
||||
@@ -2076,7 +2081,10 @@ func (self *SHost) SyncHostVMs(ctx context.Context, userCred mcclient.TokenCrede
|
||||
}
|
||||
|
||||
for i := 0; i < len(added); i += 1 {
|
||||
vm, err := db.FetchByExternalId(GuestManager, added[i].GetGlobalId())
|
||||
vm, err := db.FetchByExternalIdAndManagerId(GuestManager, added[i].GetGlobalId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
sq := HostManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("host_id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), self.ManagerId))
|
||||
})
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
log.Errorf("failed to found guest by externalId %s error: %v", added[i].GetGlobalId(), err)
|
||||
continue
|
||||
@@ -2088,7 +2096,9 @@ func (self *SHost) SyncHostVMs(ctx context.Context, userCred mcclient.TokenCrede
|
||||
log.Errorf("failed to found ihost from vm %s", added[i].GetGlobalId())
|
||||
continue
|
||||
}
|
||||
_host, err := db.FetchByExternalId(HostManager, ihost.GetGlobalId())
|
||||
_host, err := db.FetchByExternalIdAndManagerId(HostManager, ihost.GetGlobalId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", self.ManagerId)
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("failed to found host by externalId %s", ihost.GetGlobalId())
|
||||
continue
|
||||
@@ -2604,6 +2614,10 @@ func (self *SHost) getMoreDetails(ctx context.Context, out api.HostDetails, show
|
||||
if self.EnableHealthCheck && hostHealthChecker != nil {
|
||||
out.AllowHealthCheck = true
|
||||
}
|
||||
if self.GetMetadata("__auto_migrate_on_host_down", nil) == "enable" {
|
||||
out.AutoMigrateOnHostDown = true
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ func InitDB() error {
|
||||
DynamicschedtagManager,
|
||||
ServerSkuManager,
|
||||
ElasticcacheSkuManager,
|
||||
ExternalProjectManager,
|
||||
} {
|
||||
err := manager.InitializeData()
|
||||
if err != nil {
|
||||
|
||||
@@ -544,6 +544,9 @@ func (man *SLoadbalancerAgentManager) CleanPendingDeleteLoadbalancers(ctx contex
|
||||
}
|
||||
|
||||
func (lbagent *SLoadbalancerAgent) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
if data.Contains("cluster_id") {
|
||||
data.Remove("cluster_id")
|
||||
}
|
||||
{
|
||||
keyV := map[string]validators.IValidator{
|
||||
"hb_timeout": validators.NewNonNegativeValidator("hb_timeout").Optional(true),
|
||||
|
||||
@@ -114,6 +114,8 @@ func (lbagent *SLoadbalancerAgent) deploy(ctx context.Context, userCred mcclient
|
||||
}
|
||||
switch input.DeployMethod {
|
||||
case compute_apis.DeployMethodYum:
|
||||
fallthrough
|
||||
default:
|
||||
if v, ok := input.Host.GetVar("repo_base_url"); !ok || v == "" {
|
||||
return nil, httperrors.NewBadRequestError("use yum requires valid repo_base_url")
|
||||
}
|
||||
@@ -142,8 +144,6 @@ func (lbagent *SLoadbalancerAgent) deploy(ctx context.Context, userCred mcclient
|
||||
},
|
||||
)
|
||||
case compute_apis.DeployMethodCopy:
|
||||
fallthrough
|
||||
default:
|
||||
// glob for rpms
|
||||
basenames := []string{
|
||||
"packages/telegraf",
|
||||
@@ -275,6 +275,22 @@ func (lbagent *SLoadbalancerAgent) validateHost(ctx context.Context, userCred mc
|
||||
if utils.IsInStringArray(guest.Hypervisor, compute_apis.PUBLIC_CLOUD_HYPERVISORS) {
|
||||
return httperrors.NewBadRequestError("lbagent cannot be deployed on public guests")
|
||||
}
|
||||
if guest.Status != compute_apis.VM_RUNNING {
|
||||
return httperrors.NewBadRequestError("server is in %q state, want %q",
|
||||
guest.Status, compute_apis.VM_RUNNING)
|
||||
}
|
||||
|
||||
// Better make this explicit in the API
|
||||
if guest.SrcIpCheck.Bool() || guest.SrcMacCheck.Bool() {
|
||||
sess := auth.GetSession(ctx, userCred, "", "")
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("src_ip_check", jsonutils.JSONFalse)
|
||||
params.Set("src_mac_check", jsonutils.JSONFalse)
|
||||
_, err := mcclient_modules.Servers.PerformAction(sess, guest.Id, "modify-src-check", params)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "turn off src check of guest %s(%s)", guest.Name, guest.Id)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
@@ -194,7 +195,10 @@ func (lbb *SAwsCachedLb) syncRemoveCloudLoadbalancerBackend(ctx context.Context,
|
||||
func (lbb *SAwsCachedLb) constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend cloudprovider.ICloudLoadbalancerBackend) error {
|
||||
lbb.Status = extLoadbalancerBackend.GetStatus()
|
||||
|
||||
instance, err := db.FetchByExternalId(GuestManager, extLoadbalancerBackend.GetBackendId())
|
||||
instance, err := db.FetchByExternalIdAndManagerId(GuestManager, extLoadbalancerBackend.GetBackendId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
sq := HostManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(q.Field("host_id"), sq.Field("id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), lbb.ManagerId))
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -232,7 +232,9 @@ func (man *SAwsCachedLbbgManager) SyncLoadbalancerBackendgroups(ctx context.Cont
|
||||
var elb *SLoadbalancer
|
||||
elbId := commonext[i].GetLoadbalancerId()
|
||||
if len(elbId) > 0 {
|
||||
ielb, err := db.FetchByExternalId(LoadbalancerManager, elbId)
|
||||
ielb, err := db.FetchByExternalIdAndManagerId(LoadbalancerManager, elbId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", provider.Id)
|
||||
})
|
||||
if err == nil {
|
||||
elb = ielb.(*SLoadbalancer)
|
||||
}
|
||||
|
||||
@@ -264,6 +264,14 @@ func (lbb *SLoadbalancerBackend) AllowPerformStatus(ctx context.Context, userCre
|
||||
return false
|
||||
}
|
||||
|
||||
func (lbb *SLoadbalancerBackend) GetCloudproviderId() string {
|
||||
lbbg := lbb.GetLoadbalancerBackendGroup()
|
||||
if lbbg != nil {
|
||||
return lbbg.GetCloudproviderId()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (lbb *SLoadbalancerBackend) GetLoadbalancerBackendGroup() *SLoadbalancerBackendGroup {
|
||||
backendgroup, err := LoadbalancerBackendGroupManager.FetchById(lbb.BackendGroupId)
|
||||
if err != nil {
|
||||
@@ -514,7 +522,7 @@ func (man *SLoadbalancerBackendManager) SyncLoadbalancerBackends(ctx context.Con
|
||||
return syncResult
|
||||
}
|
||||
|
||||
func (lbb *SLoadbalancerBackend) constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend cloudprovider.ICloudLoadbalancerBackend) error {
|
||||
func (lbb *SLoadbalancerBackend) constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend cloudprovider.ICloudLoadbalancerBackend, managerId string) error {
|
||||
// lbb.Name = extLoadbalancerBackend.GetName()
|
||||
lbb.Status = extLoadbalancerBackend.GetStatus()
|
||||
|
||||
@@ -524,7 +532,10 @@ func (lbb *SLoadbalancerBackend) constructFieldsFromCloudLoadbalancerBackend(ext
|
||||
lbb.BackendType = extLoadbalancerBackend.GetBackendType()
|
||||
lbb.BackendRole = extLoadbalancerBackend.GetBackendRole()
|
||||
|
||||
instance, err := db.FetchByExternalId(GuestManager, extLoadbalancerBackend.GetBackendId())
|
||||
instance, err := db.FetchByExternalIdAndManagerId(GuestManager, extLoadbalancerBackend.GetBackendId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
sq := HostManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("host_id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), managerId))
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -555,7 +566,7 @@ func (lbb *SLoadbalancerBackend) syncRemoveCloudLoadbalancerBackend(ctx context.
|
||||
|
||||
func (lbb *SLoadbalancerBackend) SyncWithCloudLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, extLoadbalancerBackend cloudprovider.ICloudLoadbalancerBackend, syncOwnerId mcclient.IIdentityProvider, provider *SCloudprovider) error {
|
||||
diff, err := db.UpdateWithLock(ctx, lbb, func() error {
|
||||
return lbb.constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend)
|
||||
return lbb.constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend, provider.Id)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -605,7 +616,7 @@ func (man *SLoadbalancerBackendManager) newFromCloudLoadbalancerBackend(ctx cont
|
||||
}
|
||||
lbb.Name = newName
|
||||
|
||||
if err := lbb.constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend); err != nil {
|
||||
if err := lbb.constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend, provider.Id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -324,7 +324,10 @@ func (acl *SCachedLoadbalancerAcl) SyncWithCloudLoadbalancerAcl(ctx context.Cont
|
||||
} else {
|
||||
ext_listener_id := extAcl.GetAclListenerID()
|
||||
if len(ext_listener_id) > 0 {
|
||||
ilistener, err := db.FetchByExternalId(LoadbalancerListenerManager, ext_listener_id)
|
||||
ilistener, err := db.FetchByExternalIdAndManagerId(LoadbalancerListenerManager, ext_listener_id, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
sq := LoadbalancerManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("loadbalancer_id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), acl.ManagerId))
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cacheLoadbalancerAcl.sync.FetchByExternalId")
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
|
||||
type SLoadbalancerClusterResourceBase struct {
|
||||
// 归属LB集群
|
||||
ClusterId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" json:"cluster_id"`
|
||||
ClusterId string `width:"36" charset:"ascii" nullable:"false" list:"user" update:"user" create:"optional" json:"cluster_id"`
|
||||
}
|
||||
|
||||
type SLoadbalancerClusterResourceBaseManager struct {
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
@@ -197,7 +198,10 @@ func (lbb *SHuaweiCachedLb) syncRemoveCloudLoadbalancerBackend(ctx context.Conte
|
||||
func (lbb *SHuaweiCachedLb) constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend cloudprovider.ICloudLoadbalancerBackend) error {
|
||||
lbb.Status = extLoadbalancerBackend.GetStatus()
|
||||
|
||||
instance, err := db.FetchByExternalId(GuestManager, extLoadbalancerBackend.GetBackendId())
|
||||
instance, err := db.FetchByExternalIdAndManagerId(GuestManager, extLoadbalancerBackend.GetBackendId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
sq := HostManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("host_id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), lbb.ManagerId))
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -286,17 +290,6 @@ func (man *SHuaweiCachedLbManager) newFromCloudLoadbalancerBackend(ctx context.C
|
||||
}
|
||||
|
||||
func newLocalBackendFromCloudLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, loadbalancerBackendgroup *SLoadbalancerBackendGroup, extLoadbalancerBackend cloudprovider.ICloudLoadbalancerBackend, syncOwnerId mcclient.IIdentityProvider) (*SLoadbalancerBackend, error) {
|
||||
instance, err := db.FetchByExternalId(GuestManager, extLoadbalancerBackend.GetBackendId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
guest := instance.(*SGuest)
|
||||
//address, err := LoadbalancerBackendManager.GetGuestAddress(guest)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
lbbgRegion := loadbalancerBackendgroup.GetRegion()
|
||||
if lbbgRegion == nil {
|
||||
return nil, errors.Wrap(httperrors.ErrInvalidStatus, "loadbalancerBackendgroup is not attached to any region")
|
||||
@@ -306,6 +299,17 @@ func newLocalBackendFromCloudLoadbalancerBackend(ctx context.Context, userCred m
|
||||
return nil, errors.Wrap(httperrors.ErrInvalidStatus, "loadbalancerBackendgroup is not attached to any cloudprovider")
|
||||
}
|
||||
|
||||
instance, err := db.FetchByExternalIdAndManagerId(GuestManager, extLoadbalancerBackend.GetBackendId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
sq := HostManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("host_id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), lbbgProvider.Id))
|
||||
})
|
||||
|
||||
guest := instance.(*SGuest)
|
||||
//address, err := LoadbalancerBackendManager.GetGuestAddress(guest)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
man := LoadbalancerBackendManager
|
||||
q := man.Query().IsFalse("pending_deleted")
|
||||
q = q.Equals("weight", extLoadbalancerBackend.GetWeight()).Equals("port", extLoadbalancerBackend.GetPort())
|
||||
@@ -350,7 +354,7 @@ func newLocalBackendFromCloudLoadbalancerBackend(ctx context.Context, userCred m
|
||||
}
|
||||
lbb.Name = newName
|
||||
|
||||
if err := lbb.constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend); err != nil {
|
||||
if err := lbb.constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend, lbbgProvider.Id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,14 @@ func (self *SLoadbalancerListenerResourceBase) GetLoadbalancerListener() *SLoadb
|
||||
return listener.(*SLoadbalancerListener)
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerResourceBase) GetCloudproviderId() string {
|
||||
cloudprovider := self.GetCloudprovider()
|
||||
if cloudprovider != nil {
|
||||
return cloudprovider.Id
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SLoadbalancerListenerResourceBase) GetCloudprovider() *SCloudprovider {
|
||||
listener := self.GetLoadbalancerListener()
|
||||
if listener != nil {
|
||||
|
||||
@@ -248,6 +248,9 @@ func (man *SLoadbalancerListenerManager) ListItemFilter(
|
||||
if len(query.Scheduler) > 0 {
|
||||
q = q.In("scheduler", query.Scheduler)
|
||||
}
|
||||
if len(query.Certificate) > 0 {
|
||||
q = q.In("certificate_id", query.Certificate)
|
||||
}
|
||||
if len(query.SendProxy) > 0 {
|
||||
q = q.In("send_proxy", query.SendProxy)
|
||||
}
|
||||
@@ -952,7 +955,9 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(userCred mc
|
||||
|
||||
lblis.AclType = extListener.GetAclType()
|
||||
if aclID := extListener.GetAclId(); len(aclID) > 0 {
|
||||
if _acl, err := db.FetchByExternalId(CachedLoadbalancerAclManager, aclID); err == nil {
|
||||
if _acl, err := db.FetchByExternalIdAndManagerId(CachedLoadbalancerAclManager, aclID, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", lb.ManagerId)
|
||||
}); err == nil {
|
||||
acl := _acl.(*SCachedLoadbalancerAcl)
|
||||
lblis.CachedAclId = acl.GetId()
|
||||
lblis.AclId = acl.AclId
|
||||
@@ -988,7 +993,9 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(userCred mc
|
||||
lblis.TLSCipherPolicy = extListener.GetTLSCipherPolicy()
|
||||
lblis.EnableHttp2 = extListener.HTTP2Enabled()
|
||||
if certificateId := extListener.GetCertificateId(); len(certificateId) > 0 {
|
||||
if _cert, err := db.FetchByExternalId(CachedLoadbalancerCertificateManager, certificateId); err == nil {
|
||||
if _cert, err := db.FetchByExternalIdAndManagerId(CachedLoadbalancerCertificateManager, certificateId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", lb.ManagerId)
|
||||
}); err == nil {
|
||||
cert := _cert.(*SCachedLoadbalancerCertificate)
|
||||
lblis.CachedCertificateId = cert.GetId()
|
||||
lblis.CertificateId = cert.CertificateId
|
||||
@@ -1022,7 +1029,9 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(userCred mc
|
||||
switch lblis.GetProviderName() {
|
||||
case api.CLOUD_PROVIDER_HUAWEI:
|
||||
if len(groupId) > 0 {
|
||||
group, err := db.FetchByExternalId(HuaweiCachedLbbgManager, groupId)
|
||||
group, err := db.FetchByExternalIdAndManagerId(HuaweiCachedLbbgManager, groupId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", lb.ManagerId)
|
||||
})
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
lblis.BackendGroupId = ""
|
||||
@@ -1034,7 +1043,9 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(userCred mc
|
||||
}
|
||||
case api.CLOUD_PROVIDER_AWS:
|
||||
if len(groupId) > 0 {
|
||||
group, err := db.FetchByExternalId(AwsCachedLbbgManager, groupId)
|
||||
group, err := db.FetchByExternalIdAndManagerId(AwsCachedLbbgManager, groupId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", lb.ManagerId)
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("Fetch aws loadbalancer backendgroup by external id %s failed: %s", groupId, err)
|
||||
} else {
|
||||
@@ -1057,7 +1068,9 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(userCred mc
|
||||
lb := lblis.GetLoadbalancer()
|
||||
if forward, _ := lb.LBInfo.Int("Forward"); forward == 1 {
|
||||
// 应用型负载均衡
|
||||
group, err := db.FetchByExternalId(QcloudCachedLbbgManager, groupId)
|
||||
group, err := db.FetchByExternalIdAndManagerId(QcloudCachedLbbgManager, groupId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", lb.ManagerId)
|
||||
})
|
||||
if err != nil {
|
||||
log.Errorf("Fetch qcloud loadbalancer backendgroup by external id %s failed: %s", groupId, err)
|
||||
} else {
|
||||
@@ -1065,7 +1078,10 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(userCred mc
|
||||
}
|
||||
} else {
|
||||
// 传统型负载均衡
|
||||
if group, err := db.FetchByExternalId(LoadbalancerBackendGroupManager, groupId); err == nil {
|
||||
if group, err := db.FetchByExternalIdAndManagerId(LoadbalancerBackendGroupManager, groupId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
sq := LoadbalancerManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("loadbalancer_id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), lb.ManagerId))
|
||||
}); err == nil {
|
||||
lblis.BackendGroupId = group.GetId()
|
||||
}
|
||||
}
|
||||
@@ -1073,13 +1089,16 @@ func (lblis *SLoadbalancerListener) constructFieldsFromCloudListener(userCred mc
|
||||
default:
|
||||
if len(lblis.BackendGroupId) == 0 && len(groupId) == 0 {
|
||||
lblis.BackendGroupId = lb.BackendGroupId
|
||||
} else if group, err := db.FetchByExternalId(LoadbalancerBackendGroupManager, groupId); err == nil {
|
||||
} else if group, err := db.FetchByExternalIdAndManagerId(LoadbalancerBackendGroupManager, groupId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
sq := LoadbalancerManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("loadbalancer_id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), lb.ManagerId))
|
||||
}); err == nil {
|
||||
lblis.BackendGroupId = group.GetId()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (lblis *SLoadbalancerListener) updateCachedLoadbalancerBackendGroupAssociate(ctx context.Context, extListener cloudprovider.ICloudLoadbalancerListener) error {
|
||||
func (lblis *SLoadbalancerListener) updateCachedLoadbalancerBackendGroupAssociate(ctx context.Context, extListener cloudprovider.ICloudLoadbalancerListener, managerId string) error {
|
||||
exteralLbbgId := extListener.GetBackendGroupId()
|
||||
if len(exteralLbbgId) == 0 {
|
||||
return nil
|
||||
@@ -1087,7 +1106,9 @@ func (lblis *SLoadbalancerListener) updateCachedLoadbalancerBackendGroupAssociat
|
||||
|
||||
switch lblis.GetProviderName() {
|
||||
case api.CLOUD_PROVIDER_HUAWEI:
|
||||
_group, err := db.FetchByExternalId(HuaweiCachedLbbgManager, exteralLbbgId)
|
||||
_group, err := db.FetchByExternalIdAndManagerId(HuaweiCachedLbbgManager, exteralLbbgId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", managerId)
|
||||
})
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
lblis.BackendGroupId = ""
|
||||
@@ -1112,7 +1133,9 @@ func (lblis *SLoadbalancerListener) updateCachedLoadbalancerBackendGroupAssociat
|
||||
case api.CLOUD_PROVIDER_QCLOUD:
|
||||
lb := lblis.GetLoadbalancer()
|
||||
if forward, _ := lb.LBInfo.Int("Forward"); forward == 1 {
|
||||
_group, err := db.FetchByExternalId(QcloudCachedLbbgManager, exteralLbbgId)
|
||||
_group, err := db.FetchByExternalIdAndManagerId(QcloudCachedLbbgManager, exteralLbbgId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", managerId)
|
||||
})
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
lblis.BackendGroupId = ""
|
||||
@@ -1164,7 +1187,7 @@ func (lblis *SLoadbalancerListener) SyncWithCloudLoadbalancerListener(ctx contex
|
||||
return err
|
||||
}
|
||||
|
||||
err = lblis.updateCachedLoadbalancerBackendGroupAssociate(ctx, extListener)
|
||||
err = lblis.updateCachedLoadbalancerBackendGroupAssociate(ctx, extListener, lb.ManagerId)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "LoadbalancerListener.SyncWithCloudLoadbalancerListener")
|
||||
}
|
||||
@@ -1196,7 +1219,7 @@ func (man *SLoadbalancerListenerManager) newFromCloudLoadbalancerListener(ctx co
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = lblis.updateCachedLoadbalancerBackendGroupAssociate(ctx, extListener)
|
||||
err = lblis.updateCachedLoadbalancerBackendGroupAssociate(ctx, extListener, lb.ManagerId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "LoadbalancerListener.newFromCloudLoadbalancerListener")
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
@@ -94,7 +95,10 @@ func (lbb *SQcloudCachedLb) syncRemoveCloudLoadbalancerBackend(ctx context.Conte
|
||||
func (lbb *SQcloudCachedLb) constructFieldsFromCloudLoadbalancerBackend(extLoadbalancerBackend cloudprovider.ICloudLoadbalancerBackend) error {
|
||||
lbb.Status = extLoadbalancerBackend.GetStatus()
|
||||
|
||||
instance, err := db.FetchByExternalId(GuestManager, extLoadbalancerBackend.GetBackendId())
|
||||
instance, err := db.FetchByExternalIdAndManagerId(GuestManager, extLoadbalancerBackend.GetBackendId(), func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
sq := HostManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("host_id"))).Filter(sqlchemy.Equals(sq.Field("manager_id"), lbb.ManagerId))
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -53,6 +53,8 @@ type SLoadbalancerManager struct {
|
||||
|
||||
SManagedResourceBaseManager
|
||||
SCloudregionResourceBaseManager
|
||||
|
||||
SLoadbalancerClusterResourceBaseManager
|
||||
}
|
||||
|
||||
var LoadbalancerManager *SLoadbalancerManager
|
||||
@@ -107,8 +109,7 @@ type SLoadbalancer struct {
|
||||
// 虚拟私有网络Id
|
||||
// VpcId string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"`
|
||||
|
||||
// 负载均衡集群Id
|
||||
ClusterId string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional" json:"cluster_id"`
|
||||
SLoadbalancerClusterResourceBase
|
||||
|
||||
// 计费类型
|
||||
ChargeType string `list:"user" get:"user" create:"optional" update:"user" json:"charge_type"`
|
||||
@@ -384,6 +385,10 @@ func (lb *SLoadbalancer) GetRegion() *SCloudregion {
|
||||
return lb.SCloudregionResourceBase.GetRegion()
|
||||
}
|
||||
|
||||
func (lb *SLoadbalancer) GetCloudproviderId() string {
|
||||
return lb.SManagedResourceBase.GetCloudproviderId()
|
||||
}
|
||||
|
||||
func (lb *SLoadbalancer) GetZone() *SZone {
|
||||
return lb.SZoneResourceBase.GetZone()
|
||||
}
|
||||
@@ -548,6 +553,7 @@ func (man *SLoadbalancerManager) FetchCustomizeColumns(
|
||||
) []api.LoadbalancerDetails {
|
||||
rows := make([]api.LoadbalancerDetails, len(objs))
|
||||
|
||||
clusterRows := man.SLoadbalancerClusterResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
virtRows := man.SVirtualResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
manRows := man.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
regRows := man.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
|
||||
@@ -557,6 +563,8 @@ func (man *SLoadbalancerManager) FetchCustomizeColumns(
|
||||
|
||||
for i := range rows {
|
||||
rows[i] = api.LoadbalancerDetails{
|
||||
LoadbalancerClusterResourceInfo: clusterRows[i],
|
||||
|
||||
VirtualResourceDetails: virtRows[i],
|
||||
ManagedResourceInfo: manRows[i],
|
||||
CloudregionResourceInfo: regRows[i],
|
||||
@@ -722,7 +730,7 @@ func (man *SLoadbalancerManager) SyncLoadbalancers(ctx context.Context, userCred
|
||||
if err != nil {
|
||||
syncResult.UpdateError(err)
|
||||
} else {
|
||||
syncMetadata(ctx, userCred, &commondb[i], commonext[i])
|
||||
syncVirtualResourceMetadata(ctx, userCred, &commondb[i], commonext[i])
|
||||
localLbs = append(localLbs, commondb[i])
|
||||
remoteLbs = append(remoteLbs, commonext[i])
|
||||
syncResult.Update()
|
||||
@@ -733,7 +741,7 @@ func (man *SLoadbalancerManager) SyncLoadbalancers(ctx context.Context, userCred
|
||||
if err != nil {
|
||||
syncResult.AddError(err)
|
||||
} else {
|
||||
syncMetadata(ctx, userCred, new, added[i])
|
||||
syncVirtualResourceMetadata(ctx, userCred, new, added[i])
|
||||
localLbs = append(localLbs, *new)
|
||||
remoteLbs = append(remoteLbs, added[i])
|
||||
syncResult.Add()
|
||||
@@ -742,11 +750,18 @@ func (man *SLoadbalancerManager) SyncLoadbalancers(ctx context.Context, userCred
|
||||
return localLbs, remoteLbs, syncResult
|
||||
}
|
||||
|
||||
func getExtLbNetworkIds(extLb cloudprovider.ICloudLoadbalancer) []string {
|
||||
func getExtLbNetworkIds(extLb cloudprovider.ICloudLoadbalancer, managerId string) []string {
|
||||
extNetworkIds := extLb.GetNetworkIds()
|
||||
lbNetworkIds := []string{}
|
||||
for _, networkId := range extNetworkIds {
|
||||
if network, err := db.FetchByExternalId(NetworkManager, networkId); err == nil && network != nil {
|
||||
network, err := db.FetchByExternalIdAndManagerId(NetworkManager, networkId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
wire := WireManager.Query().SubQuery()
|
||||
vpc := VpcManager.Query().SubQuery()
|
||||
return q.Join(wire, sqlchemy.Equals(wire.Field("id"), q.Field("wire_id"))).
|
||||
Join(vpc, sqlchemy.Equals(vpc.Field("id"), wire.Field("vpc_id"))).
|
||||
Filter(sqlchemy.Equals(vpc.Field("manager_id"), managerId))
|
||||
})
|
||||
if err == nil && network != nil {
|
||||
lbNetworkIds = append(lbNetworkIds, network.GetId())
|
||||
}
|
||||
}
|
||||
@@ -774,11 +789,13 @@ func (man *SLoadbalancerManager) newFromCloudLoadbalancer(ctx context.Context, u
|
||||
lb.ChargeType = extLb.GetChargeType()
|
||||
lb.EgressMbps = extLb.GetEgressMbps()
|
||||
lb.ExternalId = extLb.GetGlobalId()
|
||||
lbNetworkIds := getExtLbNetworkIds(extLb)
|
||||
lbNetworkIds := getExtLbNetworkIds(extLb, lb.ManagerId)
|
||||
lb.NetworkId = strings.Join(lbNetworkIds, ",")
|
||||
|
||||
if vpcId := extLb.GetVpcId(); len(vpcId) > 0 {
|
||||
if vpc, err := db.FetchByExternalId(VpcManager, vpcId); err == nil && vpc != nil {
|
||||
if vpc, err := db.FetchByExternalIdAndManagerId(VpcManager, vpcId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", provider.Id)
|
||||
}); err == nil && vpc != nil {
|
||||
lb.VpcId = vpc.GetId()
|
||||
}
|
||||
}
|
||||
@@ -950,14 +967,16 @@ func (lb *SLoadbalancer) SyncWithCloudLoadbalancer(ctx context.Context, userCred
|
||||
lb.EgressMbps = extLb.GetEgressMbps()
|
||||
lb.ChargeType = extLb.GetChargeType()
|
||||
lb.ManagerId = provider.Id
|
||||
lbNetworkIds := getExtLbNetworkIds(extLb)
|
||||
lbNetworkIds := getExtLbNetworkIds(extLb, lb.ManagerId)
|
||||
lb.NetworkId = strings.Join(lbNetworkIds, ",")
|
||||
if extLb.GetMetadata() != nil {
|
||||
lb.LBInfo = extLb.GetMetadata()
|
||||
}
|
||||
|
||||
if vpcId := extLb.GetVpcId(); len(vpcId) > 0 {
|
||||
if vpc, err := db.FetchByExternalId(VpcManager, vpcId); err == nil && vpc != nil {
|
||||
if vpc, err := db.FetchByExternalIdAndManagerId(VpcManager, vpcId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
return q.Equals("manager_id", provider.Id)
|
||||
}); err == nil && vpc != nil {
|
||||
lb.VpcId = vpc.GetId()
|
||||
}
|
||||
}
|
||||
@@ -967,7 +986,7 @@ func (lb *SLoadbalancer) SyncWithCloudLoadbalancer(ctx context.Context, userCred
|
||||
|
||||
db.OpsLog.LogSyncUpdate(lb, diff, userCred)
|
||||
|
||||
networkIds := getExtLbNetworkIds(extLb)
|
||||
networkIds := getExtLbNetworkIds(extLb, lb.ManagerId)
|
||||
SyncCloudProject(userCred, lb, syncOwnerId, extLb, provider.Id)
|
||||
lb.syncLoadbalancerNetwork(ctx, userCred, networkIds)
|
||||
|
||||
|
||||
@@ -46,6 +46,10 @@ type SManagedResourceBaseManager struct {
|
||||
managerIdFieldName string
|
||||
}
|
||||
|
||||
func (self *SManagedResourceBase) GetCloudproviderId() string {
|
||||
return self.ManagerId
|
||||
}
|
||||
|
||||
func ValidateCloudproviderResourceInput(userCred mcclient.TokenCredential, query api.CloudproviderResourceInput) (*SCloudprovider, api.CloudproviderResourceInput, error) {
|
||||
managerObj, err := CloudproviderManager.FetchByIdOrName(userCred, query.Cloudprovider)
|
||||
if err != nil {
|
||||
@@ -557,7 +561,7 @@ func _managedResourceFilterByAccount(managerIdFieldName string, q *sqlchemy.SQue
|
||||
|
||||
func managedResourceFilterByZone(q *sqlchemy.SQuery, query api.ZonalFilterListInput, filterField string, subqFunc func() *sqlchemy.SQuery) (*sqlchemy.SQuery, error) {
|
||||
zoneList := query.ZoneList()
|
||||
if len(zoneList) > 1 {
|
||||
if len(query.Zones) >= 1 {
|
||||
zoneQ := ZoneManager.Query("id")
|
||||
zoneQ = zoneQ.Filter(sqlchemy.OR(
|
||||
sqlchemy.In(zoneQ.Field("id"), zoneList),
|
||||
|
||||
@@ -237,6 +237,14 @@ func (manager *SNatDEntryManager) SyncNatDTable(ctx context.Context, userCred mc
|
||||
return result
|
||||
}
|
||||
|
||||
func (self *SNatDEntry) GetCloudproviderId() string {
|
||||
nat, _ := self.GetNatgateway()
|
||||
if nat != nil {
|
||||
return nat.GetCloudproviderId()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SNatDEntry) syncRemoveCloudNatDTable(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
lockman.LockObject(ctx, self)
|
||||
defer lockman.ReleaseObject(ctx, self)
|
||||
|
||||
@@ -63,6 +63,14 @@ type SNatSEntry struct {
|
||||
SourceCIDR string `width:"22" charset:"ascii" list:"user" create:"required"`
|
||||
}
|
||||
|
||||
func (self *SNatSEntry) GetCloudproviderId() string {
|
||||
network, err := self.GetNetwork()
|
||||
if err == nil {
|
||||
return network.GetCloudproviderId()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (self *SNatSEntry) GetNetwork() (*SNetwork, error) {
|
||||
if len(self.NetworkId) == 0 {
|
||||
return nil, nil
|
||||
@@ -253,7 +261,7 @@ func (manager *SNatSEntryManager) SyncNatSTable(ctx context.Context, userCred mc
|
||||
}
|
||||
|
||||
for i := 0; i < len(commondb); i += 1 {
|
||||
err := commondb[i].SyncWithCloudNatSTable(ctx, userCred, commonext[i], syncOwnerId)
|
||||
err := commondb[i].SyncWithCloudNatSTable(ctx, userCred, commonext[i], syncOwnerId, provider.Id)
|
||||
if err != nil {
|
||||
result.UpdateError(err)
|
||||
continue
|
||||
@@ -263,7 +271,7 @@ func (manager *SNatSEntryManager) SyncNatSTable(ctx context.Context, userCred mc
|
||||
}
|
||||
|
||||
for i := 0; i < len(added); i += 1 {
|
||||
routeTableNew, err := manager.newFromCloudNatSTable(ctx, userCred, syncOwnerId, nat, added[i])
|
||||
routeTableNew, err := manager.newFromCloudNatSTable(ctx, userCred, syncOwnerId, nat, added[i], provider.Id)
|
||||
if err != nil {
|
||||
result.AddError(err)
|
||||
continue
|
||||
@@ -285,13 +293,19 @@ func (self *SNatSEntry) syncRemoveCloudNatSTable(ctx context.Context, userCred m
|
||||
return self.RealDelete(ctx, userCred)
|
||||
}
|
||||
|
||||
func (self *SNatSEntry) SyncWithCloudNatSTable(ctx context.Context, userCred mcclient.TokenCredential, extEntry cloudprovider.ICloudNatSEntry, syncOwnerId mcclient.IIdentityProvider) error {
|
||||
func (self *SNatSEntry) SyncWithCloudNatSTable(ctx context.Context, userCred mcclient.TokenCredential, extEntry cloudprovider.ICloudNatSEntry, syncOwnerId mcclient.IIdentityProvider, managerId string) error {
|
||||
diff, err := db.UpdateWithLock(ctx, self, func() error {
|
||||
self.Status = extEntry.GetStatus()
|
||||
self.IP = extEntry.GetIP()
|
||||
self.SourceCIDR = extEntry.GetSourceCIDR()
|
||||
if extNetworkId := extEntry.GetNetworkId(); len(extNetworkId) > 0 {
|
||||
network, err := db.FetchByExternalId(NetworkManager, extNetworkId)
|
||||
network, err := db.FetchByExternalIdAndManagerId(NetworkManager, extNetworkId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
wire := WireManager.Query().SubQuery()
|
||||
vpc := VpcManager.Query().SubQuery()
|
||||
return q.Join(wire, sqlchemy.Equals(wire.Field("id"), q.Field("wire_id"))).
|
||||
Join(vpc, sqlchemy.Equals(vpc.Field("id"), wire.Field("vpc_id"))).
|
||||
Filter(sqlchemy.Equals(vpc.Field("manager_id"), managerId))
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -309,7 +323,7 @@ func (self *SNatSEntry) SyncWithCloudNatSTable(ctx context.Context, userCred mcc
|
||||
return nil
|
||||
}
|
||||
|
||||
func (manager *SNatSEntryManager) newFromCloudNatSTable(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, nat *SNatGateway, extEntry cloudprovider.ICloudNatSEntry) (*SNatSEntry, error) {
|
||||
func (manager *SNatSEntryManager) newFromCloudNatSTable(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, nat *SNatGateway, extEntry cloudprovider.ICloudNatSEntry, managerId string) (*SNatSEntry, error) {
|
||||
table := SNatSEntry{}
|
||||
table.SetModelManager(manager, &table)
|
||||
|
||||
@@ -322,7 +336,13 @@ func (manager *SNatSEntryManager) newFromCloudNatSTable(ctx context.Context, use
|
||||
table.IP = extEntry.GetIP()
|
||||
table.SourceCIDR = extEntry.GetSourceCIDR()
|
||||
if extNetworkId := extEntry.GetNetworkId(); len(extNetworkId) > 0 {
|
||||
network, err := db.FetchByExternalId(NetworkManager, extNetworkId)
|
||||
network, err := db.FetchByExternalIdAndManagerId(NetworkManager, extNetworkId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
wire := WireManager.Query().SubQuery()
|
||||
vpc := VpcManager.Query().SubQuery()
|
||||
return q.Join(wire, sqlchemy.Equals(wire.Field("id"), q.Field("wire_id"))).
|
||||
Join(vpc, sqlchemy.Equals(vpc.Field("id"), wire.Field("vpc_id"))).
|
||||
Filter(sqlchemy.Equals(vpc.Field("manager_id"), managerId))
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/pkg/util/netutils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
|
||||
@@ -182,7 +183,13 @@ func (manager *SNetworkinterfacenetworkManager) newFromCloudInterfaceAddress(ctx
|
||||
address.SetModelManager(manager, &address)
|
||||
|
||||
networkId := ext.GetINetworkId()
|
||||
_network, err := db.FetchByExternalId(NetworkManager, networkId)
|
||||
_network, err := db.FetchByExternalIdAndManagerId(NetworkManager, networkId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
wire := WireManager.Query().SubQuery()
|
||||
vpc := VpcManager.Query().SubQuery()
|
||||
return q.Join(wire, sqlchemy.Equals(wire.Field("id"), q.Field("wire_id"))).
|
||||
Join(vpc, sqlchemy.Equals(vpc.Field("id"), wire.Field("vpc_id"))).
|
||||
Filter(sqlchemy.Equals(vpc.Field("manager_id"), networkinterface.ManagerId))
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "newFromCloudInterfaceAddress.FetchByExternalId(%s)", networkId)
|
||||
}
|
||||
|
||||
@@ -313,7 +313,10 @@ func (self *SNetworkInterface) SyncWithCloudNetworkInterface(ctx context.Context
|
||||
func (self *SNetworkInterface) Associate(associateId string) error {
|
||||
switch self.AssociateType {
|
||||
case api.NETWORK_INTERFACE_ASSOCIATE_TYPE_SERVER:
|
||||
guest, err := db.FetchByExternalId(GuestManager, associateId)
|
||||
guest, err := db.FetchByExternalIdAndManagerId(GuestManager, associateId, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
sq := HostManager.Query().SubQuery()
|
||||
return q.Join(sq, sqlchemy.Equals(sq.Field("id"), q.Field("host_id"))).Filter(sqlchemy.Equals(q.Field("manager_id"), self.ManagerId))
|
||||
})
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to get guest for networkinterface %s associateId %s", self.Name, associateId)
|
||||
}
|
||||
|
||||
@@ -309,7 +309,17 @@ func (self *SNetwork) GetNetworkInterfacesCount() (int, error) {
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) GetOrCreateClassicNetwork(wire *SWire) (*SNetwork, error) {
|
||||
_network, err := db.FetchByExternalId(manager, wire.Id)
|
||||
_network, err := db.FetchByExternalIdAndManagerId(manager, wire.Id, func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
|
||||
v := wire.GetVpc()
|
||||
if v != nil {
|
||||
wire := WireManager.Query().SubQuery()
|
||||
vpc := VpcManager.Query().SubQuery()
|
||||
return q.Join(wire, sqlchemy.Equals(wire.Field("id"), q.Field("wire_id"))).
|
||||
Join(vpc, sqlchemy.Equals(vpc.Field("id"), wire.Field("vpc_id"))).
|
||||
Filter(sqlchemy.Equals(vpc.Field("manager_id"), v.ManagerId))
|
||||
}
|
||||
return q
|
||||
})
|
||||
if err == nil {
|
||||
return _network.(*SNetwork), nil
|
||||
}
|
||||
@@ -631,7 +641,7 @@ func (manager *SNetworkManager) SyncNetworks(ctx context.Context, userCred mccli
|
||||
if err != nil {
|
||||
syncResult.UpdateError(err)
|
||||
} else {
|
||||
syncMetadata(ctx, userCred, &commondb[i], commonext[i])
|
||||
syncVirtualResourceMetadata(ctx, userCred, &commondb[i], commonext[i])
|
||||
localNets = append(localNets, commondb[i])
|
||||
remoteNets = append(remoteNets, commonext[i])
|
||||
syncResult.Update()
|
||||
@@ -642,7 +652,7 @@ func (manager *SNetworkManager) SyncNetworks(ctx context.Context, userCred mccli
|
||||
if err != nil {
|
||||
syncResult.AddError(err)
|
||||
} else {
|
||||
syncMetadata(ctx, userCred, new, added[i])
|
||||
syncVirtualResourceMetadata(ctx, userCred, new, added[i])
|
||||
localNets = append(localNets, *new)
|
||||
remoteNets = append(remoteNets, added[i])
|
||||
syncResult.Add()
|
||||
@@ -1289,6 +1299,8 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
|
||||
var (
|
||||
ipRange netutils.IPV4AddrRange
|
||||
masklen int8
|
||||
netAddr netutils.IPV4Addr
|
||||
)
|
||||
if len(input.GuestIpPrefix) > 0 {
|
||||
prefix, err := netutils.NewIPV4Prefix(input.GuestIpPrefix)
|
||||
@@ -1296,10 +1308,15 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
return input, httperrors.NewInputParameterError("ip_prefix error: %s", err)
|
||||
}
|
||||
ipRange = prefix.ToIPRange()
|
||||
masklen = prefix.MaskLen
|
||||
netAddr = prefix.Address.NetAddr(masklen)
|
||||
input.GuestIpMask = int64(prefix.MaskLen)
|
||||
// 根据掩码得到合法的GuestIpPrefix
|
||||
input.GuestIpPrefix = prefix.String()
|
||||
} else {
|
||||
if !isValidMaskLen(input.GuestIpMask) {
|
||||
return input, httperrors.NewInputParameterError("Invalid masklen %d", input.GuestIpMask)
|
||||
}
|
||||
ipStart, err := netutils.NewIPV4Addr(input.GuestIpStart)
|
||||
if err != nil {
|
||||
return input, httperrors.NewInputParameterError("Invalid start ip: %s %s", input.GuestIpStart, err)
|
||||
@@ -1309,28 +1326,43 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
return input, httperrors.NewInputParameterError("invalid end ip: %s %s", input.GuestIpEnd, err)
|
||||
}
|
||||
ipRange = netutils.NewIPV4AddrRange(ipStart, ipEnd)
|
||||
}
|
||||
|
||||
if !isValidMaskLen(input.GuestIpMask) {
|
||||
return input, httperrors.NewInputParameterError("Invalid masklen %d", input.GuestIpMask)
|
||||
masklen = int8(input.GuestIpMask)
|
||||
netAddr = ipStart.NetAddr(masklen)
|
||||
if ipEnd.NetAddr(masklen) != netAddr {
|
||||
return input, httperrors.NewInputParameterError("start and end ip not in the same subnet")
|
||||
}
|
||||
}
|
||||
|
||||
if len(input.GuestDns) == 0 {
|
||||
input.GuestDns = options.Options.DNSServer
|
||||
}
|
||||
|
||||
for key, ipStr := range map[string]string{"guest_gateway": input.GuestGateway, "guest_dns": input.GuestDns, "guest_dhcp": input.GuestDHCP} {
|
||||
if len(ipStr) > 0 {
|
||||
if key == "guest_dhcp" {
|
||||
ipList := strings.Split(ipStr, ",")
|
||||
for _, ipstr := range ipList {
|
||||
if !regutils.MatchIPAddr(ipstr) {
|
||||
return input, httperrors.NewInputParameterError("%s: Invalid IP address %s", key, ipstr)
|
||||
}
|
||||
for key, ipStr := range map[string]string{
|
||||
"guest_gateway": input.GuestGateway,
|
||||
"guest_dns": input.GuestDns,
|
||||
"guest_dhcp": input.GuestDHCP,
|
||||
} {
|
||||
if ipStr == "" {
|
||||
continue
|
||||
}
|
||||
if key == "guest_dhcp" {
|
||||
ipList := strings.Split(ipStr, ",")
|
||||
for _, ipstr := range ipList {
|
||||
if !regutils.MatchIPAddr(ipstr) {
|
||||
return input, httperrors.NewInputParameterError("%s: Invalid IP address %s", key, ipstr)
|
||||
}
|
||||
} else if !regutils.MatchIPAddr(ipStr) {
|
||||
return input, httperrors.NewInputParameterError("%s: Invalid IP address %s", key, ipStr)
|
||||
}
|
||||
} else if !regutils.MatchIPAddr(ipStr) {
|
||||
return input, httperrors.NewInputParameterError("%s: Invalid IP address %s", key, ipStr)
|
||||
}
|
||||
}
|
||||
if input.GuestGateway != "" {
|
||||
addr, err := netutils.NewIPV4Addr(input.GuestGateway)
|
||||
if err != nil {
|
||||
return input, httperrors.NewInputParameterError("bad gateway ip: %v", err)
|
||||
}
|
||||
if addr.NetAddr(masklen) != netAddr {
|
||||
return input, httperrors.NewInputParameterError("gateway ip must be in the same subnet as start, end ip")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1422,25 +1454,37 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
|
||||
}
|
||||
|
||||
func (self *SNetwork) validateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.NetworkUpdateInput) (api.NetworkUpdateInput, error) {
|
||||
var startIp, endIp netutils.IPV4Addr
|
||||
var err error
|
||||
var (
|
||||
startIp netutils.IPV4Addr
|
||||
endIp netutils.IPV4Addr
|
||||
netAddr netutils.IPV4Addr
|
||||
masklen int8
|
||||
err error
|
||||
)
|
||||
|
||||
ipStartStr := input.GuestIpStart
|
||||
ipEndStr := input.GuestIpEnd
|
||||
if input.GuestIpMask != nil {
|
||||
maskLen64 := int64(*input.GuestIpMask)
|
||||
if !isValidMaskLen(maskLen64) {
|
||||
return input, httperrors.NewInputParameterError("Invalid masklen %d", maskLen64)
|
||||
}
|
||||
masklen = int8(maskLen64)
|
||||
} else {
|
||||
masklen = int8(self.GuestIpMask)
|
||||
}
|
||||
|
||||
if len(ipStartStr) > 0 || len(ipEndStr) > 0 {
|
||||
if len(ipStartStr) > 0 {
|
||||
startIp, err = netutils.NewIPV4Addr(ipStartStr)
|
||||
if input.GuestIpStart != "" || input.GuestIpEnd != "" {
|
||||
if input.GuestIpStart != "" {
|
||||
startIp, err = netutils.NewIPV4Addr(input.GuestIpStart)
|
||||
if err != nil {
|
||||
return input, httperrors.NewInputParameterError("Invalid start ip: %s %s", ipStartStr, err)
|
||||
return input, httperrors.NewInputParameterError("Invalid start ip: %s %s", input.GuestIpStart, err)
|
||||
}
|
||||
} else {
|
||||
startIp, _ = netutils.NewIPV4Addr(self.GuestIpStart)
|
||||
}
|
||||
if len(ipEndStr) > 0 {
|
||||
endIp, err = netutils.NewIPV4Addr(ipEndStr)
|
||||
if input.GuestIpEnd != "" {
|
||||
endIp, err = netutils.NewIPV4Addr(input.GuestIpEnd)
|
||||
if err != nil {
|
||||
return input, httperrors.NewInputParameterError("invalid end ip: %s %s", ipEndStr, err)
|
||||
return input, httperrors.NewInputParameterError("invalid end ip: %s %s", input.GuestIpEnd, err)
|
||||
}
|
||||
} else {
|
||||
endIp, _ = netutils.NewIPV4Addr(self.GuestIpEnd)
|
||||
@@ -1477,12 +1521,9 @@ func (self *SNetwork) validateUpdateData(ctx context.Context, userCred mcclient.
|
||||
|
||||
input.GuestIpStart = startIp.String()
|
||||
input.GuestIpEnd = endIp.String()
|
||||
}
|
||||
|
||||
if input.GuestIpMask != nil {
|
||||
maskLen64 := int64(*input.GuestIpMask)
|
||||
if !isValidMaskLen(maskLen64) {
|
||||
return input, httperrors.NewInputParameterError("Invalid masklen %d", maskLen64)
|
||||
netAddr = startIp.NetAddr(masklen)
|
||||
if endIp.NetAddr(masklen) != netAddr {
|
||||
return input, httperrors.NewInputParameterError("start, end ip must be in the same subnet")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1491,20 +1532,30 @@ func (self *SNetwork) validateUpdateData(ctx context.Context, userCred mcclient.
|
||||
"guest_dns": input.GuestDns,
|
||||
"guest_dhcp": input.GuestDhcp,
|
||||
} {
|
||||
if len(ipStr) > 0 {
|
||||
if key == "guest_dhcp" {
|
||||
ipList := strings.Split(ipStr, ",")
|
||||
for _, ipstr := range ipList {
|
||||
if !regutils.MatchIPAddr(ipstr) {
|
||||
return input, httperrors.NewInputParameterError("%s: Invalid IP address %s", key, ipstr)
|
||||
}
|
||||
if ipStr == "" {
|
||||
continue
|
||||
}
|
||||
if key == "guest_dhcp" {
|
||||
ipList := strings.Split(ipStr, ",")
|
||||
for _, ipstr := range ipList {
|
||||
if !regutils.MatchIPAddr(ipstr) {
|
||||
return input, httperrors.NewInputParameterError("%s: Invalid IP address %s", key, ipstr)
|
||||
}
|
||||
} else if !regutils.MatchIPAddr(ipStr) {
|
||||
return input, httperrors.NewInputParameterError("%s: Invalid IP address %s", key, ipStr)
|
||||
}
|
||||
|
||||
} else if !regutils.MatchIPAddr(ipStr) {
|
||||
return input, httperrors.NewInputParameterError("%s: Invalid IP address %s", key, ipStr)
|
||||
}
|
||||
}
|
||||
if input.GuestGateway != "" {
|
||||
addr, err := netutils.NewIPV4Addr(input.GuestGateway)
|
||||
if err != nil {
|
||||
return input, httperrors.NewInputParameterError("bad gateway ip: %v", err)
|
||||
}
|
||||
if addr.NetAddr(masklen) != netAddr {
|
||||
return input, httperrors.NewInputParameterError("gateway ip must be in the same subnet as start, end ip")
|
||||
}
|
||||
}
|
||||
|
||||
return input, nil
|
||||
}
|
||||
|
||||
@@ -1571,7 +1622,8 @@ func (self *SNetwork) CustomizeCreate(ctx context.Context, userCred mcclient.Tok
|
||||
if self.ServerType == api.NETWORK_TYPE_GUEST && !self.IsManaged() {
|
||||
if db.IsAdminAllowPerform(userCred, self, "public") && ownerId.GetProjectDomainId() == userCred.GetProjectDomainId() {
|
||||
self.SetShare(rbacutils.ScopeSystem)
|
||||
} else if db.IsDomainAllowPerform(userCred, self, "public") && ownerId.GetProjectId() == userCred.GetProjectId() {
|
||||
} else if db.IsDomainAllowPerform(userCred, self, "public") && ownerId.GetProjectId() == userCred.GetProjectId() && consts.GetNonDefaultDomainProjects() {
|
||||
// only if non_default_domain_projects turned on, share to domain
|
||||
self.SetShare(rbacutils.ScopeDomain)
|
||||
} else {
|
||||
self.SetShare(rbacutils.ScopeNone)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user