Merge branch 'master' of https://github.com/yunionio/onecloud into feature/zxc-overview-monitor-resource

This commit is contained in:
zhaoxiangchun
2021-06-22 17:06:49 +08:00
110 changed files with 25920 additions and 53 deletions
+128
View File
@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
abuse@cloudpods.org.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.
+6
View File
@@ -122,12 +122,18 @@ $ git clone https://github.com/yunionio/ocboot && cd ./ocboot && ./run.py 10.168
* [Swagger API文档](https://www.cloudpods.org/zh/docs/swagger/)
## 谁在使用Cloudpods
请在[这里](https://github.com/yunionio/cloudpods/issues/11427)查看Cloudpods用户列表。如果你正在使用Cloudpods,欢迎回复留下你的信息。谢谢对Cloudpods的支持!
## 联系我们
您可以通过如下方式联系我们:
* Reddit: [r/Cloudpods](https://www.reddit.com/r/Cloudpods/)
* 哔哩哔哩: [Cloudpods](https://space.bilibili.com/623431553/)
* 微信: 请扫描如下二维码联系我们
<img src="https://www.cloudpods.org/images/skillcode.png" alt="WeChat QRCode">
+6
View File
@@ -127,12 +127,18 @@ For more detailed instructions, please refers to [quick start](https://www.cloud
* [Swagger API](https://www.cloudpods.org/en/docs/swagger/)
## Who is using Cloudpods?
Please check this [issue](https://github.com/yunionio/cloudpods/issues/11427) for the user list of Cloudpods. If you are using Cloudpods, you are welcome to leave your information by responding the issue. Thank you for your support.
## Contact
You may contact us by:
* Reddit: [r/Cloudpods](https://www.reddit.com/r/Cloudpods/)
* Bilibili: [Cloudpods](https://space.bilibili.com/623431553/)
* WeChat: please scan the following QRCode to contact us
<img src="https://www.cloudpods.org/images/skillcode.png" alt="WeChat QRCode">
+5 -3
View File
@@ -4,6 +4,8 @@ MAINTAINER "Zexi Li <lizexi@yunionyun.com>"
RUN mkdir -p /opt/yunion/bin
ADD ./_output/bin/baremetal-agent /opt/yunion/bin/baremetal-agent
ADD ./_output/bin/.baremetal-agent.bin /opt/yunion/bin/.baremetal-agent.bin
ADD ./_output/bin/bundles/baremetal-agent /opt/yunion/bin/bundles/baremetal-agent
#ADD ./_output/bin/baremetal-agent /opt/yunion/bin/baremetal-agent
#ADD ./_output/bin/.baremetal-agent.bin /opt/yunion/bin/.baremetal-agent.bin
#ADD ./_output/bin/bundles/baremetal-agent /opt/yunion/bin/bundles/baremetal-agent
RUN apk add librados librbd
ADD ./_output/alpine-build/bin/baremetal-agent /opt/yunion/bin/baremetal-agent
+30
View File
@@ -0,0 +1,30 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.AppGateways)
cmd.List(&compute.AppGatewayListOptions{})
cmd.Perform("syncstatus", &options.BaseIdOptions{})
cmd.Get("backends", &options.BaseIdOptions{})
cmd.Get("frontends", &options.BaseIdOptions{})
}
+33
View File
@@ -0,0 +1,33 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.WafInstances).WithKeyword("waf").WithContextManager(&modules.Cloudregions)
cmd.List(&compute.WafInstanceListOptions{})
cmd.Delete(&options.BaseIdOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Update(&options.BaseUpdateOptions{})
cmd.Get("cloud-resources", &options.BaseIdOptions{})
cmd.Perform("syncstatus", &options.BaseIdOptions{})
cmd.Create(&compute.WafInstanceCreateOptions{})
}
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.WafIPSetCaches)
cmd.List(&compute.WafIPSetCacheListOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Delete(&options.BaseIdOptions{})
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.WafIPSets)
cmd.List(&compute.WafIPSetListOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Delete(&options.BaseIdOptions{})
}
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.WafRegexSetCaches)
cmd.List(&compute.WafRegexSetCacheListOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Delete(&options.BaseIdOptions{})
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.WafRegexSets)
cmd.List(&compute.WafRegexSetListOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Delete(&options.BaseIdOptions{})
}
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.WafRuleGroups)
cmd.List(&compute.WafRuleGroupListOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Delete(&options.BaseIdOptions{})
}
+32
View File
@@ -0,0 +1,32 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.WafRules)
cmd.List(&compute.WafRuleListOptions{})
cmd.Create(&compute.WafRuleOptions{})
cmd.Update(&compute.WafRuleUpdateOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Delete(&options.BaseIdOptions{})
cmd.Perform("syncstatus", &options.BaseIdOptions{})
}
-11
View File
@@ -2,14 +2,12 @@ bazil.org/fuse v0.0.0-20180421153158-65cc252bf669 h1:FNCRpXiquG1aoyqcIWVFmpTSKVc
bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0 h1:0E3eE8MX426vUOs7aHfI7aN1BrIzzzf4ccKCSfSjGmc=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.51.0 h1:PvKAVQWCtlGUSlZkGW3QLelKaWq7KYv/MW1EboG8bfM=
cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw=
@@ -32,16 +30,12 @@ github.com/Azure/azure-sdk-for-go v36.1.0+incompatible h1:smHlbChr/JDmsyUqELZXLs
github.com/Azure/azure-sdk-for-go v36.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest v0.9.3 h1:OZEIaBbMdUE/Js+BQKlpO81XlISgipr6yDJ+PSwsgi4=
github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0=
github.com/Azure/go-autorest/autorest v0.9.6 h1:5YWtOnckcudzIw8lPPBcWOnmIFWMtHci1ZWAZulMSx0=
github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
github.com/Azure/go-autorest/autorest/adal v0.8.1 h1:pZdL8o72rK+avFWl+p9nE8RWi1JInZrWJYlnpfXJwHk=
github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
github.com/Azure/go-autorest/autorest/adal v0.8.2 h1:O1X4oexUxnZCaEUGsvMnr8ZGj8HI37tNezwY4npRqA0=
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
@@ -49,12 +43,10 @@ github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 h1:iM6UAvjR97ZIeR93qTcwp
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM=
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1 h1:LXl088ZQlP0SBppGFsRZonW6hSvwgL5gRByMbvUbx8U=
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw=
github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM=
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
@@ -703,10 +695,8 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
@@ -752,7 +742,6 @@ golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8=
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+39
View File
@@ -0,0 +1,39 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import "yunion.io/x/onecloud/pkg/apis"
const (
APP_GATEWAY_STATUS_AVAILABLE = "available"
APP_GATEWAY_STATUS_DELETING = "deleting"
APP_GATEWAY_STATUS_CREATE_FAILED = "create_failed"
APP_GATEWAY_STATUS_UPDATING = "updating"
APP_GATEWAY_STATUS_UNKNOWN = "unknown"
)
type AppGatewayDetails struct {
apis.EnabledStatusInfrasResourceBaseDetails
ManagedResourceInfo
CloudregionResourceInfo
}
type AppGatewayListInput struct {
apis.EnabledStatusInfrasResourceBaseListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
RegionalFilterListInput
}
+84
View File
@@ -0,0 +1,84 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
const (
WAF_ACTION_ALLOW = "Allow"
WAF_ACTION_BLOCK = "Block"
WAF_ACTION_PREVENTION = "Prevention"
WAF_ACTION_DETECTION = "Detection"
WAF_STATUS_AVAILABLE = "available"
WAF_STATUS_DELETING = "deleting"
WAF_STATUS_DELETE_FAILED = "delete_failed"
WAF_STATUS_CREATING = "creating"
WAF_STATUS_CREATE_FAILED = "create_failed"
WAF_STATUS_UPDATING = "updating"
WAF_STATUS_UNKNOWN = "unknown"
)
type WafInstanceCreateInput struct {
apis.EnabledStatusInfrasResourceBaseCreateInput
// 阿里云CNAME介入回源地址,支持IP和域名,域名仅支持输入一个
// 此参数和cloud_resources两者必须指定某一个
SourceIps cloudprovider.WafSourceIps `json:"source_ips"`
// 关联云资源列表
// 阿里云要求输入此参数或source_ips
CloudResources []cloudprovider.SCloudResource
CloudregionResourceInput
CloudproviderResourceInput
Type cloudprovider.TWafType
DefaultAction *cloudprovider.DefaultAction
}
type WafInstanceDetails struct {
apis.EnabledStatusInfrasResourceBaseDetails
ManagedResourceInfo
CloudregionResourceInfo
Rules []SWafRule
}
type SWafRule struct {
Id string
Name string
Priority int
Action *cloudprovider.DefaultAction
}
type WafInstanceListInput struct {
apis.EnabledStatusInfrasResourceBaseListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
RegionalFilterListInput
}
type WafSyncstatusInput struct {
}
type WafDeleteRuleInput struct {
WafRuleId string
}
+45
View File
@@ -0,0 +1,45 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import "yunion.io/x/onecloud/pkg/apis"
const (
WAF_IPSET_STATUS_AVAILABLE = "available"
WAF_IPSET_STATUS_DELETING = "deleting"
WAF_IPSET_STATUS_DELETE_FAILED = "delete_failed"
)
type WafIPSetDetails struct {
apis.StatusInfrasResourceBaseDetails
}
type WafIPSetListInput struct {
apis.StatusInfrasResourceBaseListInput
}
type WafIPSetCacheDetails struct {
apis.StatusStandaloneResourceDetails
ManagedResourceInfo
CloudregionResourceInfo
}
type WafIPSetCacheListInput struct {
apis.StatusStandaloneResourceListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
RegionalFilterListInput
}
+45
View File
@@ -0,0 +1,45 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import "yunion.io/x/onecloud/pkg/apis"
const (
WAF_REGEX_SET_STATUS_AVAILABLE = "available"
WAF_REGEX_SET_STATUS_DELETING = "deleting"
WAF_REGEX_SET_STATUS_DELETE_FAILED = "delete_failed"
)
type WafRegexSetDetails struct {
apis.StatusInfrasResourceBaseDetails
}
type WafRegexSetListInput struct {
apis.StatusInfrasResourceBaseListInput
}
type WafRegexSetCacheDetails struct {
apis.StatusStandaloneResourceDetails
ManagedResourceInfo
CloudregionResourceInfo
}
type WafRegexSetCacheListInput struct {
apis.StatusStandaloneResourceListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
RegionalFilterListInput
}
+50
View File
@@ -0,0 +1,50 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import "yunion.io/x/onecloud/pkg/apis"
const (
WAF_RULE_GROUP_STATUS_AVAILABLE = "available"
WAF_RULE_GROUP_STATUS_DELETING = "deleting"
)
type WafRuleGroupDetails struct {
apis.StatusInfrasResourceBaseDetails
}
type WafRuleGroupListInput struct {
apis.StatusInfrasResourceBaseListInput
// 是否是系统RuleGroup
IsSystem *bool `json:"is_system"`
// 云平台
Provider string `json:"provider"`
// 云环境
CloudEnv string `json:"cloud_env"`
}
type WafRuleGroupCacheDetails struct {
apis.StatusStandaloneResourceDetails
ManagedResourceInfo
CloudregionResourceInfo
}
type WafRuleGroupCacheListInput struct {
apis.StatusStandaloneResourceListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
RegionalFilterListInput
}
+76
View File
@@ -0,0 +1,76 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
const (
WAF_RULE_STATUS_AVAILABLE = "available"
WAF_RULE_STATUS_DELETING = "deleting"
WAF_RULE_STATUS_CREATING = "creating"
WAF_RULE_STATUS_CREATE_FAILED = "create_failed"
WAF_RULE_STATUS_DELETE_FAILED = "delete_failed"
WAF_RULE_STATUS_UPDATING = "updating"
WAF_RULE_STATUS_UPDATE_FAILED = "update_failed"
WAF_RULE_STATUS_UNKNOWN = "unknown"
)
type WafRuleListInput struct {
apis.StatusStandaloneResourceListInput
apis.ExternalizedResourceBaseListInput
// WAF实例Id
WafInstanceId string `json:"waf_instance_id"`
// WAF规则组Id
WafRuleGroupId string `json:"waf_rule_group_id"`
}
type WafRuleCreateInput struct {
apis.StatusStandaloneResourceCreateInput
// WAF实例Id
WafInstanceId string `json:"waf_instance_id"`
// 优先级,不可重复
// Azure优先级范围1-100
Priority int `json:"priority"`
// 匹配后默认行为
Action *cloudprovider.DefaultAction `json:"action"`
// enmu: and, or, not
StatementCondition string `json:"statement_condition"`
// swagger: ignore
// WAF规则组Id
WafRuleGroupId string `json:"waf_rule_group_id"`
// 条件表达式
Statements []cloudprovider.SWafStatement
}
type WafRuleDetails struct {
apis.StatusStandaloneResourceDetails
Statements []cloudprovider.SWafStatement
}
type WafRuleUpdateInput struct {
apis.StatusStandaloneResourceBaseUpdateInput
// 条件表达式
Statements []cloudprovider.SWafStatement
}
+1
View File
@@ -20,6 +20,7 @@ var (
METRIC_RES_TYPE_OSS: "oss_name",
METRIC_RES_TYPE_CLOUDACCOUNT: "cloudaccount_name",
METRIC_RES_TYPE_STORAGE: "storage_name",
METRIC_RES_TYPE_AGENT: "vm_name",
}
MEASUREMENT_TAG_ID = map[string]string{
METRIC_RES_TYPE_HOST: "host_id",
+49
View File
@@ -0,0 +1,49 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cloudprovider
type SAppGatewayHttpListener struct {
Name string
Port int
Protocol string
}
type SAppGatewayFrontend struct {
Name string
IpAddr string
Type string
HttpListener []SAppGatewayHttpListener
}
type SAppGatewayFrontends struct {
Total int `json:"total"`
Data []SAppGatewayFrontend `json:"data"`
}
type SAppGatewayRoutingRule struct {
Name string
Type string
HttpListener string
}
type SAppGatewayBackend struct {
Name string
RoutingRules []SAppGatewayRoutingRule
}
type SAppGatewayBackends struct {
Total int `json:"total"`
Data []SAppGatewayBackend `json:"data"`
}
+1
View File
@@ -56,6 +56,7 @@ const (
CLOUD_CAPABILITY_SAML_AUTH = "saml_auth" // 是否支持SAML 2.0
CLOUD_CAPABILITY_NAT = "nat" // NAT网关
CLOUD_CAPABILITY_NAS = "nas" // NAS
CLOUD_CAPABILITY_WAF = "waf" // WAF
)
const (
+78
View File
@@ -44,6 +44,11 @@ type ICloudResource interface {
SetTags(tags map[string]string, replace bool) error
}
type ICloudEnabledResource interface {
ICloudResource
GetEnabled() bool
}
type IVirtualResource interface {
ICloudResource
@@ -162,6 +167,16 @@ type ICloudRegion interface {
GetICloudAccessGroups() ([]ICloudAccessGroup, error)
CreateICloudAccessGroup(opts *SAccessGroup) (ICloudAccessGroup, error)
GetICloudAccessGroupById(id string) (ICloudAccessGroup, error)
GetICloudApplicationGateways() ([]ICloudApplicationGateway, error)
GetICloudApplicationGatewayById(id string) (ICloudApplicationGateway, error)
GetICloudWafIPSets() ([]ICloudWafIPSet, error)
GetICloudWafRegexSets() ([]ICloudWafRegexSet, error)
GetICloudWafInstances() ([]ICloudWafInstance, error)
GetICloudWafInstanceById(id string) (ICloudWafInstance, error)
CreateICloudWafInstance(opts *WafCreateOptions) (ICloudWafInstance, error)
GetICloudWafRuleGroups() ([]ICloudWafRuleGroup, error)
}
type ICloudZone interface {
@@ -1278,3 +1293,66 @@ type ICloudAccessGroup interface {
Delete() error
}
type ICloudApplicationGateway interface {
ICloudResource
GetInstanceType() string
GetBackends() ([]SAppGatewayBackend, error)
GetFrontends() ([]SAppGatewayFrontend, error)
}
type ICloudWafIPSet interface {
GetName() string
GetDesc() string
GetType() TWafType
GetGlobalId() string
GetAddresses() WafAddresses
Delete() error
}
type ICloudWafRegexSet interface {
GetName() string
GetDesc() string
GetType() TWafType
GetGlobalId() string
GetRegexPatterns() WafRegexPatterns
Delete() error
}
type ICloudWafInstance interface {
ICloudEnabledResource
GetWafType() TWafType
GetDefaultAction() *DefaultAction
GetRules() ([]ICloudWafRule, error)
AddRule(opts *SWafRule) (ICloudWafRule, error)
// 绑定的资源列表
GetCloudResources() ([]SCloudResource, error)
Delete() error
}
type ICloudWafRuleGroup interface {
GetName() string
GetDesc() string
GetGlobalId() string
GetWafType() TWafType
GetRules() ([]ICloudWafRule, error)
}
type ICloudWafRule interface {
GetName() string
GetDesc() string
GetGlobalId() string
GetPriority() int
GetAction() *DefaultAction
GetStatementCondition() TWafStatementCondition
GetStatements() ([]SWafStatement, error)
Update(opts *SWafRule) error
Delete() error
}
+292
View File
@@ -0,0 +1,292 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cloudprovider
import (
"fmt"
"reflect"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/gotypes"
)
type TWafStatementType string
type TWafStatementCondition string
type TWafAction string
type TWafMatchField string
type TWafType string
type TWafOperator string
type TWafTextTransformation string
var (
WafTypeCloudFront = TWafType("CloudFront")
WafTypeRegional = TWafType("Regional")
WafTypeDefault = TWafType("Default")
WafTypeAppGateway = TWafType("AppGateway")
WafStatementTypeByteMatch = TWafStatementType("ByteMatch")
WafStatementTypeGeoMatch = TWafStatementType("GeoMatch")
WafStatementTypeIPSet = TWafStatementType("IPSet")
WafStatementTypeLabelMatch = TWafStatementType("LabelMatch")
WafStatementTypeManagedRuleGroup = TWafStatementType("ManagedRuleGroup")
WafStatementTypeRate = TWafStatementType("Rate")
WafStatementTypeRegexSet = TWafStatementType("RegexSet")
WafStatementTypeRuleGroup = TWafStatementType("RuleGroup")
WafStatementTypeSize = TWafStatementType("Size")
WafStatementTypeSqliMatch = TWafStatementType("SqliMatch")
WafStatementTypeXssMatch = TWafStatementType("XssMatch")
WafStatementConditionAnd = TWafStatementCondition("And")
WafStatementConditionOr = TWafStatementCondition("Or")
WafStatementConditionNot = TWafStatementCondition("Not")
WafStatementConditionNone = TWafStatementCondition("")
WafActionAllow = TWafAction("Allow")
WafActionBlock = TWafAction("Block")
WafActionLog = TWafAction("Log")
WafActionCount = TWafAction("Count")
WafActionAlert = TWafAction("Alert")
WafActionDetection = TWafAction("Detection")
WafActionPrevention = TWafAction("Prevention")
WafActionNone = TWafAction("")
WafMatchFieldBody = TWafMatchField("Body")
WafMatchFieldJsonBody = TWafMatchField("JsonBody")
WafMatchFieldQuery = TWafMatchField("Query")
WafMatchFieldMethod = TWafMatchField("Method")
WafMatchFiledHeader = TWafMatchField("Header")
WafMatchFiledUriPath = TWafMatchField("UriPath")
WafMatchFiledPostArgs = TWafMatchField("PostArgs")
WafMatchFiledCookie = TWafMatchField("Cookie")
// size
WafOperatorEQ = TWafOperator("EQ")
WafOperatorNE = TWafOperator("NE")
WafOperatorLE = TWafOperator("LE")
WafOperatorLT = TWafOperator("LT")
WafOperatorGE = TWafOperator("GE")
WafOperatorGT = TWafOperator("GT")
// string
WafOperatorExactly = TWafOperator("Exactly")
WafOperatorStartsWith = TWafOperator("StartsWith")
WafOperatorEndsWith = TWafOperator("EndsWith")
WafOperatorContains = TWafOperator("Contains")
WafOperatorContainsWord = TWafOperator("ContainsWord")
WafOperatorRegex = TWafOperator("Regex")
WafTextTransformationNone = TWafTextTransformation("")
WafTextTransformationCompressWithSpace = TWafTextTransformation("CompressWithSpace")
WafTextTransformationHtmlEntityDecode = TWafTextTransformation("HtmlEntityDecode")
WafTextTransformationLowercase = TWafTextTransformation("Lowercase")
WafTextTransformationCmdLine = TWafTextTransformation("CmdLine")
WafTextTransformationUrlDecode = TWafTextTransformation("UrlDecode")
// azure
WafTextTransformationTrim = TWafTextTransformation("Trim")
WafTextTransformationUrlEncode = TWafTextTransformation("UrlEncode")
WafTextTransformationRemoveNulls = TWafTextTransformation("RemoveNulls")
)
type TWafMatchFieldValues []string
func (self TWafMatchFieldValues) IsZero() bool {
return len(self) == 0
}
func (self TWafMatchFieldValues) String() string {
return jsonutils.Marshal(self).String()
}
type TextTransformations []TWafTextTransformation
func (self TextTransformations) IsZero() bool {
return len(self) == 0
}
func (self TextTransformations) String() string {
return jsonutils.Marshal(self).String()
}
type SExcludeRule struct {
Name string
}
type SExcludeRules []SExcludeRule
func (self SExcludeRules) IsZero() bool {
return len(self) == 0
}
func (self SExcludeRules) String() string {
return jsonutils.Marshal(self).String()
}
type SWafRule struct {
Name string
Desc string
Action *DefaultAction
StatementCondition TWafStatementCondition
Priority int
Statements []SWafStatement
}
type SWafStatement struct {
// 管理规则组名称
ManagedRuleGroupName string `width:"64" charset:"utf8" nullable:"false" list:"user"`
// 不包含的规则列表
ExcludeRules *SExcludeRules `width:"200" charset:"utf8" nullable:"false" list:"user"`
// 表达式类别
// enmu: ByteMatch, GeoMatch, IPSet, LabelMatch, ManagedRuleGroup, Rate, RegexSet, RuleGroup, Size, SqliMatch, XssMatch
Type TWafStatementType `width:"20" charset:"ascii" nullable:"false" list:"user"`
// 是否取反操作, 仅对Azure生效
Negation bool `nullable:"false" list:"user"`
// 操作类型
// enum: EQ, NE, LE, LT, GE, GT
Operator TWafOperator `width:"20" charset:"ascii" nullable:"false" list:"user"`
// 匹配字段
// enmu: Body, JsonBody, Query, Method, Header, UriPath, PostArgs, Cookie
MatchField TWafMatchField `width:"20" charset:"utf8" nullable:"false" list:"user"`
// 匹配字段的key
MatchFieldKey string `width:"20" charset:"utf8" nullable:"false" list:"user"`
// 匹配字段的值列表
MatchFieldValues *TWafMatchFieldValues `width:"250" charset:"utf8" nullable:"false" list:"user"`
// 进行转换操作
// enmu: CompressWithSpace, HtmlEntityDecode, Lowercase, CmdLine, UrlDecode, Trim, UrlEncode, RemoveNulls
Transformations *TextTransformations `width:"250" charset:"ascii" nullable:"false" list:"user"`
ForwardedIPHeader string `width:"20" charset:"ascii" nullable:"false" list:"user"`
// 搜索字段, 仅Aws有用
SearchString string `width:"64" charset:"utf8" nullable:"false" list:"user"`
IPSetId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
// 正则表达式Id, 目前只读
RegexSetId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
// 自定义规则组Id, 目前只读
RuleGroupId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
// 大小, 仅type=Size时必填
Size *int64 `nullable:"false" list:"user"`
// 速率限制, 仅type=Rate时必填
Limit *int64 `nullable:"false" list:"user"`
}
func (self SWafStatement) GetGlobalId() string {
size, limit := int64(0), int64(0)
if self.Size != nil {
size = *self.Size
}
if self.Limit != nil {
limit = *self.Limit
}
return fmt.Sprintf("%s-%s-%s-%s-%s-%d-%d",
self.Type,
self.MatchField,
self.MatchFieldKey,
self.ManagedRuleGroupName,
self.SearchString,
size,
limit,
)
}
func (self SWafStatement) GetExternalId() string {
return self.GetGlobalId()
}
type DefaultAction struct {
// Allow, Block, Log, Count, Alert, Detection, Prevention
Action TWafAction
// 仅Action为Allow时生效
InsertHeaders map[string]string
// 仅Action为Block时生效
Response string
// 仅Action为Block时生效
ResponseCode *int
// 仅Action为Block时生效
ResponseHeaders map[string]string
}
type WafSourceIps []string
type WafRegexPatterns []string
func (self WafRegexPatterns) IsZero() bool {
return len(self) == 0
}
func (self WafRegexPatterns) String() string {
return jsonutils.Marshal(self).String()
}
type WafAddresses []string
func (self WafAddresses) IsZero() bool {
return len(self) == 0
}
func (self WafAddresses) String() string {
return jsonutils.Marshal(self).String()
}
func (self DefaultAction) IsZero() bool {
return false
}
func (self DefaultAction) String() string {
return jsonutils.Marshal(self).String()
}
type SCloudResource struct {
// 资源Id
Id string
// 资源类型
Type string
// 资源映射端口
Port int
// 是否可以解除关联
CanDissociate bool
}
type WafCreateOptions struct {
Name string
Desc string
CloudResources []SCloudResource
SourceIps WafSourceIps
Type TWafType
DefaultAction *DefaultAction
}
func init() {
gotypes.RegisterSerializable(reflect.TypeOf(&DefaultAction{}), func() gotypes.ISerializable {
return &DefaultAction{}
})
gotypes.RegisterSerializable(reflect.TypeOf(&WafAddresses{}), func() gotypes.ISerializable {
return &WafAddresses{}
})
gotypes.RegisterSerializable(reflect.TypeOf(&TextTransformations{}), func() gotypes.ISerializable {
return &TextTransformations{}
})
gotypes.RegisterSerializable(reflect.TypeOf(&TWafMatchFieldValues{}), func() gotypes.ISerializable {
return &TWafMatchFieldValues{}
})
gotypes.RegisterSerializable(reflect.TypeOf(&SExcludeRules{}), func() gotypes.ISerializable {
return &SExcludeRules{}
})
}
+1 -1
View File
@@ -160,7 +160,7 @@ func (self *SBaremetalGuestDriver) GetNamedNetworkConfiguration(guest *models.SG
}
reuseAddr := false
hn := host.GetAttach2Network(netConfig.Network)
if hn != nil && netConfig.Address == "" && options.Options.BaremetalServerReuseHostIp {
if hn != nil && options.Options.BaremetalServerReuseHostIp {
// try to reuse host network IP address
netConfig.Address = hn.IpAddr
reuseAddr = true
+399
View File
@@ -0,0 +1,399 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/tristate"
"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"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SAppGatewayManager struct {
db.SEnabledStatusInfrasResourceBaseManager
db.SExternalizedResourceBaseManager
SManagedResourceBaseManager
SCloudregionResourceBaseManager
}
var AppGatewayManager *SAppGatewayManager
func init() {
AppGatewayManager = &SAppGatewayManager{
SEnabledStatusInfrasResourceBaseManager: db.NewEnabledStatusInfrasResourceBaseManager(
SAppGateway{},
"app_gateways_tbl",
"app_gateway",
"app_gateways",
),
}
AppGatewayManager.SetVirtualObject(AppGatewayManager)
}
type SAppGateway struct {
db.SEnabledStatusInfrasResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
SCloudregionResourceBase `width:"36" charset:"ascii" nullable:"false" list:"domain" create:"domain_required" default:"default"`
// 类型
InstanceType string `width:"64" charset:"utf8" nullable:"true" list:"user" create:"optional"`
}
func (manager *SAppGatewayManager) GetContextManagers() [][]db.IModelManager {
return [][]db.IModelManager{
{CloudregionManager},
}
}
func (self *SAppGateway) ValidateDeleteCondition(ctx context.Context) error {
return self.SEnabledStatusInfrasResourceBase.ValidateDeleteCondition(ctx)
}
func (manager *SAppGatewayManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.AppGatewayDetails {
rows := make([]api.AppGatewayDetails, len(objs))
stdRows := manager.SEnabledStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.AppGatewayDetails{
EnabledStatusInfrasResourceBaseDetails: stdRows[i],
ManagedResourceInfo: managerRows[i],
CloudregionResourceInfo: regionRows[i],
}
}
return rows
}
func (self *SAppGateway) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SAppGateway) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SEnabledStatusInfrasResourceBase.Delete(ctx, userCred)
}
func (self *SAppGateway) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
lockman.LockObject(ctx, self)
defer lockman.ReleaseObject(ctx, self)
err := self.ValidateDeleteCondition(ctx)
if err != nil {
return errors.Wrapf(err, "ValidateDeleteCondition")
}
return self.RealDelete(ctx, userCred)
}
// 列出应用程序网关
func (manager *SAppGatewayManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.AppGatewayListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SEnabledStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.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")
}
q, err = manager.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SAppGatewayManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SEnabledStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SAppGatewayManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.AppGatewayListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SAppGatewayManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusInfrasResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ListItemExportKeys")
}
if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
}
}
if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
}
}
return q, nil
}
//同步应用程序网关状态
func (self *SAppGateway) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "syncstatus")
}
func (self *SAppGateway) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
return nil, StartResourceSyncStatusTask(ctx, userCred, self, "AppGatewaySyncStatusTask", "")
}
func (self *SAppGateway) GetRegion() (*SCloudregion, error) {
region, err := CloudregionManager.FetchById(self.CloudregionId)
if err != nil {
return nil, errors.Wrapf(err, "FetchById(%s)", self.CloudregionId)
}
return region.(*SCloudregion), nil
}
func (self *SAppGateway) GetIRegion() (cloudprovider.ICloudRegion, error) {
provider, err := self.GetDriver()
if err != nil {
return nil, errors.Wrapf(err, "GetDriver")
}
region, err := self.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
return provider.GetIRegionById(region.ExternalId)
}
func (self *SAppGateway) GetICloudAppGateway() (cloudprovider.ICloudApplicationGateway, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
iRegion, err := self.GetIRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetIRegion")
}
return iRegion.GetICloudApplicationGatewayById(self.ExternalId)
}
func (self *SCloudregion) GetAppGateways() ([]SAppGateway, error) {
q := AppGatewayManager.Query().Equals("cloudregion_id", self.Id)
ret := []SAppGateway{}
err := db.FetchModelObjects(AppGatewayManager, q, &ret)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return ret, nil
}
func (self *SCloudregion) SyncAppGateways(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, exts []cloudprovider.ICloudApplicationGateway) compare.SyncResult {
lockman.LockRawObject(ctx, self.Id, AppGatewayManager.Keyword())
defer lockman.ReleaseRawObject(ctx, self.Id, AppGatewayManager.Keyword())
result := compare.SyncResult{}
dbApps, err := self.GetAppGateways()
if err != nil {
result.Error(errors.Wrapf(err, "self.GetAppGateways"))
return result
}
removed := make([]SAppGateway, 0)
commondb := make([]SAppGateway, 0)
commonext := make([]cloudprovider.ICloudApplicationGateway, 0)
added := make([]cloudprovider.ICloudApplicationGateway, 0)
err = compare.CompareSets(dbApps, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(errors.Wrapf(err, "compare.CompareSets"))
return result
}
for i := 0; i < len(removed); i += 1 {
err = removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i += 1 {
err = commondb[i].SyncWithCloudAppGateway(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i += 1 {
_, err := self.newFromCloudAppGateway(ctx, userCred, provider, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func (self *SAppGateway) SyncWithCloudAppGateway(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudApplicationGateway) error {
_, err := db.Update(self, func() error {
self.Status = ext.GetStatus()
self.InstanceType = ext.GetInstanceType()
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update")
}
syncMetadata(ctx, userCred, self, ext)
provider := self.GetCloudprovider()
if provider != nil {
SyncCloudDomain(userCred, self, provider.GetOwnerId())
}
return nil
}
func (self *SCloudregion) newFromCloudAppGateway(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudApplicationGateway) (*SAppGateway, error) {
app := &SAppGateway{}
app.SetModelManager(AppGatewayManager, app)
app.Status = ext.GetStatus()
app.Enabled = tristate.True
app.CloudregionId = self.Id
app.ManagerId = provider.Id
app.ExternalId = ext.GetGlobalId()
app.InstanceType = ext.GetInstanceType()
err := func() error {
lockman.LockRawObject(ctx, AppGatewayManager.Keyword(), "name")
defer lockman.ReleaseRawObject(ctx, AppGatewayManager.Keyword(), "name")
var err error
app.Name, err = db.GenerateName(ctx, AppGatewayManager, userCred, ext.GetName())
if err != nil {
return errors.Wrapf(err, "db.GenerateName")
}
return AppGatewayManager.TableSpec().Insert(ctx, app)
}()
if err != nil {
return nil, errors.Wrapf(err, "Insert")
}
syncMetadata(ctx, userCred, app, ext)
SyncCloudDomain(userCred, app, provider.GetOwnerId())
return app, nil
}
func (self *SAppGateway) AllowGetDetailsBackends(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowGetSpec(userCred, self, "backends")
}
func (self *SAppGateway) GetDetailsBackends(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (cloudprovider.SAppGatewayBackends, error) {
ret := cloudprovider.SAppGatewayBackends{}
iApp, err := self.GetICloudAppGateway()
if err != nil {
return ret, errors.Wrapf(err, "GetICloudAppGateway")
}
ret.Data, err = iApp.GetBackends()
if err != nil {
return ret, errors.Wrapf(err, "GetBackends")
}
ret.Total = len(ret.Data)
return ret, nil
}
func (self *SAppGateway) AllowGetDetailsFrontends(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowGetSpec(userCred, self, "frontends")
}
func (self *SAppGateway) GetDetailsFrontends(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (cloudprovider.SAppGatewayFrontends, error) {
ret := cloudprovider.SAppGatewayFrontends{}
iApp, err := self.GetICloudAppGateway()
if err != nil {
return ret, errors.Wrapf(err, "GetICloudAppGateway")
}
ret.Data, err = iApp.GetFrontends()
if err != nil {
return ret, errors.Wrapf(err, "GetFrontends")
}
ret.Total = len(ret.Data)
return ret, nil
}
+4
View File
@@ -55,6 +55,8 @@ type SCapabilities struct {
DisabledNatBrands []string `json:",allowempty"`
NasBrands []string `json:",allowempty"`
DisabledNasBrands []string `json:",allowempty"`
WafBrands []string `json:",allowempty"`
DisabledWafBrands []string `json:",allowempty"`
PublicIpBrands []string `json:",allowempty"`
NetworkManageBrands []string `json:",allowempty"`
DisabledNetworkManageBrands []string `json:",allowempty"`
@@ -303,6 +305,7 @@ func getBrands(region *SCloudregion, zone *SZone, domainId string, capa *SCapabi
capa.SamlAuthBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.True, cloudprovider.CLOUD_CAPABILITY_SAML_AUTH)
capa.NatBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.True, cloudprovider.CLOUD_CAPABILITY_NAT)
capa.NasBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.True, cloudprovider.CLOUD_CAPABILITY_NAS)
capa.WafBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.True, cloudprovider.CLOUD_CAPABILITY_WAF)
if utils.IsInStringArray(api.HYPERVISOR_KVM, capa.Hypervisors) || utils.IsInStringArray(api.HYPERVISOR_BAREMETAL, capa.Hypervisors) {
capa.Brands = append(capa.Brands, api.ONECLOUD_BRAND_ONECLOUD)
@@ -324,6 +327,7 @@ func getBrands(region *SCloudregion, zone *SZone, domainId string, capa *SCapabi
capa.DisabledSamlAuthBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.False, cloudprovider.CLOUD_CAPABILITY_SAML_AUTH)
capa.DisabledNatBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.False, cloudprovider.CLOUD_CAPABILITY_NAT)
capa.DisabledNasBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.False, cloudprovider.CLOUD_CAPABILITY_NAS)
capa.DisabledNasBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.False, cloudprovider.CLOUD_CAPABILITY_WAF)
return
}
+7 -1
View File
@@ -123,7 +123,13 @@ type pmCache struct {
func (self *pmCache) GetProjectMapping() (*SProjectMapping, error) {
if len(self.ManagerProjectMappingId) > 0 {
return GetRuleMapping(self.ManagerProjectMappingId)
pm, err := GetRuleMapping(self.ManagerProjectMappingId)
if err != nil {
return nil, errors.Wrapf(err, "GetRuleMapping(%s)", self.ManagerProjectMappingId)
}
if pm.Enabled.IsTrue() {
return pm, nil
}
}
if len(self.AccountProjectMappingId) > 0 {
return GetRuleMapping(self.AccountProjectMappingId)
+111
View File
@@ -868,6 +868,24 @@ func syncSkusFromPrivateCloud(ctx context.Context, userCred mcclient.TokenCreden
}
}
func syncAppGateways(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localRegion *SCloudregion, remoteRegion cloudprovider.ICloudRegion) {
apps, err := remoteRegion.GetICloudApplicationGateways()
if err != nil {
msg := fmt.Sprintf("GetICloudApplicationGateways for region %s failed %s", remoteRegion.GetName(), err)
log.Errorf(msg)
return
}
result := localRegion.SyncAppGateways(ctx, userCred, provider, apps)
syncResults.Add(AppGatewayManager, result)
msg := result.Result()
log.Infof("SyncAppGateways for region %s result: %s", localRegion.Name, msg)
if result.IsError() {
return
}
}
func syncRegionDBInstances(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localRegion *SCloudregion, remoteRegion cloudprovider.ICloudRegion, syncRange *SSyncRange) {
instances, err := remoteRegion.GetIDBInstances()
if err != nil {
@@ -1083,6 +1101,91 @@ func syncDBInstanceAccountPrivileges(ctx context.Context, userCred mcclient.Toke
return nil
}
func syncWafIPSets(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localRegion *SCloudregion, remoteRegion cloudprovider.ICloudRegion) error {
ipSets, err := remoteRegion.GetICloudWafIPSets()
if err != nil {
msg := fmt.Sprintf("GetICloudWafIPSets for region %s failed %s", remoteRegion.GetName(), err)
log.Errorf(msg)
return err
}
result := localRegion.SyncWafIPSets(ctx, userCred, provider, ipSets)
syncResults.Add(WafIPSetManager, result)
log.Infof("SyncWafIPSets for region %s result: %s", localRegion.Name, result.Result())
if result.IsError() {
return result.AllError()
}
return nil
}
func syncWafRegexSets(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localRegion *SCloudregion, remoteRegion cloudprovider.ICloudRegion) error {
rSets, err := remoteRegion.GetICloudWafRegexSets()
if err != nil {
msg := fmt.Sprintf("GetICloudWafRegexSets for region %s failed %s", remoteRegion.GetName(), err)
log.Errorf(msg)
return err
}
result := localRegion.SyncWafRegexSets(ctx, userCred, provider, rSets)
syncResults.Add(WafRegexSetManager, result)
log.Infof("SyncWafRegexSets for region %s result: %s", localRegion.Name, result.Result())
if result.IsError() {
return result.AllError()
}
return nil
}
func syncWafInstances(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localRegion *SCloudregion, remoteRegion cloudprovider.ICloudRegion) error {
wafIns, err := remoteRegion.GetICloudWafInstances()
if err != nil {
msg := fmt.Sprintf("GetICloudWafInstances for region %s failed %s", remoteRegion.GetName(), err)
log.Errorf(msg)
return err
}
localWafs, remoteWafs, result := localRegion.SyncWafInstances(ctx, userCred, provider, wafIns)
syncResults.Add(WafInstanceManager, result)
msg := result.Result()
log.Infof("SyncWafInstances for region %s result: %s", localRegion.Name, msg)
if result.IsError() {
return result.AllError()
}
for i := 0; i < len(localWafs); i++ {
func() {
lockman.LockObject(ctx, &localWafs[i])
defer lockman.ReleaseObject(ctx, &localWafs[i])
if localWafs[i].Deleted {
return
}
err = syncWafRules(ctx, userCred, syncResults, &localWafs[i], remoteWafs[i])
if err != nil {
log.Errorf("syncDBInstanceAccountPrivileges error: %v", err)
}
}()
}
return nil
}
func syncWafRules(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, localWaf *SWafInstance, remoteWafs cloudprovider.ICloudWafInstance) error {
rules, err := remoteWafs.GetRules()
if err != nil {
msg := fmt.Sprintf("GetRules for waf instance %s failed %s", localWaf.Name, err)
log.Errorf(msg)
return err
}
result := localWaf.SyncWafRules(ctx, userCred, rules)
syncResults.Add(WafRuleManager, result)
msg := result.Result()
log.Infof("SyncWafRules for waf %s result: %s", localWaf.Name, msg)
if result.IsError() {
return result.AllError()
}
return nil
}
func syncRegionSnapshots(ctx context.Context, userCred mcclient.TokenCredential, syncResults SSyncResultSet, provider *SCloudprovider, localRegion *SCloudregion, remoteRegion cloudprovider.ICloudRegion, syncRange *SSyncRange) {
snapshots, err := remoteRegion.GetISnapshots()
if err != nil {
@@ -1258,6 +1361,14 @@ func syncPublicCloudProviderInfo(
syncElasticcaches(ctx, userCred, syncResults, provider, localRegion, remoteRegion, syncRange)
}
syncAppGateways(ctx, userCred, syncResults, provider, localRegion, remoteRegion)
if utils.IsInStringArray(cloudprovider.CLOUD_CAPABILITY_WAF, driver.GetCapabilities()) {
syncWafIPSets(ctx, userCred, syncResults, provider, localRegion, remoteRegion)
syncWafRegexSets(ctx, userCred, syncResults, provider, localRegion, remoteRegion)
syncWafInstances(ctx, userCred, syncResults, provider, localRegion, remoteRegion)
}
if cloudprovider.IsSupportCompute(driver) {
log.Debugf("storageCachePairs count %d", len(storageCachePairs))
for i := range storageCachePairs {
+23 -10
View File
@@ -2455,7 +2455,7 @@ func (self *SHost) GetNetinterfacesWithIdAndCredential(netId string, userCred mc
if err != nil {
return nil, nil
}
if used == 0 && !reserved {
if used == 0 && !reserved && !options.Options.BaremetalServerReuseHostIp {
return nil, nil
}
matchNetIfs := make([]SNetInterface, 0)
@@ -2873,16 +2873,11 @@ func (self *SHost) getMoreDetails(ctx context.Context, out api.HostDetails, show
out.ServerIps = strings.Join(server.GetRealIPs(), ",")
}
}
netifs := self.GetNetInterfaces()
if netifs != nil && len(netifs) > 0 {
nics := self.GetNics()
if nics != nil && len(nics) > 0 {
nicInfos := []jsonutils.JSONObject{}
for i := 0; i < len(netifs); i += 1 {
nicInfo := netifs[i].getBaremetalJsonDesc()
if nicInfo == nil {
log.Errorf("netif %s get baremetal desc failed", netifs[i].GetId())
continue
}
nicInfos = append(nicInfos, nicInfo)
for i := 0; i < len(nics); i += 1 {
nicInfos = append(nicInfos, jsonutils.Marshal(nics[i]))
}
out.NicCount = len(nicInfos)
out.NicInfo = nicInfos
@@ -5651,6 +5646,24 @@ func (host *SHost) GetIpmiInfo() (types.SIPMIInfo, error) {
return info, nil
}
func (host *SHost) GetNics() []*types.SNic {
netifs := host.GetNetInterfaces()
nicInfos := []*types.SNic{}
if netifs != nil && len(netifs) > 0 {
for i := 0; i < len(netifs); i += 1 {
desc := netifs[i].getBaremetalJsonDesc()
if desc == nil {
log.Errorf("netif %s get baremetal desc failed", netifs[i].GetId())
continue
}
nicInfo := new(types.SNic)
desc.Unmarshal(nicInfo)
nicInfos = append(nicInfos, nicInfo)
}
}
return nicInfos
}
func (host *SHost) GetUEFIInfo() (*types.EFIBootMgrInfo, error) {
if host.UefiInfo == nil {
return nil, nil
+5
View File
@@ -1056,6 +1056,11 @@ func isValidNetworkInfo(userCred mcclient.TokenCredential, netConfig *api.Networ
if netConfig.BwLimit > api.MAX_BANDWIDTH {
return httperrors.NewInputParameterError("Bandwidth limit cannot exceed %dMbps", api.MAX_BANDWIDTH)
}
if net.ServerType == api.NETWORK_TYPE_BAREMETAL {
// not check baremetal network free address here
// TODO: find better solution ?
return nil
}
freeCnt, err := net.getFreeAddressCount()
if err != nil {
return httperrors.NewInternalServerError("getFreeAddressCount fail %s", err)
+7
View File
@@ -178,6 +178,13 @@ type IDBInstanceDriver interface {
IElasticIpDriver
INasDriver
IWafDriver
}
type IWafDriver interface {
ValidateCreateWafInstanceData(ctx context.Context, userCred mcclient.TokenCredential, input api.WafInstanceCreateInput) (api.WafInstanceCreateInput, error)
ValidateCreateWafRuleData(ctx context.Context, userCred mcclient.TokenCredential, waf *SWafInstance, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error)
}
type INasDriver interface {
+55
View File
@@ -52,6 +52,7 @@ type SSkuResourcesMeta struct {
ImageBase string `json:"image_base"`
NatBase string `json:"nat_base"`
NasBase string `json:"nas_base"`
WafBase string `json:"waf_base"`
}
var skuIndex = map[string]string{}
@@ -351,6 +352,19 @@ func (self *SSkuResourcesMeta) getServerSkuIndex() (map[string]string, error) {
return ret, nil
}
func (self *SSkuResourcesMeta) getWafIndex() (map[string]string, error) {
resp, err := self.request(fmt.Sprintf("%s/index.json", self.WafBase))
if err != nil {
return map[string]string{}, errors.Wrapf(err, "request")
}
ret := map[string]string{}
err = resp.Unmarshal(ret)
if err != nil {
return map[string]string{}, errors.Wrapf(err, "resp.Unmarshal")
}
return ret, nil
}
func (self *SSkuResourcesMeta) _get(url string) ([]jsonutils.JSONObject, error) {
if !strings.HasPrefix(url, "http") {
return nil, fmt.Errorf("SkuResourcesMeta.get invalid url %s.expected has prefix 'http'", url)
@@ -523,6 +537,20 @@ func FetchSkuResourcesMeta() (*SSkuResourcesMeta, error) {
return ret, nil
}
func fetchCloudEnvs() ([]string, error) {
accounts := []SCloudaccount{}
q := CloudaccountManager.Query("provider", "access_url").In("provider", CloudproviderManager.GetPublicProviderProvidersQuery()).Distinct()
err := q.All(&accounts)
if err != nil {
return nil, errors.Wrapf(err, "q.All")
}
ret := []string{}
for i := range accounts {
ret = append(ret, apis.GetCloudEnv(accounts[i].Provider, accounts[i].AccessUrl))
}
return ret, nil
}
func fetchSkuSyncCloudregions() []SCloudregion {
cloudregions := []SCloudregion{}
q := CloudregionManager.Query()
@@ -535,3 +563,30 @@ func fetchSkuSyncCloudregions() []SCloudregion {
return cloudregions
}
type sWafGroup struct {
SWafRuleGroup
Rules []SWafRule
}
func (self sWafGroup) GetGlobalId() string {
return self.ExternalId
}
func (self SWafRule) GetGlobalId() string {
return self.ExternalId
}
func (self *SSkuResourcesMeta) getCloudWafGroups(cloudEnv string) ([]sWafGroup, error) {
url := fmt.Sprintf("%s/%s.json", self.WafBase, cloudEnv)
resp, err := self.request(url)
if err != nil {
return nil, errors.Wrapf(err, "_get(%s)", url)
}
ret := []sWafGroup{}
err = resp.Unmarshal(&ret)
if err != nil {
return nil, errors.Wrapf(err, "resp.Unmarshal")
}
return ret, nil
}
+478
View File
@@ -0,0 +1,478 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"fmt"
"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"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafInstanceManager struct {
db.SEnabledStatusInfrasResourceBaseManager
db.SExternalizedResourceBaseManager
SManagedResourceBaseManager
SCloudregionResourceBaseManager
}
var WafInstanceManager *SWafInstanceManager
func init() {
WafInstanceManager = &SWafInstanceManager{
SEnabledStatusInfrasResourceBaseManager: db.NewEnabledStatusInfrasResourceBaseManager(
SWafInstance{},
"waf_instances_tbl",
"waf_instance",
"waf_instances",
),
}
WafInstanceManager.SetVirtualObject(WafInstanceManager)
}
type SWafInstance struct {
db.SEnabledStatusInfrasResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
SCloudregionResourceBase
Type cloudprovider.TWafType `width:"20" charset:"ascii" nullable:"false" list:"domain" create:"required"`
DefaultAction *cloudprovider.DefaultAction `charset:"ascii" nullable:"true" list:"domain" create:"domain_optional"`
}
func (manager *SWafInstanceManager) GetContextManagers() [][]db.IModelManager {
return [][]db.IModelManager{
{CloudregionManager},
}
}
func (manager *SWafInstanceManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.WafInstanceCreateInput) (api.WafInstanceCreateInput, error) {
_region, err := validators.ValidateModel(userCred, CloudregionManager, &input.CloudregionId)
if err != nil {
return input, err
}
region := _region.(*SCloudregion)
_provider, err := validators.ValidateModel(userCred, CloudproviderManager, &input.CloudproviderId)
if err != nil {
return input, err
}
provider := _provider.(*SCloudprovider)
if !provider.IsAvailable() {
return input, httperrors.NewInputParameterError("cloudprovider %s not available", provider.Name)
}
for i := range input.CloudResources {
switch input.CloudResources[i].Type {
case LoadbalancerManager.Keyword():
_lb, err := validators.ValidateModel(userCred, LoadbalancerManager, &input.CloudResources[i].Id)
if err != nil {
return input, err
}
lb := _lb.(*SLoadbalancer)
if lb.ManagerId != provider.GetId() {
return input, httperrors.NewConflictError("lb %s does not belong to account %s", lb.Name, provider.GetName())
}
case GuestManager.Keyword():
_server, err := validators.ValidateModel(userCred, GuestManager, &input.CloudResources[i].Id)
if err != nil {
return input, err
}
server := _server.(*SGuest)
host := server.GetHost()
if host.ManagerId != provider.GetId() {
return input, httperrors.NewConflictError("server %s does not belong to account %s", server.Name, provider.GetName())
}
default:
return input, httperrors.NewInputParameterError("invalid %d resource type %s", i, input.CloudResources[i].Type)
}
}
input, err = region.GetDriver().ValidateCreateWafInstanceData(ctx, userCred, input)
if err != nil {
return input, err
}
input.SetEnabled()
input.EnabledStatusInfrasResourceBaseCreateInput, err = manager.SEnabledStatusInfrasResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.EnabledStatusInfrasResourceBaseCreateInput)
if err != nil {
return input, err
}
return input, nil
}
func (self *SWafInstance) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
self.SEnabledStatusInfrasResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
self.StartCreateTask(ctx, userCred, data.(*jsonutils.JSONDict))
}
func (self *SWafInstance) StartCreateTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafCreateTask", self, userCred, params, "", "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_STATUS_CREATING, "")
return task.ScheduleRun(nil)
}
func (manager *SWafInstanceManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafInstanceDetails {
rows := make([]api.WafInstanceDetails, len(objs))
stdRows := manager.SEnabledStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
insIds := make([]string, len(objs))
for i := range rows {
rows[i] = api.WafInstanceDetails{
EnabledStatusInfrasResourceBaseDetails: stdRows[i],
ManagedResourceInfo: managerRows[i],
CloudregionResourceInfo: regionRows[i],
}
ins := objs[i].(*SWafInstance)
insIds[i] = ins.Id
}
type WafRule struct {
api.SWafRule
WafInstanceId string
}
rules := []WafRule{}
q := WafRuleManager.Query().In("waf_instance_id", insIds)
err := q.All(&rules)
if err != nil {
return rows
}
ruleMaps := map[string][]api.SWafRule{}
for _, rule := range rules {
_, ok := ruleMaps[rule.WafInstanceId]
if !ok {
ruleMaps[rule.WafInstanceId] = []api.SWafRule{}
}
ruleMaps[rule.WafInstanceId] = append(ruleMaps[rule.WafInstanceId], rule.SWafRule)
}
for i := range rows {
rows[i].Rules, _ = ruleMaps[insIds[i]]
}
return rows
}
// 列出WAF实例
func (manager *SWafInstanceManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafInstanceListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SEnabledStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.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")
}
q, err = manager.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SWafInstanceManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SEnabledStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SWafInstanceManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafInstanceListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SWafInstanceManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusInfrasResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ListItemExportKeys")
}
if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
}
}
if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
}
}
return q, nil
}
func (self *SCloudregion) GetWafInstances(managerId string) ([]SWafInstance, error) {
q := WafInstanceManager.Query().Equals("cloudregion_id", self.Id)
if len(managerId) > 0 {
q = q.Equals("manager_id", managerId)
}
wafs := []SWafInstance{}
err := db.FetchModelObjects(WafInstanceManager, q, &wafs)
return wafs, err
}
func (self *SCloudregion) SyncWafInstances(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, exts []cloudprovider.ICloudWafInstance) ([]SWafInstance, []cloudprovider.ICloudWafInstance, compare.SyncResult) {
lockman.LockRawObject(ctx, WafInstanceManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
defer lockman.ReleaseRawObject(ctx, WafInstanceManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
result := compare.SyncResult{}
localWafs := []SWafInstance{}
remoteWafs := []cloudprovider.ICloudWafInstance{}
dbWafs, err := self.GetWafInstances(provider.Id)
if err != nil {
result.Error(err)
return nil, nil, result
}
removed := make([]SWafInstance, 0)
commondb := make([]SWafInstance, 0)
commonext := make([]cloudprovider.ICloudWafInstance, 0)
added := make([]cloudprovider.ICloudWafInstance, 0)
if err := compare.CompareSets(dbWafs, exts, &removed, &commondb, &commonext, &added); err != nil {
result.Error(err)
return nil, nil, result
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err := commondb[i].SyncWithCloudWafInstance(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
syncMetadata(ctx, userCred, &commondb[i], commonext[i])
localWafs = append(localWafs, commondb[i])
remoteWafs = append(remoteWafs, commonext[i])
result.Update()
}
for i := 0; i < len(added); i++ {
newWaf, err := self.newFromCloudWafInstance(ctx, userCred, provider, added[i])
if err != nil {
result.AddError(err)
continue
}
syncMetadata(ctx, userCred, newWaf, added[i])
localWafs = append(localWafs, *newWaf)
remoteWafs = append(remoteWafs, added[i])
result.Add()
}
return localWafs, remoteWafs, result
}
func (self *SWafInstance) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred)
}
func (self *SWafInstance) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafDeleteTask", self, userCred, nil, "", "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (self *SWafInstance) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafInstance) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
rules, err := self.GetWafRules()
if err != nil {
return errors.Wrapf(err, "GetWafRules")
}
for i := range rules {
err = rules[i].RealDelete(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "Delete Rule %s", rules[i].Name)
}
}
return self.SEnabledStatusInfrasResourceBase.Delete(ctx, userCred)
}
func (self *SWafInstance) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.RealDelete(ctx, userCred)
}
func (self *SWafInstance) GetRegion() (*SCloudregion, error) {
region, err := CloudregionManager.FetchById(self.CloudregionId)
if err != nil {
return nil, errors.Wrapf(err, "CloudregionManager.FetchById")
}
return region.(*SCloudregion), nil
}
func (self *SWafInstance) GetIRegion() (cloudprovider.ICloudRegion, error) {
region, err := self.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
provider, err := self.GetDriver()
if err != nil {
return nil, errors.Wrapf(err, "GetDriver")
}
return provider.GetIRegionById(region.ExternalId)
}
func (self *SWafInstance) GetICloudWafInstance() (cloudprovider.ICloudWafInstance, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
iRegion, err := self.GetIRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetIRegion")
}
return iRegion.GetICloudWafInstanceById(self.ExternalId)
}
func (self *SWafInstance) SyncWithCloudWafInstance(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudWafInstance) error {
_, err := db.Update(self, func() error {
self.ExternalId = ext.GetGlobalId()
self.SetEnabled(ext.GetEnabled())
self.DefaultAction = ext.GetDefaultAction()
self.Status = ext.GetStatus()
return nil
})
return err
}
func (self *SCloudregion) newFromCloudWafInstance(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafInstance) (*SWafInstance, error) {
waf := &SWafInstance{}
waf.SetModelManager(WafInstanceManager, waf)
waf.SetEnabled(ext.GetEnabled())
waf.CloudregionId = self.Id
waf.ManagerId = provider.Id
waf.Status = ext.GetStatus()
waf.DefaultAction = ext.GetDefaultAction()
waf.Type = ext.GetWafType()
waf.ExternalId = ext.GetGlobalId()
var err = func() error {
lockman.LockRawObject(ctx, WafInstanceManager.Keyword(), "name")
defer lockman.ReleaseRawObject(ctx, WafInstanceManager.Keyword(), "name")
var err error
waf.Name, err = db.GenerateName(ctx, WafInstanceManager, userCred, ext.GetName())
if err != nil {
return errors.Wrapf(err, "db.GenerateName")
}
return WafInstanceManager.TableSpec().Insert(ctx, waf)
}()
if err != nil {
return nil, err
}
return waf, nil
}
func (self *SWafInstance) AllowGetDetailsCloudResources(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsDomainAllowGetSpec(userCred, self, "cloud-resources")
}
// 获取WAF绑定的资源列表
func (self *SWafInstance) GetDetailsCloudResources(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) ([]cloudprovider.SCloudResource, error) {
iWaf, err := self.GetICloudWafInstance()
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrapf(err, "GetICloudWafInstance"))
}
return iWaf.GetCloudResources()
}
func (self *SWafInstance) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "syncstatus")
}
// 同步WAF状态
func (self *SWafInstance) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WafSyncstatusInput) (jsonutils.JSONObject, error) {
return nil, StartResourceSyncStatusTask(ctx, userCred, self, "WafSyncstatusTask", "")
}
+367
View File
@@ -0,0 +1,367 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"fmt"
"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"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafIPSetCacheManager struct {
db.SStatusStandaloneResourceBaseManager
db.SExternalizedResourceBaseManager
SManagedResourceBaseManager
SCloudregionResourceBaseManager
}
var WafIPSetCacheManager *SWafIPSetCacheManager
func init() {
WafIPSetCacheManager = &SWafIPSetCacheManager{
SStatusStandaloneResourceBaseManager: db.NewStatusStandaloneResourceBaseManager(
SWafIPSetCache{},
"waf_ipset_caches_tbl",
"waf_ipset_cache",
"waf_ipset_caches",
),
}
WafIPSetCacheManager.SetVirtualObject(WafIPSetCacheManager)
}
type SWafIPSetCache struct {
db.SStatusStandaloneResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
SCloudregionResourceBase
Type cloudprovider.TWafType `width:"20" charset:"utf8" nullable:"false" list:"user"`
WafIPSetId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
}
func (manager *SWafIPSetCacheManager) GetContextManagers() [][]db.IModelManager {
return [][]db.IModelManager{
{CloudregionManager},
}
}
func (manager *SWafIPSetCacheManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafIPSetCacheDetails {
rows := make([]api.WafIPSetCacheDetails, len(objs))
ssRows := manager.SStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.WafIPSetCacheDetails{
StatusStandaloneResourceDetails: ssRows[i],
ManagedResourceInfo: managerRows[i],
CloudregionResourceInfo: regionRows[i],
}
}
return rows
}
// 列出WAF IPSet缓存
func (manager *SWafIPSetCacheManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafIPSetCacheListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBase.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")
}
q, err = manager.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SWafIPSetCacheManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SWafIPSetCacheManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafIPSetCacheListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SWafIPSetCacheManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusStandaloneResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.ListItemExportKeys")
}
if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
}
}
if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
}
}
return q, nil
}
func (self *SWafIPSetCache) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafIPSetCache) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SStatusStandaloneResourceBase.Delete(ctx, userCred)
}
func (self *SWafIPSetCache) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.RealDelete(ctx, userCred)
}
func (self *SWafIPSetCache) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred, "")
}
func (self *SWafIPSetCache) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafIPSetCacheDeleteTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_IPSET_STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (self *SWafIPSetCache) GetRegion() (*SCloudregion, error) {
region, err := CloudregionManager.FetchById(self.CloudregionId)
if err != nil {
return nil, errors.Wrapf(err, "CloudregionManager.FetchById")
}
return region.(*SCloudregion), nil
}
func (self *SWafIPSetCache) GetIRegion() (cloudprovider.ICloudRegion, error) {
region, err := self.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
provider, err := self.GetDriver()
if err != nil {
return nil, errors.Wrapf(err, "GetDriver")
}
return provider.GetIRegionById(region.ExternalId)
}
func (self *SWafIPSetCache) GetICloudWafIPSet() (cloudprovider.ICloudWafIPSet, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
iRegion, err := self.GetIRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetIRegion")
}
caches, err := iRegion.GetICloudWafIPSets()
if err != nil {
return nil, errors.Wrapf(err, "GetICloudWafIPSets")
}
for i := range caches {
if caches[i].GetGlobalId() == self.ExternalId {
return caches[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, self.ExternalId)
}
func (self *SWafIPSetCache) syncWithCloudIPSet(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudWafIPSet) error {
_, err := db.Update(self, func() error {
self.Status = api.WAF_IPSET_STATUS_AVAILABLE
self.Name = ext.GetName()
self.Description = ext.GetDesc()
return nil
})
return err
}
func (self *SCloudregion) GetIPSets(managerId string) ([]SWafIPSetCache, error) {
q := WafIPSetCacheManager.Query().Equals("cloudregion_id", self.Id)
if len(managerId) > 0 {
q = q.Equals("manager_id", managerId)
}
caches := []SWafIPSetCache{}
err := db.FetchModelObjects(WafIPSetCacheManager, q, &caches)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return caches, nil
}
func (self *SCloudregion) findOrCreateWafIPSet(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafIPSet) (*SWafIPSet, error) {
q := WafIPSetManager.Query().Equals("domain_id", provider.DomainId).Equals("addresses", ext.GetAddresses().String())
ipSets := []SWafIPSet{}
err := db.FetchModelObjects(WafIPSetManager, q, &ipSets)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
if len(ipSets) > 0 {
return &ipSets[0], nil
}
ipSet := &SWafIPSet{}
ipSet.SetModelManager(WafIPSetManager, ipSet)
ipSet.Name = ext.GetName()
ipSet.Status = api.WAF_IPSET_STATUS_AVAILABLE
ipSet.DomainId = provider.DomainId
addrs := ext.GetAddresses()
ipSet.Addresses = &addrs
return ipSet, WafIPSetManager.TableSpec().Insert(ctx, ipSet)
}
func (self *SCloudregion) newFromCloudWafIPSet(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafIPSet, ipSetId string) error {
cache := &SWafIPSetCache{}
cache.SetModelManager(WafIPSetCacheManager, cache)
cache.Name = ext.GetName()
cache.WafIPSetId = ipSetId
cache.CloudregionId = self.Id
cache.ManagerId = provider.Id
cache.ExternalId = ext.GetGlobalId()
cache.Status = api.WAF_IPSET_STATUS_AVAILABLE
cache.Type = ext.GetType()
cache.Description = ext.GetDesc()
return WafIPSetCacheManager.TableSpec().Insert(ctx, cache)
}
func (self *SCloudregion) SyncWafIPSets(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, exts []cloudprovider.ICloudWafIPSet) compare.SyncResult {
lockman.LockRawObject(ctx, WafIPSetCacheManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
defer lockman.ReleaseRawObject(ctx, WafIPSetCacheManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
result := compare.SyncResult{}
dbIPSets, err := self.GetIPSets(provider.Id)
if err != nil {
result.Error(err)
return result
}
removed := make([]SWafIPSetCache, 0)
commondb := make([]SWafIPSetCache, 0)
commonext := make([]cloudprovider.ICloudWafIPSet, 0)
added := make([]cloudprovider.ICloudWafIPSet, 0)
err = compare.CompareSets(dbIPSets, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err := commondb[i].syncWithCloudIPSet(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i++ {
ipSet, err := self.findOrCreateWafIPSet(ctx, userCred, provider, added[i])
if err != nil {
result.AddError(err)
continue
}
err = self.newFromCloudWafIPSet(ctx, userCred, provider, added[i], ipSet.Id)
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
+151
View File
@@ -0,0 +1,151 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafIPSetManager struct {
db.SStatusInfrasResourceBaseManager
}
var WafIPSetManager *SWafIPSetManager
func init() {
WafIPSetManager = &SWafIPSetManager{
SStatusInfrasResourceBaseManager: db.NewStatusInfrasResourceBaseManager(
SWafIPSet{},
"waf_ipsets_tbl",
"waf_ipset",
"waf_ipsets",
),
}
WafIPSetManager.SetVirtualObject(WafIPSetManager)
}
type SWafIPSet struct {
db.SStatusInfrasResourceBase
Addresses *cloudprovider.WafAddresses `list:"domain" update:"domain" create:"required"`
}
func (manager *SWafIPSetManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafIPSetDetails {
rows := make([]api.WafIPSetDetails, len(objs))
siRows := manager.SStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.WafIPSetDetails{
StatusInfrasResourceBaseDetails: siRows[i],
}
}
return rows
}
// 列出WAF IPSets
func (manager *SWafIPSetManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafIPSetListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SWafIPSetManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SWafIPSetManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafIPSetListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SWafIPSetManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusInfrasResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ListItemExportKeys")
}
return q, nil
}
func (self *SWafIPSet) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafIPSet) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SStatusInfrasResourceBase.Delete(ctx, userCred)
}
func (self *SWafIPSet) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred, "")
}
func (self *SWafIPSet) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafIPSetDeleteTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_IPSET_STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (self *SWafIPSet) GetCaches() ([]SWafIPSetCache, error) {
q := WafIPSetCacheManager.Query().Equals("waf_ipset_id", self.Id)
caches := []SWafIPSetCache{}
err := db.FetchModelObjects(WafIPSetCacheManager, q, &caches)
return caches, err
}
+367
View File
@@ -0,0 +1,367 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"fmt"
"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"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafRegexSetCacheManager struct {
db.SStatusStandaloneResourceBaseManager
db.SExternalizedResourceBaseManager
SManagedResourceBaseManager
SCloudregionResourceBaseManager
}
var WafRegexSetCacheManager *SWafRegexSetCacheManager
func init() {
WafRegexSetCacheManager = &SWafRegexSetCacheManager{
SStatusStandaloneResourceBaseManager: db.NewStatusStandaloneResourceBaseManager(
SWafRegexSetCache{},
"waf_regexset_caches_tbl",
"waf_regexset_cache",
"waf_regexset_caches",
),
}
WafRegexSetCacheManager.SetVirtualObject(WafRegexSetCacheManager)
}
type SWafRegexSetCache struct {
db.SStatusStandaloneResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
SCloudregionResourceBase
Type cloudprovider.TWafType `width:"20" charset:"utf8" nullable:"false" list:"user"`
WafRegexSetId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
}
func (manager *SWafRegexSetCacheManager) GetContextManagers() [][]db.IModelManager {
return [][]db.IModelManager{
{CloudregionManager},
}
}
func (manager *SWafRegexSetCacheManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafRegexSetCacheDetails {
rows := make([]api.WafRegexSetCacheDetails, len(objs))
ssRows := manager.SStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.WafRegexSetCacheDetails{
StatusStandaloneResourceDetails: ssRows[i],
ManagedResourceInfo: managerRows[i],
CloudregionResourceInfo: regionRows[i],
}
}
return rows
}
// 列出WAF RegexSet缓存
func (manager *SWafRegexSetCacheManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRegexSetCacheListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBase.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")
}
q, err = manager.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SWafRegexSetCacheManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SWafRegexSetCacheManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRegexSetCacheListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SWafRegexSetCacheManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusStandaloneResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.ListItemExportKeys")
}
if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
}
}
if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
}
}
return q, nil
}
func (self *SWafRegexSetCache) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafRegexSetCache) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SStatusStandaloneResourceBase.Delete(ctx, userCred)
}
func (self *SWafRegexSetCache) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.RealDelete(ctx, userCred)
}
func (self *SWafRegexSetCache) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred, "")
}
func (self *SWafRegexSetCache) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafRegexSetCacheDeleteTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_REGEX_SET_STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (self *SWafRegexSetCache) GetRegion() (*SCloudregion, error) {
region, err := CloudregionManager.FetchById(self.CloudregionId)
if err != nil {
return nil, errors.Wrapf(err, "CloudregionManager.FetchById")
}
return region.(*SCloudregion), nil
}
func (self *SWafRegexSetCache) GetIRegion() (cloudprovider.ICloudRegion, error) {
region, err := self.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
provider, err := self.GetDriver()
if err != nil {
return nil, errors.Wrapf(err, "GetDriver")
}
return provider.GetIRegionById(region.ExternalId)
}
func (self *SWafRegexSetCache) GetICloudWafRegexSet() (cloudprovider.ICloudWafRegexSet, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
iRegion, err := self.GetIRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetIRegion")
}
caches, err := iRegion.GetICloudWafRegexSets()
if err != nil {
return nil, errors.Wrapf(err, "GetICloudWafRegexSets")
}
for i := range caches {
if caches[i].GetGlobalId() == self.ExternalId {
return caches[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, self.ExternalId)
}
func (self *SWafRegexSetCache) syncWithCloudRegexSet(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudWafRegexSet) error {
_, err := db.Update(self, func() error {
self.Status = api.WAF_IPSET_STATUS_AVAILABLE
self.Name = ext.GetName()
self.Description = ext.GetDesc()
return nil
})
return err
}
func (self *SCloudregion) GetRegexSets(managerId string) ([]SWafRegexSetCache, error) {
q := WafRegexSetCacheManager.Query().Equals("cloudregion_id", self.Id)
if len(managerId) > 0 {
q = q.Equals("manager_id", managerId)
}
caches := []SWafRegexSetCache{}
err := db.FetchModelObjects(WafRegexSetCacheManager, q, &caches)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return caches, nil
}
func (self *SCloudregion) findOrCreateWafRegexSet(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafRegexSet) (*SWafRegexSet, error) {
q := WafRegexSetManager.Query().Equals("domain_id", provider.DomainId).Equals("regex_patterns", ext.GetRegexPatterns().String())
patternSets := []SWafRegexSet{}
err := db.FetchModelObjects(WafRegexSetManager, q, &patternSets)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
if len(patternSets) > 0 {
return &patternSets[0], nil
}
ps := &SWafRegexSet{}
ps.SetModelManager(WafRegexSetManager, ps)
ps.Name = ext.GetName()
ps.Status = api.WAF_IPSET_STATUS_AVAILABLE
ps.DomainId = provider.DomainId
patterns := ext.GetRegexPatterns()
ps.RegexPatterns = &patterns
return ps, WafRegexSetManager.TableSpec().Insert(ctx, ps)
}
func (self *SCloudregion) newFromCloudWafRegexSet(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafRegexSet, ipSetId string) error {
cache := &SWafRegexSetCache{}
cache.SetModelManager(WafRegexSetCacheManager, cache)
cache.Name = ext.GetName()
cache.WafRegexSetId = ipSetId
cache.CloudregionId = self.Id
cache.ManagerId = provider.Id
cache.ExternalId = ext.GetGlobalId()
cache.Status = api.WAF_IPSET_STATUS_AVAILABLE
cache.Type = ext.GetType()
cache.Description = ext.GetDesc()
return WafRegexSetCacheManager.TableSpec().Insert(ctx, cache)
}
func (self *SCloudregion) SyncWafRegexSets(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, exts []cloudprovider.ICloudWafRegexSet) compare.SyncResult {
lockman.LockRawObject(ctx, WafRegexSetCacheManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
defer lockman.ReleaseRawObject(ctx, WafRegexSetCacheManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
result := compare.SyncResult{}
dbRegexSets, err := self.GetRegexSets(provider.Id)
if err != nil {
result.Error(err)
return result
}
removed := make([]SWafRegexSetCache, 0)
commondb := make([]SWafRegexSetCache, 0)
commonext := make([]cloudprovider.ICloudWafRegexSet, 0)
added := make([]cloudprovider.ICloudWafRegexSet, 0)
err = compare.CompareSets(dbRegexSets, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err := commondb[i].syncWithCloudRegexSet(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i++ {
ipSet, err := self.findOrCreateWafRegexSet(ctx, userCred, provider, added[i])
if err != nil {
result.AddError(err)
continue
}
err = self.newFromCloudWafRegexSet(ctx, userCred, provider, added[i], ipSet.Id)
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
+151
View File
@@ -0,0 +1,151 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafRegexSetManager struct {
db.SStatusInfrasResourceBaseManager
}
var WafRegexSetManager *SWafRegexSetManager
func init() {
WafRegexSetManager = &SWafRegexSetManager{
SStatusInfrasResourceBaseManager: db.NewStatusInfrasResourceBaseManager(
SWafRegexSet{},
"waf_regexsets_tbl",
"waf_regexset",
"waf_regexsets",
),
}
WafRegexSetManager.SetVirtualObject(WafRegexSetManager)
}
type SWafRegexSet struct {
db.SStatusInfrasResourceBase
RegexPatterns *cloudprovider.WafRegexPatterns `list:"domain" update:"domain" create:"required"`
}
func (manager *SWafRegexSetManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafRegexSetDetails {
rows := make([]api.WafRegexSetDetails, len(objs))
siRows := manager.SStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.WafRegexSetDetails{
StatusInfrasResourceBaseDetails: siRows[i],
}
}
return rows
}
// 列出WAF RegexSets
func (manager *SWafRegexSetManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRegexSetListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SWafRegexSetManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SWafRegexSetManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRegexSetListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SWafRegexSetManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusInfrasResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ListItemExportKeys")
}
return q, nil
}
func (self *SWafRegexSet) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafRegexSet) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SStatusInfrasResourceBase.Delete(ctx, userCred)
}
func (self *SWafRegexSet) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred, "")
}
func (self *SWafRegexSet) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafRegexSetDeleteTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_REGEX_SET_STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (self *SWafRegexSet) GetCaches() ([]SWafRegexSetCache, error) {
q := WafRegexSetCacheManager.Query().Equals("waf_regexset_id", self.Id)
caches := []SWafRegexSetCache{}
err := db.FetchModelObjects(WafRegexSetCacheManager, q, &caches)
return caches, err
}
+367
View File
@@ -0,0 +1,367 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"fmt"
"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"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafRuleGroupCacheManager struct {
db.SStatusStandaloneResourceBaseManager
db.SExternalizedResourceBaseManager
SManagedResourceBaseManager
SCloudregionResourceBaseManager
}
var WafRuleGroupCacheManager *SWafRuleGroupCacheManager
func init() {
WafRuleGroupCacheManager = &SWafRuleGroupCacheManager{
SStatusStandaloneResourceBaseManager: db.NewStatusStandaloneResourceBaseManager(
SWafRuleGroupCache{},
"waf_rule_group_caches_tbl",
"waf_rule_group_cache",
"waf_rule_group_caches",
),
}
WafRuleGroupCacheManager.SetVirtualObject(WafRuleGroupCacheManager)
}
type SWafRuleGroupCache struct {
db.SStatusStandaloneResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
SCloudregionResourceBase
Type cloudprovider.TWafType `width:"20" charset:"utf8" nullable:"false" list:"user"`
WafRuleGroupId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
}
func (manager *SWafRuleGroupCacheManager) GetContextManagers() [][]db.IModelManager {
return [][]db.IModelManager{
{CloudregionManager},
}
}
func (manager *SWafRuleGroupCacheManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafRuleGroupCacheDetails {
rows := make([]api.WafRuleGroupCacheDetails, len(objs))
ssRows := manager.SStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.WafRuleGroupCacheDetails{
StatusStandaloneResourceDetails: ssRows[i],
ManagedResourceInfo: managerRows[i],
CloudregionResourceInfo: regionRows[i],
}
}
return rows
}
// 列出WAF RuleGroup缓存
func (manager *SWafRuleGroupCacheManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRuleGroupCacheListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBase.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")
}
q, err = manager.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SWafRuleGroupCacheManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SWafRuleGroupCacheManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRuleGroupCacheListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SWafRuleGroupCacheManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusStandaloneResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.ListItemExportKeys")
}
if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
}
}
if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
}
}
return q, nil
}
func (self *SWafRuleGroupCache) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafRuleGroupCache) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SStatusStandaloneResourceBase.Delete(ctx, userCred)
}
func (self *SWafRuleGroupCache) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.RealDelete(ctx, userCred)
}
func (self *SWafRuleGroupCache) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred, "")
}
func (self *SWafRuleGroupCache) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafRuleGroupCacheDeleteTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_RULE_GROUP_STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (self *SWafRuleGroupCache) GetRegion() (*SCloudregion, error) {
region, err := CloudregionManager.FetchById(self.CloudregionId)
if err != nil {
return nil, errors.Wrapf(err, "CloudregionManager.FetchById")
}
return region.(*SCloudregion), nil
}
func (self *SWafRuleGroupCache) GetIRegion() (cloudprovider.ICloudRegion, error) {
region, err := self.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
provider, err := self.GetDriver()
if err != nil {
return nil, errors.Wrapf(err, "GetDriver")
}
return provider.GetIRegionById(region.ExternalId)
}
func (self *SWafRuleGroupCache) GetICloudWafRuleGroup() (cloudprovider.ICloudWafRuleGroup, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
iRegion, err := self.GetIRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetIRegion")
}
caches, err := iRegion.GetICloudWafRuleGroups()
if err != nil {
return nil, errors.Wrapf(err, "GetICloudWafRuleGroups")
}
for i := range caches {
if caches[i].GetGlobalId() == self.ExternalId {
return caches[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, self.ExternalId)
}
func (self *SWafRuleGroupCache) syncWithCloudRuleGroup(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudWafRuleGroup) error {
_, err := db.Update(self, func() error {
self.Status = api.WAF_RULE_GROUP_STATUS_AVAILABLE
self.Name = ext.GetName()
self.Type = ext.GetWafType()
self.Description = ext.GetDesc()
return nil
})
return err
}
func (self *SCloudregion) GetRuleGroups(managerId string) ([]SWafRuleGroupCache, error) {
q := WafRuleGroupCacheManager.Query().Equals("cloudregion_id", self.Id)
if len(managerId) > 0 {
q = q.Equals("manager_id", managerId)
}
caches := []SWafRuleGroupCache{}
err := db.FetchModelObjects(WafRuleGroupCacheManager, q, &caches)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return caches, nil
}
func (self *SCloudregion) createWafRuleGroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafRuleGroup) (*SWafRuleGroup, error) {
rg := &SWafRuleGroup{}
rg.SetModelManager(WafRuleGroupManager, rg)
rg.Name = ext.GetName()
rg.Status = api.WAF_RULE_GROUP_STATUS_AVAILABLE
rg.Description = ext.GetDesc()
rg.DomainId = provider.DomainId
return rg, WafRuleGroupManager.TableSpec().Insert(ctx, rg)
}
func (self *SCloudregion) createRuleGroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafRuleGroup) (*SWafRuleGroup, error) {
rg := &SWafRuleGroup{}
rg.SetModelManager(WafRuleGroupManager, rg)
rg.Name = ext.GetName()
rg.Status = api.WAF_RULE_GROUP_STATUS_AVAILABLE
rg.Description = ext.GetDesc()
rg.DomainId = provider.DomainId
return rg, WafRuleGroupManager.TableSpec().Insert(ctx, rg)
}
func (self *SCloudregion) newFromCloudWafRuleGroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafRuleGroup) error {
rg, err := self.createRuleGroup(ctx, userCred, provider, ext)
if err != nil {
return errors.Wrapf(err, "createRuleGroup")
}
cache := &SWafRuleGroupCache{}
cache.SetModelManager(WafRuleGroupCacheManager, cache)
cache.Name = ext.GetName()
cache.WafRuleGroupId = rg.Id
cache.CloudregionId = self.Id
cache.ManagerId = provider.Id
cache.ExternalId = ext.GetGlobalId()
cache.Status = api.WAF_RULE_GROUP_STATUS_AVAILABLE
cache.Type = ext.GetWafType()
cache.Description = ext.GetDesc()
return WafRuleGroupCacheManager.TableSpec().Insert(ctx, cache)
}
func (self *SCloudregion) SyncWafRuleGroups(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, exts []cloudprovider.ICloudWafRuleGroup) compare.SyncResult {
lockman.LockRawObject(ctx, WafRuleGroupCacheManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
defer lockman.ReleaseRawObject(ctx, WafRuleGroupCacheManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
result := compare.SyncResult{}
dbRuleGroups, err := self.GetRuleGroups(provider.Id)
if err != nil {
result.Error(err)
return result
}
removed := make([]SWafRuleGroupCache, 0)
commondb := make([]SWafRuleGroupCache, 0)
commonext := make([]cloudprovider.ICloudWafRuleGroup, 0)
added := make([]cloudprovider.ICloudWafRuleGroup, 0)
err = compare.CompareSets(dbRuleGroups, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err := commondb[i].syncWithCloudRuleGroup(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i++ {
err = self.newFromCloudWafRuleGroup(ctx, userCred, provider, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
+305
View File
@@ -0,0 +1,305 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"yunion.io/x/jsonutils"
"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"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafRuleGroupManager struct {
db.SStatusInfrasResourceBaseManager
db.SExternalizedResourceBaseManager
}
var wafIndex map[string]string
var WafRuleGroupManager *SWafRuleGroupManager
func init() {
WafRuleGroupManager = &SWafRuleGroupManager{
SStatusInfrasResourceBaseManager: db.NewStatusInfrasResourceBaseManager(
SWafRuleGroup{},
"waf_rule_groups_tbl",
"waf_rule_group",
"waf_rule_groups",
),
}
wafIndex = map[string]string{}
WafRuleGroupManager.SetVirtualObject(WafRuleGroupManager)
}
type SWafRuleGroup struct {
db.SStatusInfrasResourceBase
db.SExternalizedResourceBase
// 支持的WAF类型,仅is_system=true时有效
WafType cloudprovider.TWafType `width:"40" charset:"ascii" list:"domain" nullable:"false"`
Provider string `width:"20" charset:"ascii" list:"domain" nullable:"false"`
CloudEnv string `width:"20" charset:"ascii" list:"domain" nullable:"false"`
IsSystem bool `nullable:"false" default:"false" list:"domain" update:"domain" create:"optional"`
}
func (manager *SWafRuleGroupManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafRuleGroupDetails {
rows := make([]api.WafRuleGroupDetails, len(objs))
siRows := manager.SStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.WafRuleGroupDetails{
StatusInfrasResourceBaseDetails: siRows[i],
}
}
return rows
}
// 列出WAF RuleGroups
func (manager *SWafRuleGroupManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRuleGroupListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ListItemFilter")
}
if query.IsSystem != nil {
q = q.Equals("is_system", *query.IsSystem)
}
if len(query.Provider) > 0 {
q = q.Equals("provider", query.Provider)
}
if len(query.CloudEnv) > 0 {
q = q.Equals("cloud_env", query.CloudEnv)
}
return q, nil
}
func (manager *SWafRuleGroupManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SWafRuleGroupManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRuleGroupListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SWafRuleGroupManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusInfrasResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ListItemExportKeys")
}
return q, nil
}
func (self *SWafRuleGroup) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafRuleGroup) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
rules, err := self.GetWafRules()
if err != nil {
return errors.Wrapf(err, "GetWafRules")
}
for i := range rules {
err = rules[i].Delete(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "Delete rule %s %s", rules[i].Id, rules[i].Name)
}
}
return self.SStatusInfrasResourceBase.Delete(ctx, userCred)
}
func (self *SSkuResourcesMeta) GetWafGroups(cloudEnv string) ([]SWafRuleGroup, error) {
q := WafRuleGroupManager.Query().Equals("cloud_env", cloudEnv).IsTrue("is_system")
groups := []SWafRuleGroup{}
err := db.FetchModelObjects(WafRuleGroupManager, q, &groups)
return groups, err
}
func (self *SWafRuleGroup) syncWithCloudSku(ctx context.Context, userCred mcclient.TokenCredential, ext sWafGroup) error {
_, err := db.Update(self, func() error {
self.Name = ext.Name
self.Description = ext.Description
self.IsPublic = true
self.Status = api.WAF_RULE_GROUP_STATUS_AVAILABLE
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update")
}
result, err := self.SyncManagedWafRules(ctx, userCred, ext.Rules)
if err != nil {
return errors.Wrapf(err, "SyncManagedWafRules")
}
log.Debugf("Sync waf group %s rule result: %s", self.Name, result.Result())
return nil
}
func (self *SSkuResourcesMeta) newFromCloudWafGroup(ctx context.Context, userCred mcclient.TokenCredential, ext sWafGroup) error {
group := &ext.SWafRuleGroup
group.SetModelManager(WafRuleGroupManager, group)
group.Status = api.WAF_RULE_GROUP_STATUS_AVAILABLE
group.IsPublic = true
err := WafRuleGroupManager.TableSpec().Insert(ctx, group)
if err != nil {
return errors.Wrapf(err, "Insert")
}
result, err := group.SyncManagedWafRules(ctx, userCred, ext.Rules)
if err != nil {
return errors.Wrapf(err, "SyncManagedWafRules")
}
log.Debugf("Sync waf group %s rule result: %s", group.Name, result.Result())
return nil
}
func (self *SSkuResourcesMeta) SyncWafGroups(ctx context.Context, userCred mcclient.TokenCredential, cloudEnv string) compare.SyncResult {
lockman.LockRawObject(ctx, cloudEnv, "waf-rule-group")
defer lockman.ReleaseRawObject(ctx, cloudEnv, "waf-rule-group")
result := compare.SyncResult{}
exts, err := self.getCloudWafGroups(cloudEnv)
if err != nil {
result.Error(errors.Wrapf(err, "getWafGroups(%s)", cloudEnv))
return result
}
dbGroup, err := self.GetWafGroups(cloudEnv)
if err != nil {
result.Error(errors.Wrapf(err, "GetWafGroups"))
return result
}
removed := make([]SWafRuleGroup, 0)
commondb := make([]SWafRuleGroup, 0)
commonext := make([]sWafGroup, 0)
added := make([]sWafGroup, 0)
err = compare.CompareSets(dbGroup, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i += 1 {
err = removed[i].RealDelete(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i += 1 {
err = commondb[i].syncWithCloudSku(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i += 1 {
err = self.newFromCloudWafGroup(ctx, userCred, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func SyncWafGroups(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
err := func() error {
cloudEnvs, err := fetchCloudEnvs()
if err != nil {
return errors.Wrapf(err, "fetchCloudEnvs")
}
meta, err := FetchSkuResourcesMeta()
if err != nil {
return errors.Wrapf(err, "FetchSkuResourcesMeta")
}
index, err := meta.getWafIndex()
if err != nil {
return errors.Wrapf(err, "getWafIndex")
}
for _, cloudEnv := range cloudEnvs {
newMd5, ok := index[cloudEnv]
if !ok {
continue
}
oldMd5, _ := wafIndex[cloudEnv]
if newMd5 == EMPTY_MD5 {
log.Infof("%s Waf group is empty skip syncing", cloudEnv)
continue
}
if len(oldMd5) > 0 && newMd5 == oldMd5 {
log.Infof("%s Waf group not Changed skip syncing", cloudEnv)
continue
}
result := meta.SyncWafGroups(ctx, userCred, cloudEnv)
log.Infof("sync %s waf group result: %s", cloudEnv, result.Result())
wafIndex[cloudEnv] = newMd5
}
return nil
}()
if err != nil {
log.Errorf("SyncWafGroups: error: %v", err)
}
}
+193
View File
@@ -0,0 +1,193 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/util/stringutils"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SWafRuleStatementManager struct {
db.SResourceBaseManager
}
var WafRuleStatementManager *SWafRuleStatementManager
func init() {
WafRuleStatementManager = &SWafRuleStatementManager{
SResourceBaseManager: db.NewResourceBaseManager(
SWafRuleStatement{},
"waf_rule_statements_tbl",
"waf_rule_statement",
"waf_rule_statements",
),
}
WafRuleStatementManager.SetVirtualObject(WafRuleStatementManager)
}
type SWafRuleStatement struct {
db.SResourceBase
Id string `width:"128" charset:"ascii" primary:"true" list:"user"`
cloudprovider.SWafStatement
WafRuleId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
}
func (self *SWafRuleStatement) BeforeInsert() {
if len(self.Id) == 0 {
self.Id = stringutils.UUID4()
}
}
func (self *SWafRuleStatement) GetId() string {
return self.Id
}
func (self *SWafRule) GetRuleStatements() ([]SWafRuleStatement, error) {
q := WafRuleStatementManager.Query().Equals("waf_rule_id", self.Id)
statements := []SWafRuleStatement{}
err := db.FetchModelObjects(WafRuleStatementManager, q, &statements)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return statements, nil
}
func (self *SWafRuleStatement) syncWithStatement(ctx context.Context, userCred mcclient.TokenCredential, statement cloudprovider.SWafStatement) error {
_, err := db.Update(self, func() error {
self.SWafStatement = statement
switch self.Type {
case cloudprovider.WafStatementTypeIPSet:
if len(self.IPSetId) > 0 {
_cache, err := db.FetchByExternalId(WafIPSetCacheManager, self.IPSetId)
if err != nil {
log.Errorf("WafIPSetCacheManager(%s) error: %v", self.IPSetId, err)
} else {
cache := _cache.(*SWafIPSetCache)
self.IPSetId = cache.WafIPSetId
}
}
case cloudprovider.WafStatementTypeRegexSet:
if len(self.RegexSetId) > 0 {
_cache, err := db.FetchByExternalId(WafRegexSetCacheManager, self.RegexSetId)
if err != nil {
log.Errorf("WafRegexSetCacheManager(%s) error: %v", self.RegexSetId, err)
} else {
cache := _cache.(*SWafRegexSetCache)
self.RegexSetId = cache.WafRegexSetId
}
}
}
return nil
})
return err
}
func (self *SWafRule) newFromCloudStatement(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.SWafStatement) error {
statement := &SWafRuleStatement{}
statement.SetModelManager(WafRuleStatementManager, statement)
statement.WafRuleId = self.Id
statement.SWafStatement = ext
switch statement.Type {
case cloudprovider.WafStatementTypeIPSet:
if len(statement.IPSetId) > 0 {
_cache, err := db.FetchByExternalId(WafIPSetCacheManager, statement.IPSetId)
if err != nil {
log.Errorf("WafIPSetCacheManager(%s) error: %v", statement.IPSetId, err)
} else {
cache := _cache.(*SWafIPSetCache)
statement.IPSetId = cache.WafIPSetId
}
}
case cloudprovider.WafStatementTypeRegexSet:
if len(statement.RegexSetId) > 0 {
_cache, err := db.FetchByExternalId(WafRegexSetCacheManager, statement.RegexSetId)
if err != nil {
log.Errorf("WafRegexSetCacheManager(%s) error: %v", statement.RegexSetId, err)
} else {
cache := _cache.(*SWafRegexSetCache)
statement.RegexSetId = cache.WafRegexSetId
}
}
}
return WafRuleStatementManager.TableSpec().Insert(ctx, statement)
}
func (self *SWafRule) SyncStatements(ctx context.Context, userCred mcclient.TokenCredential, rule cloudprovider.ICloudWafRule) error {
lockman.LockRawObject(ctx, WafRuleManager.Keyword(), self.Id)
defer lockman.ReleaseRawObject(ctx, WafRuleManager.Keyword(), self.Id)
dbStatements, err := self.GetRuleStatements()
if err != nil {
return errors.Wrapf(err, "GetRuleStatements")
}
exts, err := rule.GetStatements()
if err != nil {
return errors.Wrapf(err, "GetStatements")
}
result := compare.SyncResult{}
removed := make([]SWafRuleStatement, 0)
commondb := make([]SWafRuleStatement, 0)
commonext := make([]cloudprovider.SWafStatement, 0)
added := make([]cloudprovider.SWafStatement, 0)
err = compare.CompareSets(dbStatements, exts, &removed, &commondb, &commonext, &added)
if err != nil {
return errors.Wrapf(err, "compare.CompareSets")
}
for i := 0; i < len(removed); i++ {
err := removed[i].Delete(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err := commondb[i].syncWithStatement(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i++ {
err := self.newFromCloudStatement(ctx, userCred, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
log.Debugf("sync statements for rule %s result: %s", self.Name, result.Result())
return nil
}
+583
View File
@@ -0,0 +1,583 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"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"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/rbacutils"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafRuleManager struct {
db.SStatusStandaloneResourceBaseManager
db.SExternalizedResourceBaseManager
}
var WafRuleManager *SWafRuleManager
func init() {
WafRuleManager = &SWafRuleManager{
SStatusStandaloneResourceBaseManager: db.NewStatusStandaloneResourceBaseManager(
SWafRule{},
"waf_rules_tbl",
"waf_rule",
"waf_rules",
),
}
WafRuleManager.SetVirtualObject(WafRuleManager)
}
type SWafRule struct {
db.SStatusStandaloneResourceBase
db.SExternalizedResourceBase
// 规则优先级
Priority int `nullable:"false" list:"domain" create:"required"`
// 规则默认行为
Action *cloudprovider.DefaultAction `charset:"utf8" nullable:"false" list:"user" update:"domain" create:"required"`
// 条件
StatementConditon cloudprovider.TWafStatementCondition `width:"20" charset:"ascii" nullable:"false" list:"domain" create:"optional"`
// 规则组的id
WafRuleGroupId string `width:"36" charset:"ascii" nullable:"false" list:"domain" create:"optional"`
// 所属waf实例id
WafInstanceId string `width:"36" charset:"ascii" nullable:"false" list:"domain" create:"optional"`
}
func (manager *SWafRuleManager) FetchUniqValues(ctx context.Context, data jsonutils.JSONObject) jsonutils.JSONObject {
values := struct {
WafRuleGroupId string
WafInstanceId string
}{}
data.Unmarshal(&values)
return jsonutils.Marshal(values)
}
func (manager *SWafRuleManager) FilterByUniqValues(q *sqlchemy.SQuery, values jsonutils.JSONObject) *sqlchemy.SQuery {
data := struct {
WafRuleGroupId string
WafInstanceId string
}{}
if len(data.WafRuleGroupId) > 0 {
q = q.Equals("waf_rule_group_id", data.WafRuleGroupId)
}
if len(data.WafInstanceId) > 0 {
q = q.Equals("waf_instance_id", data.WafInstanceId)
}
return q
}
func (manager *SWafRuleManager) FetchOwnerId(ctx context.Context, data jsonutils.JSONObject) (mcclient.IIdentityProvider, error) {
values := struct {
WafRuleGroupId string
WafInstanceId string
}{}
data.Unmarshal(&values)
if len(values.WafInstanceId) > 0 {
ins, err := db.FetchById(WafInstanceManager, values.WafInstanceId)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchById(WafInstanceManager, %s)", values.WafInstanceId)
}
waf := ins.(*SWafInstance)
return waf.GetOwnerId(), nil
}
if len(values.WafRuleGroupId) > 0 {
rg, err := db.FetchById(WafRuleGroupManager, values.WafRuleGroupId)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchById(WafRuleGroupManager, %s)", values.WafRuleGroupId)
}
return rg.GetOwnerId(), nil
}
return db.FetchDomainInfo(ctx, data)
}
func (manager *SWafRuleManager) FilterByOwner(q *sqlchemy.SQuery, userCred mcclient.IIdentityProvider, scope rbacutils.TRbacScope) *sqlchemy.SQuery {
sq1 := WafInstanceManager.Query("id")
sq1 = db.SharableManagerFilterByOwner(WafInstanceManager, sq1, userCred, scope)
sq2 := WafRuleGroupManager.Query("id")
sq2 = db.SharableManagerFilterByOwner(WafRuleGroupManager, sq2, userCred, scope)
return q.Filter(sqlchemy.OR(
sqlchemy.In(q.Field("waf_instance_id"), sq1.SubQuery()),
sqlchemy.In(q.Field("waf_rule_group_id"), sq2.SubQuery()),
))
}
func (manager *SWafRuleManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error) {
if len(input.WafInstanceId) > 0 {
ins, err := validators.ValidateModel(userCred, WafInstanceManager, &input.WafInstanceId)
if err != nil {
return input, err
}
waf := ins.(*SWafInstance)
if waf.Status != api.WAF_STATUS_AVAILABLE {
return input, httperrors.NewInvalidStatusError("waf %s status is not available", waf.Name)
}
region, err := waf.GetRegion()
if err != nil {
return input, httperrors.NewGeneralError(errors.Wrapf(err, "GetRegion"))
}
input, err = region.GetDriver().ValidateCreateWafRuleData(ctx, userCred, waf, input)
if err != nil {
return input, err
}
} else if len(input.WafRuleGroupId) > 0 {
return input, httperrors.NewInputParameterError("not implement")
} else {
return input, httperrors.NewMissingParameterError("waf_instance_id")
}
var err error
input.StatusStandaloneResourceCreateInput, err = manager.SStatusStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.StatusStandaloneResourceCreateInput)
if err != nil {
return input, err
}
return input, nil
}
func (self *SWafRule) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
self.SStatusStandaloneResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
input := &api.WafRuleCreateInput{}
data.Unmarshal(input)
for _, s := range input.Statements {
statement := &SWafRuleStatement{}
statement.SetModelManager(WafRuleStatementManager, statement)
statement.SWafStatement = s
statement.WafRuleId = self.Id
WafRuleStatementManager.TableSpec().Insert(ctx, statement)
}
self.StartCreateTask(ctx, userCred)
}
func (self *SWafRule) StartCreateTask(ctx context.Context, userCred mcclient.TokenCredential) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafRuleCreateTask", self, userCred, nil, "", "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_RULE_STATUS_CREATING, "")
return task.ScheduleRun(nil)
}
// 列出WAF规则
func (manager *SWafRuleManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRuleListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusStandaloneResourceBaseManager.ListItemFilter")
}
q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
}
if len(query.WafInstanceId) > 0 {
_, err := validators.ValidateModel(userCred, WafInstanceManager, &query.WafInstanceId)
if err != nil {
return nil, err
}
q = q.Equals("waf_instance_id", query.WafInstanceId)
}
if len(query.WafRuleGroupId) > 0 {
_, err := validators.ValidateModel(userCred, WafRuleGroupManager, &query.WafRuleGroupId)
if err != nil {
return nil, err
}
q = q.Equals("waf_rule_group_id", query.WafRuleGroupId)
}
return q, nil
}
func (manager *SWafRuleManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafRuleDetails {
rows := make([]api.WafRuleDetails, len(objs))
stdRows := manager.SStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
ruleIds := make([]string, len(objs))
for i := range rows {
rows[i] = api.WafRuleDetails{
StatusStandaloneResourceDetails: stdRows[i],
}
ruleIds[i] = objs[i].(*SWafRule).Id
}
q := WafRuleStatementManager.Query().In("waf_rule_id", ruleIds)
statements := []SWafRuleStatement{}
err := q.All(&statements)
if err != nil {
return rows
}
statementMaps := map[string][]cloudprovider.SWafStatement{}
for i := range statements {
_, ok := statementMaps[statements[i].WafRuleId]
if !ok {
statementMaps[statements[i].WafRuleId] = []cloudprovider.SWafStatement{}
}
statementMaps[statements[i].WafRuleId] = append(statementMaps[statements[i].WafRuleId], statements[i].SWafStatement)
}
for i := range rows {
rows[i].Statements, _ = statementMaps[ruleIds[i]]
}
return rows
}
func (self *SWafRule) GetWafInstance() (*SWafInstance, error) {
waf, err := WafInstanceManager.FetchById(self.WafInstanceId)
if err != nil {
return nil, errors.Wrapf(err, "WafInstanceManager.FetchById(%s)", self.WafInstanceId)
}
return waf.(*SWafInstance), nil
}
func (self *SWafRule) GetWafRuleGroup() (*SWafRuleGroup, error) {
rg, err := WafRuleGroupManager.FetchById(self.WafRuleGroupId)
if err != nil {
return nil, errors.Wrapf(err, "WafRuleGroupManager.FetchById(%s)", self.WafRuleGroupId)
}
return rg.(*SWafRuleGroup), nil
}
func (self *SWafRule) GetOwnerId() mcclient.IIdentityProvider {
if len(self.WafInstanceId) > 0 {
ins, err := self.GetWafInstance()
if err != nil {
return nil
}
return ins.GetOwnerId()
}
if len(self.WafRuleGroupId) > 0 {
rg, err := self.GetWafRuleGroup()
if err != nil {
return nil
}
return rg.GetOwnerId()
}
return nil
}
func (manager *SWafRuleManager) ResourceScope() rbacutils.TRbacScope {
return rbacutils.ScopeDomain
}
func (self *SWafInstance) GetWafRules() ([]SWafRule, error) {
q := WafRuleManager.Query().Equals("waf_instance_id", self.Id)
rules := []SWafRule{}
err := db.FetchModelObjects(WafRuleManager, q, &rules)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return rules, nil
}
func (self *SWafRule) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred)
}
func (self *SWafRule) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafRuleDeleteTask", self, userCred, nil, "", "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_RULE_STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (self *SWafRule) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafRule) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
statements, err := self.GetRuleStatements()
if err != nil {
return errors.Wrapf(err, "GetRuleStatements")
}
for i := range statements {
err = statements[i].Delete(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "Delete statement %s(%s)", statements[i].Type, statements[i].MatchField)
}
}
return self.SStatusStandaloneResourceBase.Delete(ctx, userCred)
}
func (self *SWafRule) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.RealDelete(ctx, userCred)
}
func (self *SWafRule) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WafRuleUpdateInput) (api.WafRuleUpdateInput, error) {
var err error
if len(input.Name) > 0 && input.Name != self.Name {
return input, httperrors.NewInputParameterError("Not allow update rule name")
}
input.StatusStandaloneResourceBaseUpdateInput, err = self.SStatusStandaloneResourceBase.ValidateUpdateData(ctx, userCred, query, input.StatusStandaloneResourceBaseUpdateInput)
if err != nil {
return input, err
}
return input, nil
}
func (self *SWafRule) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) {
self.SStatusStandaloneResourceBase.PostUpdate(ctx, userCred, query, data)
input := api.WafRuleUpdateInput{}
data.Unmarshal(&input)
statements, err := self.GetRuleStatements()
if err != nil {
return
}
for i := len(input.Statements); i < len(statements); i++ {
statements[i].Delete(ctx, userCred)
}
for i := len(statements); i < len(input.Statements); i++ {
statement := &SWafRuleStatement{}
statement.SetModelManager(WafRuleStatementManager, statement)
statement.SWafStatement = input.Statements[i]
statement.WafRuleId = self.Id
WafRuleStatementManager.TableSpec().Insert(ctx, statement)
}
for i := 0; i < len(input.Statements) && i < len(statements); i++ {
db.Update(&statements[i], func() error {
statements[i].SWafStatement = input.Statements[i]
return nil
})
}
self.StartUpdateTask(ctx, userCred, "")
}
func (self *SWafRule) StartUpdateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafRuleUpdateTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_RULE_STATUS_UPDATING, "")
return task.ScheduleRun(nil)
}
func (self *SWafRule) SyncWithCloudRule(ctx context.Context, userCred mcclient.TokenCredential, rule cloudprovider.ICloudWafRule) error {
_, err := db.Update(self, func() error {
self.Action = rule.GetAction()
self.StatementConditon = rule.GetStatementCondition()
self.Priority = rule.GetPriority()
self.Status = api.WAF_RULE_STATUS_AVAILABLE
self.Name = rule.GetName()
self.ExternalId = rule.GetGlobalId()
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update")
}
return self.SyncStatements(ctx, userCred, rule)
}
func (self *SWafInstance) newFromCloudRule(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudWafRule) error {
rule := &SWafRule{}
rule.SetModelManager(WafRuleManager, rule)
rule.WafInstanceId = self.Id
rule.Name = ext.GetName()
rule.Description = ext.GetDesc()
rule.ExternalId = ext.GetGlobalId()
rule.Action = ext.GetAction()
rule.StatementConditon = ext.GetStatementCondition()
rule.Priority = ext.GetPriority()
rule.Status = api.WAF_RULE_STATUS_AVAILABLE
err := WafRuleManager.TableSpec().Insert(ctx, rule)
if err != nil {
return errors.Wrapf(err, "Insert")
}
return rule.SyncStatements(ctx, userCred, ext)
}
func (self *SWafInstance) SyncWafRules(ctx context.Context, userCred mcclient.TokenCredential, exts []cloudprovider.ICloudWafRule) compare.SyncResult {
lockman.LockRawObject(ctx, WafInstanceManager.Keyword(), self.Id)
defer lockman.ReleaseRawObject(ctx, WafInstanceManager.Keyword(), self.Id)
result := compare.SyncResult{}
dbRules, err := self.GetWafRules()
if err != nil {
result.Error(err)
return result
}
removed := make([]SWafRule, 0)
commondb := make([]SWafRule, 0)
commonext := make([]cloudprovider.ICloudWafRule, 0)
added := make([]cloudprovider.ICloudWafRule, 0)
if err := compare.CompareSets(dbRules, exts, &removed, &commondb, &commonext, &added); err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err := commondb[i].SyncWithCloudRule(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i++ {
err := self.newFromCloudRule(ctx, userCred, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func (self *SWafRuleGroup) GetWafRules() ([]SWafRule, error) {
q := WafRuleManager.Query().Equals("waf_rule_group_id", self.Id)
rules := []SWafRule{}
err := db.FetchModelObjects(WafRuleManager, q, &rules)
return rules, err
}
func (self *SWafRuleGroup) newFromManagedRule(ctx context.Context, userCred mcclient.TokenCredential, ext SWafRule) error {
ext.SetModelManager(WafRuleManager, &ext)
ext.WafRuleGroupId = self.Id
return WafRuleManager.TableSpec().Insert(ctx, &ext)
}
func (self *SWafRuleGroup) SyncManagedWafRules(ctx context.Context, userCred mcclient.TokenCredential, exts []SWafRule) (compare.SyncResult, error) {
lockman.LockRawObject(ctx, WafRuleGroupManager.Keyword(), self.Id)
defer lockman.ReleaseRawObject(ctx, WafRuleGroupManager.Keyword(), self.Id)
result := compare.SyncResult{}
dbRules, err := self.GetWafRules()
if err != nil {
return result, errors.Wrapf(err, "GetWafRules")
}
removed := make([]SWafRule, 0)
commondb := make([]SWafRule, 0)
commonext := make([]SWafRule, 0)
added := make([]SWafRule, 0)
err = compare.CompareSets(dbRules, exts, &removed, &commondb, &commonext, &added)
if err != nil {
return result, errors.Wrapf(err, "compare.CompareSets")
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(added); i++ {
err := self.newFromManagedRule(ctx, userCred, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result, nil
}
func (self *SWafRule) GetICloudWafInstance() (cloudprovider.ICloudWafInstance, error) {
ins, err := self.GetWafInstance()
if err != nil {
return nil, errors.Wrapf(err, "GetWafInstance")
}
iWaf, err := ins.GetICloudWafInstance()
if err != nil {
return nil, errors.Wrapf(err, "GetICloudWafInstance")
}
return iWaf, nil
}
func (self *SWafRule) GetICloudWafRule() (cloudprovider.ICloudWafRule, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
if len(self.WafInstanceId) > 0 {
iWaf, err := self.GetICloudWafInstance()
if err != nil {
return nil, errors.Wrapf(err, "GetICloudWafInstance")
}
rules, err := iWaf.GetRules()
if err != nil {
return nil, errors.Wrapf(err, "GetWafRules")
}
for i := range rules {
if rules[i].GetGlobalId() == self.ExternalId {
return rules[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, self.ExternalId)
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "")
}
func (self *SWafRule) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
ins, _ := self.GetWafInstance()
if ins != nil {
return ins.IsOwner(userCred) || db.IsDomainAllowPerform(userCred, self, "syncstatus")
}
return db.IsDomainAllowPerform(userCred, self, "syncstatus")
}
// 同步WAF规则状态
func (self *SWafRule) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WafSyncstatusInput) (jsonutils.JSONObject, error) {
return nil, StartResourceSyncStatusTask(ctx, userCred, self, "WafRuleSyncstatusTask", "")
}
+12
View File
@@ -162,6 +162,18 @@ var (
Extra: []string{"saml"},
Result: rbacutils.Allow,
},
{
Service: api.SERVICE_TYPE,
Resource: "waf_rules",
Action: PolicyActionGet,
Result: rbacutils.Allow,
},
{
Service: api.SERVICE_TYPE,
Resource: "waf_rules",
Action: PolicyActionList,
Result: rbacutils.Allow,
},
},
},
{
+6
View File
@@ -58,6 +58,12 @@ var (
"policy_assignments",
"proxysettings",
"project_mappings",
"app_gateways",
"waf_instances",
"waf_rules",
"waf_rule_groups",
"waf_ipsets",
"waf_regexsets",
}
computeUserResources = []string{
"keypairs",
+16
View File
@@ -25,6 +25,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/regutils"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
@@ -1530,3 +1531,18 @@ func (self *SAliyunRegionDriver) RequestSyncAccessGroup(ctx context.Context, use
})
return nil
}
func (self *SAliyunRegionDriver) ValidateCreateWafInstanceData(ctx context.Context, userCred mcclient.TokenCredential, input api.WafInstanceCreateInput) (api.WafInstanceCreateInput, error) {
if !regutils.DOMAINNAME_REG.MatchString(input.Name) {
return input, httperrors.NewInputParameterError("invalid domain name %s", input.Name)
}
input.Type = cloudprovider.WafTypeDefault
if len(input.SourceIps) == 0 && len(input.CloudResources) == 0 {
return input, httperrors.NewMissingParameterError("source_ips")
}
return input, nil
}
func (self *SAliyunRegionDriver) ValidateCreateWafRuleData(ctx context.Context, userCred mcclient.TokenCredential, waf *models.SWafInstance, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error) {
return input, httperrors.NewUnsupportOperationError("not supported create rule")
}
+30
View File
@@ -1559,3 +1559,33 @@ func (self *SAwsRegionDriver) RequestAssociateEip(ctx context.Context, userCred
})
return nil
}
func (self *SAwsRegionDriver) ValidateCreateWafInstanceData(ctx context.Context, userCred mcclient.TokenCredential, input api.WafInstanceCreateInput) (api.WafInstanceCreateInput, error) {
if len(input.Type) == 0 {
input.Type = cloudprovider.WafTypeRegional
}
switch input.Type {
case cloudprovider.WafTypeRegional:
case cloudprovider.WafTypeCloudFront:
_region, err := models.CloudregionManager.FetchById(input.CloudregionId)
if err != nil {
return input, err
}
region := _region.(*models.SCloudregion)
if !strings.HasSuffix(region.ExternalId, "us-east-1") {
return input, httperrors.NewUnsupportOperationError("only us-east-1 support %s", input.Type)
}
default:
return input, httperrors.NewInputParameterError("Invalid aws waf type %s", input.Type)
}
if input.DefaultAction == nil {
input.DefaultAction = &cloudprovider.DefaultAction{
Action: cloudprovider.WafActionAllow,
}
}
return input, nil
}
func (self *SAwsRegionDriver) ValidateCreateWafRuleData(ctx context.Context, userCred mcclient.TokenCredential, waf *models.SWafInstance, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error) {
return input, nil
}
+28
View File
@@ -83,3 +83,31 @@ func (self *SAzureRegionDriver) ValidateCreateVpcData(ctx context.Context, userC
}
return input, nil
}
func (self *SAzureRegionDriver) ValidateCreateWafInstanceData(ctx context.Context, userCred mcclient.TokenCredential, input api.WafInstanceCreateInput) (api.WafInstanceCreateInput, error) {
if len(input.Type) == 0 {
input.Type = cloudprovider.WafTypeAppGateway
}
switch input.Type {
case cloudprovider.WafTypeAppGateway:
default:
return input, httperrors.NewInputParameterError("Invalid azure waf type %s", input.Type)
}
if input.DefaultAction == nil {
input.DefaultAction = &cloudprovider.DefaultAction{}
}
if len(input.DefaultAction.Action) == 0 {
input.DefaultAction.Action = cloudprovider.WafActionDetection
}
switch input.DefaultAction.Action {
case cloudprovider.WafActionPrevention:
case cloudprovider.WafActionDetection:
default:
return input, httperrors.NewInputParameterError("invalid default action %s", input.DefaultAction.Action)
}
return input, nil
}
func (self *SAzureRegionDriver) ValidateCreateWafRuleData(ctx context.Context, userCred mcclient.TokenCredential, waf *models.SWafInstance, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error) {
return input, nil
}
+8
View File
@@ -451,3 +451,11 @@ func (self *SBaseRegionDriver) RequestAssociatEip(ctx context.Context, userCred
func (self *SBaseRegionDriver) RequestSyncAccessGroup(ctx context.Context, userCred mcclient.TokenCredential, fs *models.SFileSystem, mt *models.SMountTarget, ag *models.SAccessGroup, task taskman.ITask) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestSyncAccessGroup")
}
func (self *SBaseRegionDriver) ValidateCreateWafInstanceData(ctx context.Context, userCred mcclient.TokenCredential, input api.WafInstanceCreateInput) (api.WafInstanceCreateInput, error) {
return input, errors.Wrapf(cloudprovider.ErrNotImplemented, "ValidateCreateWafInstanceData")
}
func (self *SBaseRegionDriver) ValidateCreateWafRuleData(ctx context.Context, userCred mcclient.TokenCredential, waf *models.SWafInstance, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error) {
return input, errors.Wrapf(cloudprovider.ErrNotImplemented, "ValidateCreateWafRuleData")
}
+12
View File
@@ -93,6 +93,8 @@ func InitHandlers(app *appsrv.Application) {
models.ScheduledTaskLabelManager,
models.DnsRecordSetTrafficPolicyManager,
models.CloudimageManager,
models.WafRuleStatementManager,
} {
db.RegisterModelManager(manager)
}
@@ -214,6 +216,16 @@ func InitHandlers(app *appsrv.Application) {
models.MountTargetManager,
models.ProjectMappingManager,
models.AppGatewayManager,
models.WafRuleGroupManager,
models.WafIPSetManager,
models.WafIPSetCacheManager,
models.WafRegexSetManager,
models.WafRegexSetCacheManager,
models.WafInstanceManager,
models.WafRuleManager,
} {
db.RegisterModelManager(manager)
handler := db.NewModelHandler(manager)
+1
View File
@@ -152,6 +152,7 @@ func StartService() {
cron.AddJobEveryFewHour("SnapshotsCleanup", 1, 35, 0, models.SnapshotManager.CleanupSnapshots, false)
cron.AddJobAtIntervalsWithStartRun("SyncSkus", time.Duration(opts.ServerSkuSyncIntervalMinutes)*time.Minute, models.SyncServerSkus, true)
cron.AddJobAtIntervalsWithStartRun("SyncManagedWafGroups", time.Duration(opts.ServerSkuSyncIntervalMinutes)*time.Minute, models.SyncWafGroups, true)
cron.AddJobEveryFewDays("SyncDBInstanceSkus", opts.SyncSkusDay, opts.SyncSkusHour, 0, 0, models.SyncDBInstanceSkus, true)
cron.AddJobEveryFewDays("SyncNatSkus", opts.SyncSkusDay, opts.SyncSkusHour, 0, 0, models.SyncNatSkus, false)
@@ -0,0 +1,54 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type AppGatewaySyncStatusTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(AppGatewaySyncStatusTask{})
}
func (self *AppGatewaySyncStatusTask) taskFailed(ctx context.Context, app *models.SAppGateway, err error) {
app.SetStatus(self.UserCred, api.APP_GATEWAY_STATUS_UNKNOWN, err.Error())
db.OpsLog.LogEvent(app, db.ACT_SYNC_STATUS, err, self.GetUserCred())
logclient.AddActionLogWithStartable(self, app, logclient.ACT_SYNC_STATUS, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *AppGatewaySyncStatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
app := obj.(*models.SAppGateway)
iApp, err := app.GetICloudAppGateway()
if err != nil {
self.taskFailed(ctx, app, errors.Wrapf(err, "app.GetIAppGateway"))
return
}
app.SyncWithCloudAppGateway(ctx, self.UserCred, iApp)
self.SetStageComplete(ctx, nil)
}
+77
View File
@@ -0,0 +1,77 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafCreateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafCreateTask{})
}
func (self *WafCreateTask) taskFailed(ctx context.Context, waf *models.SWafInstance, err error) {
waf.SetStatus(self.UserCred, api.WAF_STATUS_CREATE_FAILED, err.Error())
db.OpsLog.LogEvent(waf, db.ACT_ALLOCATE_FAIL, err, self.UserCred)
logclient.AddActionLogWithStartable(self, waf, logclient.ACT_ALLOCATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
waf := obj.(*models.SWafInstance)
iRegion, err := waf.GetIRegion()
if err != nil {
self.taskFailed(ctx, waf, errors.Wrapf(err, "GetIRegion"))
return
}
params := api.WafInstanceCreateInput{}
self.GetParams().Unmarshal(&params)
opts := &cloudprovider.WafCreateOptions{
Name: waf.Name,
Desc: waf.Description,
Type: waf.Type,
DefaultAction: waf.DefaultAction,
CloudResources: params.CloudResources,
SourceIps: params.SourceIps,
}
iWaf, err := iRegion.CreateICloudWafInstance(opts)
if err != nil {
self.taskFailed(ctx, waf, errors.Wrapf(err, "CreateICloudWafInstance"))
return
}
cloudprovider.WaitStatus(iWaf, api.WAF_STATUS_AVAILABLE, time.Second*5, time.Minute*5)
waf.SyncWithCloudWafInstance(ctx, self.GetUserCred(), iWaf)
rules, err := iWaf.GetRules()
if err == nil {
waf.SyncWafRules(ctx, self.GetUserCred(), rules)
}
self.SetStageComplete(ctx, nil)
}
+73
View File
@@ -0,0 +1,73 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafDeleteTask{})
}
func (self *WafDeleteTask) taskFailed(ctx context.Context, waf *models.SWafInstance, err error) {
waf.SetStatus(self.UserCred, api.WAF_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, waf, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
waf := obj.(*models.SWafInstance)
iWaf, err := waf.GetICloudWafInstance()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
self.taskComplete(ctx, waf)
return
}
self.taskFailed(ctx, waf, errors.Wrapf(err, "GetICloudWafInstance"))
return
}
err = iWaf.Delete()
if err != nil {
self.taskFailed(ctx, waf, errors.Wrapf(err, "iWaf.Delete"))
return
}
err = cloudprovider.WaitDeleted(iWaf, time.Second*5, time.Minute*5)
if err != nil {
self.taskFailed(ctx, waf, errors.Wrapf(err, "WaitDeleted"))
return
}
self.taskComplete(ctx, waf)
}
func (self *WafDeleteTask) taskComplete(ctx context.Context, waf *models.SWafInstance) {
waf.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,67 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafIPSetCacheDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafIPSetCacheDeleteTask{})
}
func (self *WafIPSetCacheDeleteTask) taskFailed(ctx context.Context, cache *models.SWafIPSetCache, err error) {
cache.SetStatus(self.UserCred, api.WAF_IPSET_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, cache, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafIPSetCacheDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
cache := obj.(*models.SWafIPSetCache)
iCache, err := cache.GetICloudWafIPSet()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
self.taskComplete(ctx, cache)
return
}
self.taskFailed(ctx, cache, errors.Wrapf(err, "GetICloudWafIPSet"))
return
}
err = iCache.Delete()
if err != nil {
self.taskFailed(ctx, cache, errors.Wrapf(err, "iCache.Delete"))
return
}
self.taskComplete(ctx, cache)
}
func (self *WafIPSetCacheDeleteTask) taskComplete(ctx context.Context, cache *models.SWafIPSetCache) {
cache.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,75 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafIPSetDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafIPSetDeleteTask{})
}
func (self *WafIPSetDeleteTask) taskFailed(ctx context.Context, ipset *models.SWafIPSet, err error) {
ipset.SetStatus(self.UserCred, api.WAF_IPSET_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, ipset, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafIPSetDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
ipset := obj.(*models.SWafIPSet)
caches, err := ipset.GetCaches()
if err != nil {
self.taskFailed(ctx, ipset, errors.Wrapf(err, "GetCaches"))
return
}
for i := range caches {
iCache, err := caches[i].GetICloudWafIPSet()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
caches[i].RealDelete(ctx, self.GetUserCred())
continue
}
self.taskFailed(ctx, ipset, errors.Wrapf(err, "GetICloudWafIPSet"))
return
}
err = iCache.Delete()
if err != nil {
self.taskFailed(ctx, ipset, errors.Wrapf(err, "iCache.Delete"))
return
}
caches[i].RealDelete(ctx, self.GetUserCred())
}
self.taskComplete(ctx, ipset)
}
func (self *WafIPSetDeleteTask) taskComplete(ctx context.Context, ipset *models.SWafIPSet) {
ipset.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,67 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafRegexSetCacheDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafRegexSetCacheDeleteTask{})
}
func (self *WafRegexSetCacheDeleteTask) taskFailed(ctx context.Context, cache *models.SWafRegexSetCache, err error) {
cache.SetStatus(self.UserCred, api.WAF_REGEX_SET_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, cache, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafRegexSetCacheDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
cache := obj.(*models.SWafRegexSetCache)
iCache, err := cache.GetICloudWafRegexSet()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
self.taskComplete(ctx, cache)
return
}
self.taskFailed(ctx, cache, errors.Wrapf(err, "GetICloudWafRegexSet"))
return
}
err = iCache.Delete()
if err != nil {
self.taskFailed(ctx, cache, errors.Wrapf(err, "iCache.Delete"))
return
}
self.taskComplete(ctx, cache)
}
func (self *WafRegexSetCacheDeleteTask) taskComplete(ctx context.Context, cache *models.SWafRegexSetCache) {
cache.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,75 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafRegexSetDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafRegexSetDeleteTask{})
}
func (self *WafRegexSetDeleteTask) taskFailed(ctx context.Context, regexset *models.SWafRegexSet, err error) {
regexset.SetStatus(self.UserCred, api.WAF_REGEX_SET_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, regexset, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafRegexSetDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
regexset := obj.(*models.SWafRegexSet)
caches, err := regexset.GetCaches()
if err != nil {
self.taskFailed(ctx, regexset, errors.Wrapf(err, "GetCaches"))
return
}
for i := range caches {
iCache, err := caches[i].GetICloudWafRegexSet()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
caches[i].RealDelete(ctx, self.GetUserCred())
continue
}
self.taskFailed(ctx, regexset, errors.Wrapf(err, "GetICloudWafRegexSet"))
return
}
err = iCache.Delete()
if err != nil {
self.taskFailed(ctx, regexset, errors.Wrapf(err, "iCache.Delete"))
return
}
caches[i].RealDelete(ctx, self.GetUserCred())
}
self.taskComplete(ctx, regexset)
}
func (self *WafRegexSetDeleteTask) taskComplete(ctx context.Context, regexset *models.SWafRegexSet) {
regexset.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
+79
View File
@@ -0,0 +1,79 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafRuleCreateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafRuleCreateTask{})
}
func (self *WafRuleCreateTask) taskFailed(ctx context.Context, rule *models.SWafRule, err error) {
rule.SetStatus(self.UserCred, api.WAF_RULE_STATUS_CREATE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, rule, logclient.ACT_ALLOCATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafRuleCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
rule := obj.(*models.SWafRule)
iWaf, err := rule.GetICloudWafInstance()
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "GetICloudWafInstance"))
return
}
opts := cloudprovider.SWafRule{
Name: rule.Name,
Desc: rule.Description,
Action: rule.Action,
Priority: rule.Priority,
Statements: []cloudprovider.SWafStatement{},
}
opts.StatementCondition = rule.StatementConditon
statements, err := rule.GetRuleStatements()
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "GetRuleStatements"))
return
}
for i := range statements {
opts.Statements = append(opts.Statements, statements[i].SWafStatement)
}
iRule, err := iWaf.AddRule(&opts)
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "iWaf.AddRule"))
return
}
rule.SyncWithCloudRule(ctx, self.GetUserCred(), iRule)
self.taskComplete(ctx, rule)
}
func (self *WafRuleCreateTask) taskComplete(ctx context.Context, rule *models.SWafRule) {
self.SetStageComplete(ctx, nil)
}
+67
View File
@@ -0,0 +1,67 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafRuleDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafRuleDeleteTask{})
}
func (self *WafRuleDeleteTask) taskFailed(ctx context.Context, rule *models.SWafRule, err error) {
rule.SetStatus(self.UserCred, api.WAF_RULE_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, rule, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafRuleDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
rule := obj.(*models.SWafRule)
iRule, err := rule.GetICloudWafRule()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
self.taskComplete(ctx, rule)
return
}
self.taskFailed(ctx, rule, errors.Wrapf(err, "GetICloudWafRule"))
return
}
err = iRule.Delete()
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "iRule.Delete"))
return
}
self.taskComplete(ctx, rule)
}
func (self *WafRuleDeleteTask) taskComplete(ctx context.Context, rule *models.SWafRule) {
rule.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,55 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafRuleSyncstatusTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafRuleSyncstatusTask{})
}
func (self *WafRuleSyncstatusTask) taskFailed(ctx context.Context, rule *models.SWafRule, err error) {
rule.SetStatus(self.UserCred, api.WAF_RULE_STATUS_UNKNOWN, err.Error())
logclient.AddActionLogWithStartable(self, rule, logclient.ACT_SYNC_STATUS, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafRuleSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
rule := obj.(*models.SWafRule)
iRule, err := rule.GetICloudWafRule()
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "GetICloudWafRule"))
return
}
rule.SyncWithCloudRule(ctx, self.GetUserCred(), iRule)
self.SetStageComplete(ctx, nil)
}
+84
View File
@@ -0,0 +1,84 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafRuleUpdateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafRuleUpdateTask{})
}
func (self *WafRuleUpdateTask) taskFailed(ctx context.Context, rule *models.SWafRule, err error) {
rule.SetStatus(self.UserCred, api.WAF_RULE_STATUS_UPDATE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, rule, logclient.ACT_UPDATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafRuleUpdateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
rule := obj.(*models.SWafRule)
iRule, err := rule.GetICloudWafRule()
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "GetICloudWafRule"))
return
}
opts := cloudprovider.SWafRule{
Name: rule.Name,
Desc: rule.Description,
Action: rule.Action,
Priority: rule.Priority,
Statements: []cloudprovider.SWafStatement{},
}
opts.StatementCondition = rule.StatementConditon
statements, err := rule.GetRuleStatements()
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "GetRuleStatements"))
return
}
for i := range statements {
opts.Statements = append(opts.Statements, statements[i].SWafStatement)
}
err = iRule.Update(&opts)
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "iRule.Update"))
return
}
self.taskComplete(ctx, rule)
}
func (self *WafRuleUpdateTask) taskComplete(ctx context.Context, rule *models.SWafRule) {
rule.SetStatus(self.UserCred, api.WAF_RULE_STATUS_AVAILABLE, "")
self.SetStageComplete(ctx, nil)
}
+59
View File
@@ -0,0 +1,59 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafSyncstatusTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafSyncstatusTask{})
}
func (self *WafSyncstatusTask) taskFailed(ctx context.Context, waf *models.SWafInstance, err error) {
waf.SetStatus(self.UserCred, api.WAF_STATUS_UNKNOWN, err.Error())
logclient.AddActionLogWithStartable(self, waf, logclient.ACT_SYNC_STATUS, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
waf := obj.(*models.SWafInstance)
iWaf, err := waf.GetICloudWafInstance()
if err != nil {
self.taskFailed(ctx, waf, errors.Wrapf(err, "GetICloudWafInstance"))
return
}
waf.SyncWithCloudWafInstance(ctx, self.GetUserCred(), iWaf)
rules, err := iWaf.GetRules()
if err == nil {
result := waf.SyncWafRules(ctx, self.GetUserCred(), rules)
log.Infof("Sync waf %s rules result: %s", waf.Name, result.Result())
}
self.SetStageComplete(ctx, nil)
}
+37
View File
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
type AppGatewayManager struct {
modulebase.ResourceManager
}
var (
AppGateways AppGatewayManager
)
func init() {
AppGateways = AppGatewayManager{
NewComputeManager(
"app_gateway",
"app_gateways",
[]string{},
[]string{},
),
}
registerCompute(&AppGateways)
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
WafInstances modulebase.ResourceManager
)
func init() {
WafInstances = NewComputeManager("waf_instance", "waf_instances",
[]string{"ID", "Name", "Enabled", "Status", "Cloudregion_Id", "Region", "Rules", "Public_Scope", "Domain_Id", "Domain", "Metadata"},
[]string{})
registerCompute(&WafInstances)
}
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
WafIPSetCaches modulebase.ResourceManager
)
func init() {
WafIPSetCaches = NewComputeManager("waf_ipset_cache", "waf_ipset_caches",
[]string{"ID", "Name", "Status", "Cloudregion", "Provider", "Account", "Type", "Domain_Id", "Domain", "Metadata"},
[]string{})
registerCompute(&WafIPSetCaches)
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
WafIPSets modulebase.ResourceManager
)
func init() {
WafIPSets = NewComputeManager("waf_ipset", "waf_ipsets",
[]string{"ID", "Name", "Status", "Addresses", "Domain_Id", "Domain", "Metadata"},
[]string{})
registerCompute(&WafIPSets)
}
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
WafRegexSetCaches modulebase.ResourceManager
)
func init() {
WafRegexSetCaches = NewComputeManager("waf_regexset_cache", "waf_regexset_caches",
[]string{"ID", "Name", "Status", "Cloudregion", "Provider", "Account", "Type", "Domain_Id", "Domain", "Metadata"},
[]string{})
registerCompute(&WafRegexSetCaches)
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
WafRegexSets modulebase.ResourceManager
)
func init() {
WafRegexSets = NewComputeManager("waf_regexset", "waf_regexsets",
[]string{"ID", "Name", "Status", "Addresses", "Domain_Id", "Domain", "Metadata"},
[]string{})
registerCompute(&WafRegexSets)
}
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
WafRuleGroups modulebase.ResourceManager
)
func init() {
WafRuleGroups = NewComputeManager("waf_rule_group", "waf_rule_groups",
[]string{"ID", "Name", "Status", "Domain_Id", "Domain", "Is_System", "Rules"},
[]string{})
registerCompute(&WafRuleGroups)
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
WafRules modulebase.ResourceManager
)
func init() {
WafRules = NewComputeManager("waf_rule", "waf_rules",
[]string{"ID", "Name", "Status", "Priority", "Action", "Statement_Condition", "Statements"},
[]string{})
registerCompute(&WafRules)
}
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type AppGatewayListOptions struct {
options.BaseListOptions
}
func (opts *AppGatewayListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
@@ -0,0 +1,40 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type WafInstanceListOptions struct {
options.BaseListOptions
}
func (opts *WafInstanceListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
type WafInstanceCreateOptions struct {
options.BaseCreateOptions
CloudregionId string
CloudproviderId string
SourceIps []string
}
func (opts *WafInstanceCreateOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(opts), nil
}
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type WafIPSetListOptions struct {
options.BaseListOptions
}
func (opts *WafIPSetListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
type WafIPSetCacheListOptions struct {
options.BaseListOptions
}
func (opts *WafIPSetCacheListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type WafRegexSetListOptions struct {
options.BaseListOptions
}
func (opts *WafRegexSetListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
type WafRegexSetCacheListOptions struct {
options.BaseListOptions
}
func (opts *WafRegexSetCacheListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
@@ -0,0 +1,39 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type WafRuleGroupListOptions struct {
options.BaseListOptions
IsSystem bool
}
func (opts *WafRuleGroupListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
type WafRuleGroupCacheListOptions struct {
options.BaseListOptions
}
func (opts *WafRuleGroupCacheListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
+60
View File
@@ -0,0 +1,60 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"io/ioutil"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type WafRuleListOptions struct {
options.BaseListOptions
WafInstanceId string
WafRuleGroupId string
}
func (opts *WafRuleListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
type WafRuleOptions struct {
RULE_FILE string
}
func (opts *WafRuleOptions) Params() (jsonutils.JSONObject, error) {
data, err := ioutil.ReadFile(opts.RULE_FILE)
if err != nil {
return nil, errors.Wrapf(err, "ioutils.ReadFile")
}
ret, err := jsonutils.Parse(data)
if err != nil {
return nil, err
}
return ret, nil
}
type WafRuleUpdateOptions struct {
options.BaseIdOptions
WafRuleOptions
}
func (opts *WafRuleUpdateOptions) Params() (jsonutils.JSONObject, error) {
return opts.WafRuleOptions.Params()
}
+2
View File
@@ -752,6 +752,8 @@ func (c *QueryCondition) getTagKeyRelationMap() map[string]string {
relationMap = monitor.DomainTags
case monitor.METRIC_RES_TYPE_STORAGE:
relationMap = monitor.StorageTags
case monitor.METRIC_RES_TYPE_AGENT:
relationMap = monitor.ServerTags
default:
relationMap = monitor.HostTags
}
+3
View File
@@ -211,6 +211,9 @@ func (e *AlertEngine) processJob(attemptID int, attemptChan chan int, cancelChan
attemptChan <- (attemptID + 1)
return
}
log.Errorf("gt AlertingMaxAttempts, error: %v", evalContext.Error)
close(attemptChan)
return
}
// create new context with timeout for notifications
+6 -1
View File
@@ -65,6 +65,7 @@ const (
ALIYUN_CDN_API_VERSION = "2018-05-10"
ALIYUN_IMS_API_VERSION = "2019-08-15"
ALIYUN_NAS_API_VERSION = "2017-06-26"
ALIYUN_WAF_API_VERSION = "2019-09-10"
ALIYUN_SERVICE_ECS = "ecs"
ALIYUN_SERVICE_VPC = "vpc"
@@ -179,7 +180,10 @@ func jsonRequest(client *sdk.Client, domain, apiVersion, apiName string, params
"OperationUnsupported.EipNatBWPCheck": // create nat snat
retry = true
default:
if strings.HasPrefix(code, "EntityNotExist.") || strings.HasSuffix(code, ".NotFound") {
if strings.HasPrefix(code, "EntityNotExist.") || strings.HasSuffix(code, ".NotFound") || strings.HasSuffix(code, "NotExist") {
if strings.HasPrefix(apiName, "Delete") {
return jsonutils.NewDict(), nil
}
return nil, errors.Wrap(cloudprovider.ErrNotFound, err.Error())
}
return nil, err
@@ -639,6 +643,7 @@ func (region *SAliyunClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_SAML_AUTH,
cloudprovider.CLOUD_CAPABILITY_NAT,
cloudprovider.CLOUD_CAPABILITY_NAS,
cloudprovider.CLOUD_CAPABILITY_WAF,
}
return caps
}
+12
View File
@@ -136,6 +136,18 @@ func (self *SRegion) ecsRequest(apiName string, params map[string]string) (jsonu
return jsonRequest(client, endpoint, ALIYUN_API_VERSION, apiName, params, self.client.debug)
}
func (self *SRegion) wafRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
client, err := self.getSdkClient()
if err != nil {
return nil, err
}
if self.RegionId != "cn-hangzhou" && self.RegionId != "ap-southeast-1" {
return nil, cloudprovider.ErrNotSupported
}
endpoint := fmt.Sprintf("wafopenapi.%s.aliyuncs.com", self.RegionId)
return jsonRequest(client, endpoint, ALIYUN_WAF_API_VERSION, apiName, params, self.client.debug)
}
func (self *SRegion) rdsRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
client, err := self.getSdkClient()
if err != nil {
+73
View File
@@ -0,0 +1,73 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package shell
import (
"fmt"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/multicloud/aliyun"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type WafShowOptions struct {
}
shellutils.R(&WafShowOptions{}, "waf-instance-show", "Show waf instance", func(cli *aliyun.SRegion, args *WafShowOptions) error {
waf, err := cli.DescribeInstanceSpecInfo()
if err != nil {
return err
}
printObject(waf)
return nil
})
type WafIdOptions struct {
ID string
}
shellutils.R(&WafIdOptions{}, "waf-instance-delete", "Delete waf instance", func(cli *aliyun.SRegion, args *WafIdOptions) error {
return cli.DeleteInstance(args.ID)
})
shellutils.R(&WafIdOptions{}, "waf-domain-list", "List waf instance domains", func(cli *aliyun.SRegion, args *WafIdOptions) error {
domains, err := cli.DescribeDomainNames(args.ID)
if err != nil {
return errors.Wrapf(err, "DescribeDomainNames")
}
fmt.Println("domains: ", domains)
return nil
})
type WafDomainIdOptions struct {
ID string
DOMAIN string
}
shellutils.R(&WafDomainIdOptions{}, "waf-domain-show", "Show waf domain", func(cli *aliyun.SRegion, args *WafDomainIdOptions) error {
domain, err := cli.DescribeDomain(args.ID, args.DOMAIN)
if err != nil {
return err
}
printObject(domain)
return nil
})
shellutils.R(&WafDomainIdOptions{}, "waf-domain-delete", "Delete waf domain", func(cli *aliyun.SRegion, args *WafDomainIdOptions) error {
return cli.DeleteDomain(args.ID, args.DOMAIN)
})
}
+61
View File
@@ -0,0 +1,61 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aliyun
import (
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SInstanceSpecs struct {
Code int
Value bool
}
type SWafInstance struct {
Version string
InstanceSpecInfos []SInstanceSpecs
InstanceId string
ExpireTime uint64
}
func (self *SRegion) DescribeInstanceSpecInfo() (*SWafInstance, error) {
params := map[string]string{
"RegionId": self.RegionId,
}
resp, err := self.wafRequest("DescribeInstanceSpecInfo", params)
if err != nil {
return nil, errors.Wrapf(err, "DescribeInstanceSpecInfo")
}
ret := &SWafInstance{}
err = resp.Unmarshal(&ret)
if err != nil {
return nil, errors.Wrapf(err, "resp.Unmarshal")
}
if len(ret.InstanceId) == 0 {
return nil, cloudprovider.ErrNotFound
}
return ret, nil
}
func (self *SRegion) DeleteInstance(id string) error {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": id,
}
_, err := self.wafRequest("DeleteInstance", params)
return errors.Wrapf(err, "DeleteInstance")
}
+502
View File
@@ -0,0 +1,502 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aliyun
import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
type SWafDomain struct {
multicloud.SResourceBase
multicloud.AliyunTags
region *SRegion
insId string
name string
Httptouserip int `json:"HttpToUserIp"`
Httpport []int `json:"HttpPort"`
Isaccessproduct int `json:"IsAccessProduct"`
Resourcegroupid string `json:"ResourceGroupId"`
Readtime int `json:"ReadTime"`
Sourceips []string `json:"SourceIps"`
Ipfollowstatus int `json:"IpFollowStatus"`
Clustertype int `json:"ClusterType"`
Loadbalancing int `json:"LoadBalancing"`
Cname string `json:"Cname"`
Writetime int `json:"WriteTime"`
HTTP2Port []interface{} `json:"Http2Port"`
Version int `json:"Version"`
Httpsredirect int `json:"HttpsRedirect"`
Connectiontime int `json:"ConnectionTime"`
Accesstype string `json:"AccessType"`
Httpsport []interface{} `json:"HttpsPort"`
}
func (self *SRegion) DescribeDomain(id, domain string) (*SWafDomain, error) {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": id,
"Domain": domain,
}
resp, err := self.wafRequest("DescribeDomain", params)
if err != nil {
return nil, errors.Wrapf(err, "DescribeDomain")
}
ret := &SWafDomain{region: self, name: domain, insId: id}
err = resp.Unmarshal(ret, "Domain")
if err != nil {
return nil, errors.Wrapf(err, "resp.Unmarshal")
}
return ret, nil
}
func (self *SRegion) DeleteDomain(id, domain string) error {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": id,
"Domain": domain,
}
_, err := self.wafRequest("DeleteDomain", params)
return errors.Wrapf(err, "DeleteDomain")
}
func (self *SRegion) DescribeDomainNames(id string) ([]string, error) {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": id,
}
resp, err := self.wafRequest("DescribeDomainNames", params)
if err != nil {
return nil, errors.Wrapf(err, "DescribeDomainNames")
}
domains := []string{}
err = resp.Unmarshal(&domains, "DomainNames")
return domains, errors.Wrapf(err, "resp.Unmarshal")
}
func (self *SRegion) SetDomainRuleGroup(insId, domain, ruleGroupId string) error {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": insId,
"Domains": domain,
"RuleGroupId": ruleGroupId,
}
_, err := self.wafRequest("SetDomainRuleGroup", params)
return err
}
func (self *SRegion) DescribeDomainRuleGroup(insId, domain string) (string, error) {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": insId,
"Domain": domain,
}
resp, err := self.wafRequest("DescribeDomainRuleGroup", params)
if err != nil {
return "", errors.Wrapf(err, "DescribeDomainRuleGroup")
}
return resp.GetString("RuleGroupId")
}
func (self *SRegion) GetICloudWafInstances() ([]cloudprovider.ICloudWafInstance, error) {
ins, err := self.DescribeInstanceSpecInfo()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
return []cloudprovider.ICloudWafInstance{}, nil
}
return nil, errors.Wrapf(err, "DescribeInstanceSpecInfo")
}
domains, err := self.DescribeDomainNames(ins.InstanceId)
if err != nil {
return nil, errors.Wrapf(err, "DescribeDomainNames")
}
ret := []cloudprovider.ICloudWafInstance{}
for i := range domains {
domain, err := self.DescribeDomain(ins.InstanceId, domains[i])
if err != nil {
return nil, errors.Wrapf(err, "DescribeDomain %s", domains[i])
}
domain.region = self
domain.insId = ins.InstanceId
domain.name = domains[i]
ret = append(ret, domain)
}
return ret, nil
}
func (self *SRegion) GetICloudWafInstanceById(id string) (cloudprovider.ICloudWafInstance, error) {
ins, err := self.DescribeInstanceSpecInfo()
if err != nil {
return nil, errors.Wrapf(err, "DescribeInstanceSpecInfo")
}
return self.DescribeDomain(ins.InstanceId, id)
}
func (self *SWafDomain) GetId() string {
return self.name
}
func (self *SWafDomain) GetStatus() string {
return api.WAF_STATUS_AVAILABLE
}
func (self *SWafDomain) GetWafType() cloudprovider.TWafType {
return cloudprovider.WafTypeDefault
}
func (self *SWafDomain) GetEnabled() bool {
return true
}
func (self *SWafDomain) GetName() string {
return self.name
}
func (self *SWafDomain) GetGlobalId() string {
return self.name
}
func (self *SWafDomain) Delete() error {
return self.region.DeleteDomain(self.insId, self.name)
}
func (self *SWafDomain) GetDefaultAction() *cloudprovider.DefaultAction {
return &cloudprovider.DefaultAction{
Action: cloudprovider.WafActionAllow,
InsertHeaders: map[string]string{},
}
}
type ManagedRuleGroup struct {
waf *SWafDomain
insId string
domain string
ruleGroupId string
}
func (self *ManagedRuleGroup) GetName() string {
return "RuleGroup"
}
func (self *ManagedRuleGroup) GetDesc() string {
return "规则组"
}
func (self *ManagedRuleGroup) GetGlobalId() string {
return fmt.Sprintf("%s-%s", self.insId, self.domain)
}
func (self *ManagedRuleGroup) GetPriority() int {
return 0
}
func (self *ManagedRuleGroup) GetAction() *cloudprovider.DefaultAction {
return nil
}
func (self *ManagedRuleGroup) Delete() error {
return cloudprovider.ErrNotSupported
}
func (self *ManagedRuleGroup) Update(opts *cloudprovider.SWafRule) error {
for _, statement := range opts.Statements {
if len(statement.RuleGroupId) == 0 {
return self.waf.region.SetDomainRuleGroup(self.insId, self.domain, statement.RuleGroupId)
} else if len(statement.ManagedRuleGroupName) > 0 {
switch statement.ManagedRuleGroupName {
case "严格规则":
return self.waf.region.SetDomainRuleGroup(self.insId, self.domain, "1011")
case "中等规则":
return self.waf.region.SetDomainRuleGroup(self.insId, self.domain, "1012")
case "宽松规则":
return self.waf.region.SetDomainRuleGroup(self.insId, self.domain, "1013")
}
}
}
return nil
}
func (self *ManagedRuleGroup) GetStatementCondition() cloudprovider.TWafStatementCondition {
return cloudprovider.WafStatementConditionNone
}
func (self *ManagedRuleGroup) GetStatements() ([]cloudprovider.SWafStatement, error) {
groupName := self.ruleGroupId
switch self.ruleGroupId {
case "1011":
groupName = "严格规则"
case "1012":
groupName = "中等规则"
case "1013":
groupName = "宽松规则"
}
return []cloudprovider.SWafStatement{
cloudprovider.SWafStatement{
ManagedRuleGroupName: groupName,
RuleGroupId: self.ruleGroupId,
},
}, nil
}
type SDefenseTypeRule struct {
insId string
domain string
defenseType string
action cloudprovider.TWafAction
}
func (self *SDefenseTypeRule) GetName() string {
switch self.defenseType {
case "waf":
return "正则防护引擎"
case "dld":
return "大数据深度学习引擎"
case "ac_cc":
return "CC安全防护"
case "antifraud":
return "数据风控"
case "normalized":
return "主动防御"
}
return self.defenseType
}
func (self *SDefenseTypeRule) GetDesc() string {
return ""
}
func (self *SDefenseTypeRule) GetGlobalId() string {
return fmt.Sprintf("%s-%s-%s", self.insId, self.domain, self.defenseType)
}
func (self *SDefenseTypeRule) GetPriority() int {
return 0
}
func (self *SDefenseTypeRule) GetAction() *cloudprovider.DefaultAction {
return &cloudprovider.DefaultAction{
Action: self.action,
}
}
func (self *SDefenseTypeRule) GetStatementCondition() cloudprovider.TWafStatementCondition {
return cloudprovider.WafStatementConditionNone
}
func (self *SDefenseTypeRule) GetStatements() ([]cloudprovider.SWafStatement, error) {
return []cloudprovider.SWafStatement{}, nil
}
func (self *SDefenseTypeRule) Delete() error {
return cloudprovider.ErrNotSupported
}
func (self *SDefenseTypeRule) Update(opts *cloudprovider.SWafRule) error {
return cloudprovider.ErrNotSupported
}
func (self *SWafDomain) GetRules() ([]cloudprovider.ICloudWafRule, error) {
ruleGroupId, err := self.region.DescribeDomainRuleGroup(self.insId, self.name)
if err != nil {
return nil, errors.Wrapf(err, "DescribeDomainRuleGroup")
}
ret := []cloudprovider.ICloudWafRule{}
ret = append(ret, &ManagedRuleGroup{
waf: self,
insId: self.insId,
domain: self.name,
ruleGroupId: ruleGroupId,
})
for _, defenseType := range []string{
"waf",
"dld",
"ac_cc",
"antifraud",
"normalized",
} {
act, _ := self.region.DescribeProtectionModuleMode(self.insId, self.name, defenseType)
ret = append(ret, &SDefenseTypeRule{
insId: self.insId,
domain: self.name,
defenseType: defenseType,
action: act,
})
}
return ret, nil
}
type SIpSegement struct {
IpV6s string
Ips string
}
func (self *SRegion) DescribeWafSourceIpSegment(insId string) (*SIpSegement, error) {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": insId,
}
resp, err := self.wafRequest("DescribeWafSourceIpSegment", params)
if err != nil {
return nil, errors.Wrapf(err, "DescribeWafSourceIpSegment")
}
ret := &SIpSegement{}
err = resp.Unmarshal(ret)
if err != nil {
return nil, errors.Wrapf(err, "")
}
return ret, nil
}
func (self *SRegion) CreateICloudWafInstance(opts *cloudprovider.WafCreateOptions) (cloudprovider.ICloudWafInstance, error) {
ins, err := self.DescribeInstanceSpecInfo()
if err != nil {
return nil, errors.Wrapf(err, "DescribeInstanceSpecInfo")
}
waf, err := self.CreateDomain(ins.InstanceId, opts.Name, opts.SourceIps, opts.CloudResources)
if err != nil {
return nil, errors.Wrapf(err, "CreateDomain")
}
return waf, nil
}
func (self *SRegion) CreateDomain(insId, domain string, sourceIps []string, cloudResources []cloudprovider.SCloudResource) (*SWafDomain, error) {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": insId,
"Domain": domain,
"IsAccessProduct": "0",
"HttpPort": `["80"]`,
"HttpsPort": `["443"]`,
"Http2Port": `["80", "443"]`,
}
if len(sourceIps) > 0 {
params["SourceIps"] = jsonutils.Marshal(sourceIps).String()
params["AccessType"] = "waf-cloud-dns"
} else if len(cloudResources) > 0 {
ins := jsonutils.NewArray()
for _, res := range cloudResources {
ins.Add(jsonutils.Marshal(map[string]interface{}{"InstanceId": res.Id, "Port": res.Port}))
}
params["CloudNativeInstances"] = ins.String()
params["AccessType"] = "waf-cloud-native"
} else {
return nil, errors.Error("missing source ips")
}
_, err := self.wafRequest("CreateDomain", params)
if err != nil {
return nil, errors.Wrapf(err, "CreateDomain")
}
return self.DescribeDomain(insId, domain)
}
func (self *SWafDomain) AddRule(opts *cloudprovider.SWafRule) (cloudprovider.ICloudWafRule, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotSupported, "AddRule")
}
func (self *SWafDomain) Refresh() error {
domain, err := self.region.DescribeDomain(self.insId, self.name)
if err != nil {
return errors.Wrapf(err, "DescribeDomain")
}
return jsonutils.Update(self, domain)
}
func (self *SWafDomain) GetCloudResources() ([]cloudprovider.SCloudResource, error) {
ret := []cloudprovider.SCloudResource{}
if len(self.Cname) > 0 {
ret = append(ret, cloudprovider.SCloudResource{
Type: "cname",
Id: self.Cname,
CanDissociate: false,
})
}
ipseg, err := self.region.DescribeWafSourceIpSegment(self.insId)
if err == nil {
ret = append(ret, cloudprovider.SCloudResource{
Type: "segment_ipv4",
Id: ipseg.Ips,
CanDissociate: false,
})
ret = append(ret, cloudprovider.SCloudResource{
Type: "segment_ipv6",
Id: ipseg.IpV6s,
CanDissociate: false,
})
}
return ret, nil
}
func (self *SRegion) DescribeProtectionModuleMode(insId, domain, defenseType string) (cloudprovider.TWafAction, error) {
params := map[string]string{
"RegionId": self.RegionId,
"Domain": domain,
"InstanceId": insId,
"DefenseType": defenseType,
}
resp, err := self.wafRequest("DescribeProtectionModuleMode", params)
if err != nil {
return cloudprovider.WafActionNone, errors.Wrapf(err, "DescribeProtectionModuleMode %s", defenseType)
}
if !resp.Contains("Mode") {
return cloudprovider.WafActionNone, nil
}
mode, _ := resp.Int("Mode")
switch defenseType {
case "waf":
if mode == 0 {
return cloudprovider.WafActionBlock, nil
}
if mode == 1 {
return cloudprovider.WafActionAlert, nil
}
case "dld":
if mode == 0 {
return cloudprovider.WafActionAlert, nil
}
if mode == 1 {
return cloudprovider.WafActionBlock, nil
}
case "ac_cc":
if mode == 0 {
return cloudprovider.WafActionAllow, nil
}
if mode == 1 {
return cloudprovider.WafActionBlock, nil
}
case "antifraud":
if mode == 0 {
return cloudprovider.WafActionAlert, nil
}
if mode == 1 || mode == 2 {
return cloudprovider.WafActionBlock, nil
}
case "normalized":
if mode == 0 {
return cloudprovider.WafActionAlert, nil
}
if mode == 1 {
return cloudprovider.WafActionBlock, nil
}
}
return cloudprovider.WafActionNone, nil
}
+1
View File
@@ -586,6 +586,7 @@ func (self *SAwsClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_CLOUDID,
cloudprovider.CLOUD_CAPABILITY_DNSZONE,
cloudprovider.CLOUD_CAPABILITY_SAML_AUTH,
cloudprovider.CLOUD_CAPABILITY_WAF,
}
return caps
}
+13
View File
@@ -39,6 +39,7 @@ import (
"github.com/aws/aws-sdk-go/service/organizations"
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/wafv2"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -139,6 +140,7 @@ type SRegion struct {
s3Client *s3.S3
elbv2Client *elbv2.ELBV2
acmClient *acm.ACM
wafClient *wafv2.WAFV2
organizationClient *organizations.Organizations
resourceGroupTagClient *resourcegroupstaggingapi.ResourceGroupsTaggingAPI
@@ -189,6 +191,17 @@ func (self *SRegion) getIamClient() (*iam.IAM, error) {
return self.iamClient, nil
}
func (self *SRegion) getWafClient() (*wafv2.WAFV2, error) {
if self.wafClient == nil {
s, err := self.getAwsSession()
if err != nil {
return nil, errors.Wrapf(err, "getAwsSession")
}
self.wafClient = wafv2.New(s)
}
return self.wafClient, nil
}
func (self *SRegion) GetS3Client() (*s3.S3, error) {
if self.s3Client == nil {
s, err := self.getAwsSession()
+210
View File
@@ -0,0 +1,210 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package shell
import (
"fmt"
"io/ioutil"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/aws"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type WafRuleGroupListOptions struct {
Scope string `choices:"CLOUDFRONT|REGIONAL" default:"REGIONAL"`
}
shellutils.R(&WafRuleGroupListOptions{}, "waf-managed-rule-group-list", "List waf managed rule group", func(cli *aws.SRegion, args *WafRuleGroupListOptions) error {
groups, err := cli.ListAvailableManagedRuleGroups(args.Scope)
if err != nil {
return err
}
printList(groups, 0, 0, 0, []string{})
return nil
})
shellutils.R(&WafRuleGroupListOptions{}, "waf-rule-group-list", "List waf rule group", func(cli *aws.SRegion, args *WafRuleGroupListOptions) error {
groups, err := cli.ListRuleGroups(args.Scope)
if err != nil {
return err
}
printList(groups, 0, 0, 0, []string{})
return nil
})
type WafRuleGroupShowOptions struct {
ID string
NAME string
SCOPE string
}
shellutils.R(&WafRuleGroupShowOptions{}, "waf-rule-group-show", "Show waf rule group", func(cli *aws.SRegion, args *WafRuleGroupShowOptions) error {
group, err := cli.GetRuleGroup(args.ID, args.NAME, args.SCOPE)
if err != nil {
return err
}
printObject(group)
return nil
})
type WafManagedRuleGroupShowOptions struct {
NAME string
SCOPE string
VendorName string `default:"AWS"`
}
shellutils.R(&WafManagedRuleGroupShowOptions{}, "waf-managed-rule-group-show", "Show waf rule group", func(cli *aws.SRegion, args *WafManagedRuleGroupShowOptions) error {
group, err := cli.DescribeManagedRuleGroup(args.NAME, args.SCOPE, args.VendorName)
if err != nil {
return err
}
printObject(group)
return nil
})
type RuleGroupDeleteOptions struct {
ID string
NAME string
SCOPE string
LOCK_TOKEN string
}
shellutils.R(&RuleGroupDeleteOptions{}, "waf-rule-group-delete", "Delete waf ip set", func(cli *aws.SRegion, args *RuleGroupDeleteOptions) error {
return cli.DeleteRuleGroup(args.ID, args.NAME, args.SCOPE, args.LOCK_TOKEN)
})
type IPSetListOptions struct {
Scope string `choices:"CLOUDFRONT|REGIONAL" default:"REGIONAL"`
}
shellutils.R(&IPSetListOptions{}, "waf-ipset-list", "List waf ip sets", func(cli *aws.SRegion, args *IPSetListOptions) error {
ipsets, err := cli.ListIPSets(args.Scope)
if err != nil {
return err
}
printList(ipsets, 0, 0, 0, []string{})
return nil
})
type WafIPSetShowOptions struct {
ID string
NAME string
SCOPE string
}
shellutils.R(&WafIPSetShowOptions{}, "waf-ipset-show", "Show waf ip sets", func(cli *aws.SRegion, args *WafIPSetShowOptions) error {
ipset, err := cli.GetIPSet(args.ID, args.NAME, args.SCOPE)
if err != nil {
return err
}
printObject(ipset)
return nil
})
type WafIPSetDeleteOptions struct {
ID string
NAME string
SCOPE string
LOCK_TOKEN string
}
shellutils.R(&WafIPSetDeleteOptions{}, "waf-ipset-delete", "Delete waf ip set", func(cli *aws.SRegion, args *WafIPSetDeleteOptions) error {
return cli.DeleteIPSet(args.ID, args.NAME, args.SCOPE, args.LOCK_TOKEN)
})
type WafListOptions struct {
Scope string `choices:"CLOUDFRONT|REGIONAL" default:"REGIONAL"`
}
shellutils.R(&WafListOptions{}, "waf-list", "List web acls", func(cli *aws.SRegion, args *WafListOptions) error {
acls, err := cli.ListWebACLs(args.Scope)
if err != nil {
return err
}
printList(acls, 0, 0, 0, []string{})
return nil
})
type WafShowOptions struct {
ID string
NAME string
SCOPE string
}
shellutils.R(&WafShowOptions{}, "waf-show", "Show web acl", func(cli *aws.SRegion, args *WafShowOptions) error {
webAcl, err := cli.GetWebAcl(args.ID, args.NAME, args.SCOPE)
if err != nil {
return err
}
printObject(webAcl)
return nil
})
type WafDeleteOptions struct {
ID string
NAME string
SCOPE string
LOCK_TOKEN string
}
shellutils.R(&WafDeleteOptions{}, "waf-delete", "Delete web acl", func(cli *aws.SRegion, args *WafDeleteOptions) error {
return cli.DeleteWebAcl(args.ID, args.NAME, args.SCOPE, args.LOCK_TOKEN)
})
type WafResourceListOptions struct {
ResType string `choices:"APPLICATION_LOAD_BALANCER|API_GATEWAY|APPSYNC"`
ARN string
}
shellutils.R(&WafResourceListOptions{}, "waf-res-list", "List web acl resource", func(cli *aws.SRegion, args *WafResourceListOptions) error {
res, err := cli.ListResourcesForWebACL(args.ResType, args.ARN)
if err != nil {
return err
}
fmt.Println("res:", res)
return nil
})
type WafAddRuleOptions struct {
WafShowOptions
RULE_FILE string
}
shellutils.R(&WafAddRuleOptions{}, "waf-add-rule", "Add web acl rule", func(cli *aws.SRegion, args *WafAddRuleOptions) error {
waf, err := cli.GetWebAcl(args.ID, args.NAME, args.SCOPE)
if err != nil {
return errors.Wrapf(err, "GetWebAcl")
}
data, err := ioutil.ReadFile(args.RULE_FILE)
if err != nil {
return errors.Wrapf(err, "ReadFile")
}
params, err := jsonutils.Parse(data)
if err != nil {
return errors.Wrapf(err, "Parse")
}
rule := &cloudprovider.SWafRule{}
params.Unmarshal(rule)
_, err = waf.AddRule(rule)
return err
})
}
+536
View File
@@ -0,0 +1,536 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aws
import (
"strings"
"github.com/aws/aws-sdk-go/service/wafv2"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
const (
SCOPE_REGIONAL = "REGIONAL"
SCOPE_CLOUDFRONT = "CLOUDFRONT"
)
var (
WAF_SCOPES = []string{
SCOPE_REGIONAL,
SCOPE_CLOUDFRONT,
}
)
type SWafRule struct {
Action struct {
Block struct {
} `json:"Block"`
} `json:"Action"`
Name string `json:"Name"`
}
type SVisibilityConfig struct {
CloudWatchMetricsEnabled bool
MetricName string
SampledRequestsEnabled bool
}
type SWebAcl struct {
multicloud.SResourceBase
multicloud.AwsTags
region *SRegion
sWebDetails
scope string
ARN string
Description string
Id string
LockToken string
Name string
LabelNamespace string
Capacity int
ManagedByFirewallManager bool
VisibilityConfig SVisibilityConfig
}
func (self *SRegion) ListWebACLs(scope string) ([]SWebAcl, error) {
if scope == SCOPE_CLOUDFRONT && self.RegionId != "us-east-1" {
return []SWebAcl{}, nil
}
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
ret := []SWebAcl{}
input := wafv2.ListWebACLsInput{}
input.SetScope(scope)
for {
resp, err := client.ListWebACLs(&input)
if err != nil {
return nil, errors.Wrapf(err, "ListWebACLs")
}
part := []SWebAcl{}
jsonutils.Update(&part, resp.WebACLs)
ret = append(ret, part...)
if resp.NextMarker == nil || len(*resp.NextMarker) == 0 {
break
}
input.SetNextMarker(*resp.NextMarker)
}
return ret, nil
}
func (self *SRegion) GetWebAcl(id, name, scope string) (*SWebAcl, error) {
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
input := wafv2.GetWebACLInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
resp, err := client.GetWebACL(&input)
if err != nil {
if _, ok := err.(*wafv2.WAFNonexistentItemException); ok {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, err.Error())
}
return nil, errors.Wrapf(err, "GetWebAcl")
}
ret := &SWebAcl{region: self, scope: scope, sWebDetails: sWebDetails{resp.WebACL}, LockToken: *resp.LockToken}
return ret, jsonutils.Update(ret, resp.WebACL)
}
func (self *SRegion) DeleteWebAcl(id, name, scope, lockToken string) error {
client, err := self.getWafClient()
if err != nil {
return errors.Wrapf(err, "getWafClient")
}
input := wafv2.DeleteWebACLInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
input.SetLockToken(lockToken)
_, err = client.DeleteWebACL(&input)
return errors.Wrapf(err, "DeleteWebACL")
}
func (self *SRegion) ListResourcesForWebACL(resType, arn string) ([]string, error) {
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
input := wafv2.ListResourcesForWebACLInput{}
input.SetResourceType(resType)
input.SetWebACLArn(arn)
resp, err := client.ListResourcesForWebACL(&input)
if err != nil {
return nil, errors.Wrapf(err, "ListResourcesForWebACL")
}
ret := []string{}
for _, id := range resp.ResourceArns {
ret = append(ret, *id)
}
return ret, nil
}
func (self *SRegion) GetICloudWafInstanceById(id string) (cloudprovider.ICloudWafInstance, error) {
idInfo := strings.Split(id, "/")
if len(idInfo) != 4 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "invalid arn %s", id)
}
scope := SCOPE_CLOUDFRONT
if strings.HasSuffix(idInfo[0], "regional") {
scope = SCOPE_REGIONAL
}
ins, err := self.GetWebAcl(idInfo[3], idInfo[2], scope)
if err != nil {
return nil, errors.Wrapf(err, "GetWebAcl(%s, %s, %s)", idInfo[3], idInfo[2], scope)
}
return ins, nil
}
func (self *SRegion) GetICloudWafInstances() ([]cloudprovider.ICloudWafInstance, error) {
ret := []cloudprovider.ICloudWafInstance{}
for _, scope := range WAF_SCOPES {
ins, err := self.ListWebACLs(scope)
if err != nil {
return nil, errors.Wrapf(err, "ListWebACLs")
}
for i := range ins {
ins[i].region = self
ins[i].scope = scope
ret = append(ret, &ins[i])
}
}
return ret, nil
}
func (self *SWebAcl) GetEnabled() bool {
return true
}
func (self *SWebAcl) GetGlobalId() string {
return self.ARN
}
func (self *SWebAcl) GetName() string {
return self.Name
}
func (self *SWebAcl) GetId() string {
return self.ARN
}
func (self *SWebAcl) GetWafType() cloudprovider.TWafType {
if self.scope == SCOPE_CLOUDFRONT {
return cloudprovider.WafTypeCloudFront
}
return cloudprovider.WafTypeRegional
}
func (self *SWebAcl) GetStatus() string {
return api.WAF_STATUS_AVAILABLE
}
func (self *SWebAcl) GetDefaultAction() *cloudprovider.DefaultAction {
ret := &cloudprovider.DefaultAction{}
if self.WebACL != nil && self.WebACL.DefaultAction != nil {
action := self.WebACL.DefaultAction
if action.Allow != nil {
ret.Action = cloudprovider.WafActionAllow
} else if action.Block != nil {
ret.Action = cloudprovider.WafActionBlock
}
}
return ret
}
func (self *SWebAcl) Refresh() error {
acl, err := self.region.GetWebAcl(self.Id, self.Name, self.scope)
if err != nil {
return errors.Wrapf(err, "GetWebAcl")
}
return jsonutils.Update(self, acl)
}
func (self *SWebAcl) Delete() error {
return self.region.DeleteWebAcl(self.Id, self.Name, self.scope, self.LockToken)
}
func (self *SRegion) CreateICloudWafInstance(opts *cloudprovider.WafCreateOptions) (cloudprovider.ICloudWafInstance, error) {
waf, err := self.CreateWebAcl(opts.Name, opts.Desc, opts.Type, opts.DefaultAction)
if err != nil {
return nil, errors.Wrapf(err, "CreateWebAcl")
}
return waf, nil
}
func (self *SRegion) CreateWebAcl(name, desc string, wafType cloudprovider.TWafType, action *cloudprovider.DefaultAction) (*SWebAcl, error) {
input := wafv2.CreateWebACLInput{}
input.SetName(name)
if len(desc) > 0 {
input.SetDescription(desc)
}
switch wafType {
case cloudprovider.WafTypeRegional, cloudprovider.WafTypeCloudFront:
input.SetScope(strings.ToUpper(string(wafType)))
default:
return nil, errors.Errorf("invalid waf type %s", wafType)
}
if action != nil {
defaultAction := wafv2.DefaultAction{}
switch action.Action {
case cloudprovider.WafActionAllow:
defaultAction.Allow = &wafv2.AllowAction{}
case cloudprovider.WafActionBlock:
defaultAction.Block = &wafv2.BlockAction{}
}
input.SetDefaultAction(&defaultAction)
}
visib := &wafv2.VisibilityConfig{}
visib.SetSampledRequestsEnabled(true)
visib.SetCloudWatchMetricsEnabled(true)
visib.SetMetricName(name)
input.SetVisibilityConfig(visib)
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
output, err := client.CreateWebACL(&input)
if err != nil {
return nil, errors.Wrapf(err, "CreateWebAcl")
}
return self.GetWebAcl(*output.Summary.Id, name, *input.Scope)
}
func reverseConvertField(opts cloudprovider.SWafStatement) *wafv2.FieldToMatch {
ret := &wafv2.FieldToMatch{}
switch opts.MatchField {
case cloudprovider.WafMatchFieldBody:
body := &wafv2.Body{}
ret.SetBody(body)
case cloudprovider.WafMatchFieldJsonBody:
case cloudprovider.WafMatchFieldMethod:
method := &wafv2.Method{}
ret.SetMethod(method)
case cloudprovider.WafMatchFieldQuery:
switch opts.MatchFieldKey {
case "SingleArgument":
query := &wafv2.SingleQueryArgument{}
ret.SetSingleQueryArgument(query)
case "AllArguments":
query := &wafv2.AllQueryArguments{}
ret.SetAllQueryArguments(query)
default:
query := &wafv2.QueryString{}
ret.SetQueryString(query)
}
case cloudprovider.WafMatchFiledHeader:
head := &wafv2.SingleHeader{}
head.SetName(opts.MatchFieldKey)
ret.SetSingleHeader(head)
case cloudprovider.WafMatchFiledUriPath:
uri := &wafv2.UriPath{}
ret.SetUriPath(uri)
}
return ret
}
func reverseConvertStatement(statement cloudprovider.SWafStatement) *wafv2.Statement {
ret := &wafv2.Statement{}
trans := []*wafv2.TextTransformation{}
if statement.Transformations != nil {
for i, tran := range *statement.Transformations {
t := &wafv2.TextTransformation{}
switch tran {
case cloudprovider.WafTextTransformationNone:
t.SetType(wafv2.TextTransformationTypeNone)
case cloudprovider.WafTextTransformationLowercase:
t.SetType(wafv2.TextTransformationTypeLowercase)
case cloudprovider.WafTextTransformationCmdLine:
t.SetType(wafv2.TextTransformationTypeCmdLine)
case cloudprovider.WafTextTransformationUrlDecode:
t.SetType(wafv2.TextTransformationTypeUrlDecode)
case cloudprovider.WafTextTransformationHtmlEntityDecode:
t.SetType(wafv2.TextTransformationTypeHtmlEntityDecode)
case cloudprovider.WafTextTransformationCompressWithSpace:
t.SetType(wafv2.TextTransformationTypeCompressWhiteSpace)
}
t.SetPriority(int64(i))
trans = append(trans, t)
}
}
rules := []*wafv2.ExcludedRule{}
if statement.ExcludeRules != nil {
for _, r := range *statement.ExcludeRules {
name := r.Name
rules = append(rules, &wafv2.ExcludedRule{
Name: &name,
})
}
}
field := reverseConvertField(statement)
switch statement.Type {
case cloudprovider.WafStatementTypeRate:
rate := &wafv2.RateBasedStatement{}
rate.SetLimit(*statement.Limit)
fd := &wafv2.ForwardedIPConfig{}
if len(statement.ForwardedIPHeader) > 0 {
fd.SetHeaderName(statement.ForwardedIPHeader)
rate.SetForwardedIPConfig(fd)
}
ret.SetRateBasedStatement(rate)
case cloudprovider.WafStatementTypeIPSet:
ipset := &wafv2.IPSetReferenceStatement{}
ipset.SetARN(statement.IPSetId)
fd := &wafv2.IPSetForwardedIPConfig{}
if len(statement.ForwardedIPHeader) > 0 {
fd.SetHeaderName(statement.ForwardedIPHeader)
ipset.SetIPSetForwardedIPConfig(fd)
}
ret.SetIPSetReferenceStatement(ipset)
case cloudprovider.WafStatementTypeXssMatch:
xss := &wafv2.XssMatchStatement{}
if len(trans) > 0 {
xss.SetTextTransformations(trans)
}
field := &wafv2.FieldToMatch{}
xss.SetFieldToMatch(field)
xss.SetTextTransformations(trans)
ret.SetXssMatchStatement(xss)
case cloudprovider.WafStatementTypeSize:
size := &wafv2.SizeConstraintStatement{}
size.SetFieldToMatch(field)
size.SetSize(*statement.Size)
ret.SetSizeConstraintStatement(size)
case cloudprovider.WafStatementTypeGeoMatch:
geo := &wafv2.GeoMatchStatement{}
values := []*string{}
if statement.MatchFieldValues != nil {
for i := range *statement.MatchFieldValues {
v := (*statement.MatchFieldValues)[i]
values = append(values, &v)
}
geo.SetCountryCodes(values)
}
fd := &wafv2.ForwardedIPConfig{}
if len(statement.ForwardedIPHeader) > 0 {
fd.SetHeaderName(statement.ForwardedIPHeader)
geo.SetForwardedIPConfig(fd)
}
ret.SetGeoMatchStatement(geo)
case cloudprovider.WafStatementTypeRegexSet:
regex := &wafv2.RegexPatternSetReferenceStatement{}
regex.SetARN(statement.RegexSetId)
if len(trans) > 0 {
regex.SetTextTransformations(trans)
}
regex.SetFieldToMatch(field)
ret.SetRegexPatternSetReferenceStatement(regex)
case cloudprovider.WafStatementTypeByteMatch:
bm := &wafv2.ByteMatchStatement{}
if len(trans) > 0 {
bm.SetTextTransformations(trans)
}
bm.SetSearchString([]byte(statement.SearchString))
if len(statement.Operator) > 0 {
bm.SetPositionalConstraint(string(statement.Operator))
}
bm.SetFieldToMatch(field)
ret.SetByteMatchStatement(bm)
case cloudprovider.WafStatementTypeRuleGroup:
rg := &wafv2.RuleGroupReferenceStatement{}
rg.SetARN(statement.RuleGroupId)
if len(rules) > 0 {
rg.SetExcludedRules(rules)
}
ret.SetRuleGroupReferenceStatement(rg)
case cloudprovider.WafStatementTypeSqliMatch:
sqli := &wafv2.SqliMatchStatement{}
if len(trans) > 0 {
sqli.SetTextTransformations(trans)
}
sqli.SetFieldToMatch(field)
ret.SetSqliMatchStatement(sqli)
case cloudprovider.WafStatementTypeLabelMatch:
case cloudprovider.WafStatementTypeManagedRuleGroup:
rg := &wafv2.ManagedRuleGroupStatement{}
rg.SetName(statement.ManagedRuleGroupName)
rg.SetVendorName("aws")
if len(rules) > 0 {
rg.SetExcludedRules(rules)
}
ret.SetManagedRuleGroupStatement(rg)
}
return ret
}
func (self *SWebAcl) AddRule(opts *cloudprovider.SWafRule) (cloudprovider.ICloudWafRule, error) {
input := &wafv2.UpdateWebACLInput{}
input.SetLockToken(self.LockToken)
input.SetId(self.Id)
input.SetName(self.Name)
input.SetScope(self.scope)
input.SetDescription(self.Description)
input.SetDefaultAction(self.sWebDetails.DefaultAction)
input.SetVisibilityConfig(self.sWebDetails.VisibilityConfig)
rules := self.sWebDetails.Rules
rule := &wafv2.Rule{}
rule.SetName(opts.Name)
rule.SetPriority(int64(opts.Priority))
action := &wafv2.RuleAction{}
if opts.Action != nil {
switch opts.Action.Action {
case cloudprovider.WafActionAllow:
allow := &wafv2.AllowAction{}
action.SetAllow(allow)
case cloudprovider.WafActionBlock:
block := &wafv2.BlockAction{}
action.SetBlock(block)
case cloudprovider.WafActionCount:
count := &wafv2.CountAction{}
action.SetCount(count)
}
}
rule.SetAction(action)
visib := &wafv2.VisibilityConfig{}
visib.SetSampledRequestsEnabled(false)
visib.SetCloudWatchMetricsEnabled(true)
visib.SetMetricName(opts.Name)
rule.SetVisibilityConfig(visib)
statement := &wafv2.Statement{}
switch opts.StatementCondition {
case cloudprovider.WafStatementConditionOr:
ss := &wafv2.OrStatement{}
for _, s := range opts.Statements {
ss.Statements = append(ss.Statements, reverseConvertStatement(s))
}
statement.SetOrStatement(ss)
case cloudprovider.WafStatementConditionAnd:
ss := &wafv2.AndStatement{}
for _, s := range opts.Statements {
ss.Statements = append(ss.Statements, reverseConvertStatement(s))
}
statement.SetAndStatement(ss)
case cloudprovider.WafStatementConditionNot:
ss := &wafv2.NotStatement{}
for _, s := range opts.Statements {
ss.SetStatement(reverseConvertStatement(s))
break
}
statement.SetNotStatement(ss)
case cloudprovider.WafStatementConditionNone:
for _, s := range opts.Statements {
statement = reverseConvertStatement(s)
break
}
}
rule.SetStatement(statement)
rules = append(rules, rule)
input.SetRules(rules)
client, err := self.region.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
_, err = client.UpdateWebACL(input)
if err != nil {
return nil, errors.Wrapf(err, "UpdateWebACL")
}
ret := &sWafRule{waf: self, Rule: rule}
return ret, nil
}
func (self *SWebAcl) GetCloudResources() ([]cloudprovider.SCloudResource, error) {
ret := []cloudprovider.SCloudResource{}
for _, resType := range []string{"APPLICATION_LOAD_BALANCER", "API_GATEWAY", "APPSYNC"} {
resIds, err := self.region.ListResourcesForWebACL(resType, self.ARN)
if err != nil {
return nil, errors.Wrapf(err, "ListResourcesForWebACL(%s, %s)", resType, self.ARN)
}
for _, resId := range resIds {
ret = append(ret, cloudprovider.SCloudResource{
Id: resId,
Type: resType,
})
}
}
return ret, nil
}
+146
View File
@@ -0,0 +1,146 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aws
import (
"github.com/aws/aws-sdk-go/service/wafv2"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SWafIPSet struct {
region *SRegion
scope string
Addresses []string
ARN string
Description string
Id string
LockToken string
Name string
}
func (self *SWafIPSet) GetName() string {
return self.Name
}
func (self *SWafIPSet) GetDesc() string {
return self.Description
}
func (self *SWafIPSet) GetGlobalId() string {
return self.ARN
}
func (self *SWafIPSet) GetType() cloudprovider.TWafType {
switch self.scope {
case SCOPE_CLOUDFRONT:
return cloudprovider.WafTypeCloudFront
case SCOPE_REGIONAL:
return cloudprovider.WafTypeRegional
}
return cloudprovider.TWafType(self.scope)
}
func (self *SWafIPSet) GetAddresses() cloudprovider.WafAddresses {
if len(self.Addresses) == 0 {
ipSet, err := self.region.GetIPSet(self.Id, self.Name, self.scope)
if err != nil {
return cloudprovider.WafAddresses{}
}
return ipSet.Addresses
}
return self.Addresses
}
func (self *SWafIPSet) Delete() error {
return self.region.DeleteIPSet(self.Id, self.Name, self.scope, self.LockToken)
}
func (self *SRegion) ListIPSets(scope string) ([]SWafIPSet, error) {
if scope == SCOPE_CLOUDFRONT && self.RegionId != "us-east-1" {
return []SWafIPSet{}, nil
}
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
ret := []SWafIPSet{}
input := wafv2.ListIPSetsInput{}
input.SetScope(scope)
for {
resp, err := client.ListIPSets(&input)
if err != nil {
return nil, errors.Wrapf(err, "ListIPSets")
}
part := []SWafIPSet{}
jsonutils.Update(&part, resp.IPSets)
ret = append(ret, part...)
if resp.NextMarker == nil || len(*resp.NextMarker) == 0 {
break
}
input.SetNextMarker(*resp.NextMarker)
}
return ret, nil
}
func (self *SRegion) GetIPSet(id, name, scope string) (*SWafIPSet, error) {
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
input := wafv2.GetIPSetInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
resp, err := client.GetIPSet(&input)
if err != nil {
return nil, errors.Wrapf(err, "GetIPSet")
}
ret := &SWafIPSet{LockToken: *resp.LockToken}
return ret, jsonutils.Update(ret, resp.IPSet)
}
func (self *SRegion) DeleteIPSet(id, name, scope, lockToken string) error {
client, err := self.getWafClient()
if err != nil {
return errors.Wrapf(err, "getWafClient")
}
input := wafv2.DeleteIPSetInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
input.SetLockToken(lockToken)
_, err = client.DeleteIPSet(&input)
return errors.Wrapf(err, "DeleteIPSet")
}
func (self *SRegion) GetICloudWafIPSets() ([]cloudprovider.ICloudWafIPSet, error) {
ret := []cloudprovider.ICloudWafIPSet{}
for _, scope := range WAF_SCOPES {
part, err := self.ListIPSets(scope)
if err != nil {
return nil, errors.Wrapf(err, "ListIPSets(%s)", scope)
}
for i := range part {
part[i].scope = scope
part[i].region = self
ret = append(ret, &part[i])
}
}
return ret, nil
}
+155
View File
@@ -0,0 +1,155 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aws
import (
"github.com/aws/aws-sdk-go/service/wafv2"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type RegularExpression struct {
RegexString string
}
type SWafRegexSet struct {
region *SRegion
scope string
RegularExpressionList []RegularExpression
ARN string
Description string
Id string
LockToken string
Name string
}
func (self *SWafRegexSet) GetName() string {
return self.Name
}
func (self *SWafRegexSet) GetDesc() string {
return self.Description
}
func (self *SWafRegexSet) GetGlobalId() string {
return self.ARN
}
func (self *SWafRegexSet) GetType() cloudprovider.TWafType {
switch self.scope {
case SCOPE_REGIONAL:
return cloudprovider.WafTypeRegional
case SCOPE_CLOUDFRONT:
return cloudprovider.WafTypeCloudFront
default:
return cloudprovider.TWafType(self.scope)
}
}
func (self *SWafRegexSet) GetRegexPatterns() cloudprovider.WafRegexPatterns {
if len(self.RegularExpressionList) == 0 {
rSet, err := self.region.GetRegexSet(self.Id, self.Name, self.scope)
if err != nil {
return cloudprovider.WafRegexPatterns{}
}
jsonutils.Update(self, rSet)
}
ret := cloudprovider.WafRegexPatterns{}
for _, r := range self.RegularExpressionList {
ret = append(ret, r.RegexString)
}
return ret
}
func (self *SWafRegexSet) Delete() error {
return self.region.DeleteRegexSet(self.Id, self.Name, self.scope, self.LockToken)
}
func (self *SRegion) ListRegexSets(scope string) ([]SWafRegexSet, error) {
if scope == SCOPE_CLOUDFRONT && self.RegionId != "us-east-1" {
return []SWafRegexSet{}, nil
}
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
ret := []SWafRegexSet{}
input := wafv2.ListRegexPatternSetsInput{}
input.SetScope(scope)
for {
resp, err := client.ListRegexPatternSets(&input)
if err != nil {
return nil, errors.Wrapf(err, "ListRegexPatternSets")
}
part := []SWafRegexSet{}
jsonutils.Update(&part, resp.RegexPatternSets)
ret = append(ret, part...)
if resp.NextMarker == nil || len(*resp.NextMarker) == 0 {
break
}
input.SetNextMarker(*resp.NextMarker)
}
return ret, nil
}
func (self *SRegion) GetRegexSet(id, name, scope string) (*SWafRegexSet, error) {
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
input := wafv2.GetRegexPatternSetInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
resp, err := client.GetRegexPatternSet(&input)
if err != nil {
return nil, errors.Wrapf(err, "GetRegexPatternSet")
}
ret := &SWafRegexSet{LockToken: *resp.LockToken}
return ret, jsonutils.Update(ret, resp.RegexPatternSet)
}
func (self *SRegion) DeleteRegexSet(id, name, scope, lockToken string) error {
client, err := self.getWafClient()
if err != nil {
return errors.Wrapf(err, "getWafClient")
}
input := wafv2.DeleteRegexPatternSetInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
input.SetLockToken(lockToken)
_, err = client.DeleteRegexPatternSet(&input)
return errors.Wrapf(err, "DeleteRegexPatternSet")
}
func (self *SRegion) GetICloudWafRegexSets() ([]cloudprovider.ICloudWafRegexSet, error) {
ret := []cloudprovider.ICloudWafRegexSet{}
for _, scope := range WAF_SCOPES {
part, err := self.ListRegexSets(scope)
if err != nil {
return nil, errors.Wrapf(err, "ListRegexSets(%s)", scope)
}
for i := range part {
part[i].scope = scope
part[i].region = self
ret = append(ret, &part[i])
}
}
return ret, nil
}
+135
View File
@@ -0,0 +1,135 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aws
import (
"github.com/aws/aws-sdk-go/service/wafv2"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
)
type SWafRuleGroup struct {
Description string
Name string
VendorName string
Capacity int `json:"Capacity"`
Rules []SWafRule
}
func (self *SRegion) ListAvailableManagedRuleGroups(scope string) ([]SWafRuleGroup, error) {
if scope == SCOPE_CLOUDFRONT && self.RegionId != "us-east-1" {
return []SWafRuleGroup{}, nil
}
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
ret := []SWafRuleGroup{}
input := wafv2.ListAvailableManagedRuleGroupsInput{}
input.SetScope(scope)
for {
resp, err := client.ListAvailableManagedRuleGroups(&input)
if err != nil {
return nil, errors.Wrapf(err, "ListAvailableManagedRuleGroups")
}
part := []SWafRuleGroup{}
jsonutils.Update(&part, resp.ManagedRuleGroups)
ret = append(ret, part...)
if resp.NextMarker == nil || len(*resp.NextMarker) == 0 {
break
}
input.SetNextMarker(*resp.NextMarker)
}
return ret, nil
}
func (self *SRegion) DescribeManagedRuleGroup(name, scope, vendorName string) (*SWafRuleGroup, error) {
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
input := wafv2.DescribeManagedRuleGroupInput{}
input.SetName(name)
input.SetScope(scope)
input.SetVendorName(vendorName)
resp, err := client.DescribeManagedRuleGroup(&input)
if err != nil {
return nil, err
}
ret := &SWafRuleGroup{
Name: name,
VendorName: vendorName,
}
return ret, jsonutils.Update(ret, resp)
}
func (self *SRegion) ListRuleGroups(scope string) ([]SWafRuleGroup, error) {
if scope == SCOPE_CLOUDFRONT && self.RegionId != "us-east-1" {
return []SWafRuleGroup{}, nil
}
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
ret := []SWafRuleGroup{}
input := wafv2.ListRuleGroupsInput{}
input.SetScope(scope)
for {
resp, err := client.ListRuleGroups(&input)
if err != nil {
return nil, errors.Wrapf(err, "ListRuleGroups")
}
part := []SWafRuleGroup{}
jsonutils.Update(&part, resp.RuleGroups)
ret = append(ret, part...)
if resp.NextMarker == nil || len(*resp.NextMarker) == 0 {
break
}
input.SetNextMarker(*resp.NextMarker)
}
return ret, nil
}
func (self *SRegion) GetRuleGroup(id, name, scope string) (*SWafRuleGroup, error) {
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
input := wafv2.GetRuleGroupInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
resp, err := client.GetRuleGroup(&input)
if err != nil {
return nil, errors.Wrapf(err, "GetRuleGroup")
}
ret := &SWafRuleGroup{}
return ret, jsonutils.Update(ret, resp.RuleGroup)
}
func (self *SRegion) DeleteRuleGroup(id, name, scope, lockToken string) error {
client, err := self.getWafClient()
if err != nil {
return errors.Wrapf(err, "getWafClient")
}
input := wafv2.DeleteRuleGroupInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
input.SetLockToken(lockToken)
_, err = client.DeleteRuleGroup(&input)
return errors.Wrapf(err, "DeleteRuleGroup")
}
+265
View File
@@ -0,0 +1,265 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aws
import (
"strings"
"github.com/aws/aws-sdk-go/service/wafv2"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type sWebDetails struct {
*wafv2.WebACL
}
type sWafRule struct {
waf *SWebAcl
*wafv2.Rule
}
func (self *sWafRule) GetAction() *cloudprovider.DefaultAction {
ret := &cloudprovider.DefaultAction{}
if self.Action.Allow != nil {
ret.Action = cloudprovider.WafActionAllow
} else if self.Action.Block != nil {
ret.Action = cloudprovider.WafActionBlock
} else if self.Action.Count != nil {
ret.Action = cloudprovider.WafActionCount
}
return ret
}
func (self *sWafRule) GetDesc() string {
return ""
}
func (self *sWafRule) GetName() string {
return *self.Rule.Name
}
func (self *sWafRule) GetGlobalId() string {
return self.GetName()
}
func (self *sWafRule) GetPriority() int {
return int(*self.Rule.Priority)
}
func (self *sWafRule) Delete() error {
input := wafv2.UpdateWebACLInput{}
rules := []*wafv2.Rule{}
for _, rule := range self.waf.sWebDetails.Rules {
if *rule.Name == *self.Name {
continue
}
rules = append(rules, rule)
}
input.SetRules(rules)
input.SetLockToken(self.waf.LockToken)
input.SetId(self.waf.Id)
input.SetName(self.waf.Name)
input.SetScope(self.waf.scope)
input.SetDescription(self.waf.Description)
input.SetDefaultAction(self.waf.DefaultAction)
input.SetVisibilityConfig(self.waf.sWebDetails.VisibilityConfig)
client, err := self.waf.region.getWafClient()
if err != nil {
return errors.Wrapf(err, "getWafClient")
}
_, err = client.UpdateWebACL(&input)
return errors.Wrapf(err, "UpdateWebACL")
}
func (self *sWafRule) Update(opts *cloudprovider.SWafRule) error {
return cloudprovider.ErrNotImplemented
}
func (self *sWafRule) GetStatementCondition() cloudprovider.TWafStatementCondition {
if self.Rule.Statement == nil {
return cloudprovider.WafStatementConditionNone
}
if self.Rule.Statement.AndStatement != nil {
return cloudprovider.WafStatementConditionAnd
} else if self.Rule.Statement.OrStatement != nil {
return cloudprovider.WafStatementConditionOr
} else if self.Rule.Statement.NotStatement != nil {
return cloudprovider.WafStatementConditionNot
}
return cloudprovider.WafStatementConditionNone
}
type sWafStatement struct {
*wafv2.Statement
}
func (self *sWafStatement) convert() cloudprovider.SWafStatement {
statement := cloudprovider.SWafStatement{
Transformations: &cloudprovider.TextTransformations{},
}
if self.ByteMatchStatement != nil {
statement.Type = cloudprovider.WafStatementTypeByteMatch
if self.ByteMatchStatement.PositionalConstraint != nil {
operator := strings.ReplaceAll(utils.CamelSplit(*self.ByteMatchStatement.PositionalConstraint, "_"), "_", "")
if operator == "None" {
operator = ""
}
statement.Operator = cloudprovider.TWafOperator(operator)
}
fillStatement(&statement, self.ByteMatchStatement.FieldToMatch)
statement.SearchString = string(self.ByteMatchStatement.SearchString)
fillTransformations(&statement, self.ByteMatchStatement.TextTransformations)
} else if self.GeoMatchStatement != nil {
statement.Type = cloudprovider.WafStatementTypeGeoMatch
statement.MatchFieldKey = "CountryCodes"
values := cloudprovider.TWafMatchFieldValues{}
for _, code := range self.GeoMatchStatement.CountryCodes {
values = append(values, *code)
}
statement.MatchFieldValues = &values
if self.GeoMatchStatement.ForwardedIPConfig != nil {
statement.ForwardedIPHeader = *self.GeoMatchStatement.ForwardedIPConfig.HeaderName
}
} else if self.IPSetReferenceStatement != nil {
statement.Type = cloudprovider.WafStatementTypeIPSet
statement.IPSetId = *self.IPSetReferenceStatement.ARN
if self.IPSetReferenceStatement.IPSetForwardedIPConfig != nil {
statement.ForwardedIPHeader = *self.IPSetReferenceStatement.IPSetForwardedIPConfig.HeaderName
}
} else if self.ManagedRuleGroupStatement != nil {
statement.Type = cloudprovider.WafStatementTypeManagedRuleGroup
statement.ManagedRuleGroupName = *self.ManagedRuleGroupStatement.Name
fillExcludeRules(&statement, self.ManagedRuleGroupStatement.ExcludedRules)
} else if self.RateBasedStatement != nil {
statement.Type = cloudprovider.WafStatementTypeRate
statement.Limit = self.RateBasedStatement.Limit
if self.RateBasedStatement.ForwardedIPConfig != nil {
statement.ForwardedIPHeader = *self.RateBasedStatement.ForwardedIPConfig.HeaderName
}
} else if self.RegexPatternSetReferenceStatement != nil {
statement.Type = cloudprovider.WafStatementTypeRegexSet
statement.RegexSetId = *self.RegexPatternSetReferenceStatement.ARN
fillStatement(&statement, self.RegexPatternSetReferenceStatement.FieldToMatch)
} else if self.RuleGroupReferenceStatement != nil {
statement.Type = cloudprovider.WafStatementTypeRuleGroup
statement.RuleGroupId = *self.RuleGroupReferenceStatement.ARN
fillExcludeRules(&statement, self.RuleGroupReferenceStatement.ExcludedRules)
} else if self.SizeConstraintStatement != nil {
statement.Type = cloudprovider.WafStatementTypeSize
statement.Operator = cloudprovider.TWafOperator(*self.SizeConstraintStatement.ComparisonOperator)
statement.Size = self.SizeConstraintStatement.Size
fillStatement(&statement, self.SizeConstraintStatement.FieldToMatch)
fillTransformations(&statement, self.SizeConstraintStatement.TextTransformations)
} else if self.SqliMatchStatement != nil {
statement.Type = cloudprovider.WafStatementTypeSqliMatch
fillStatement(&statement, self.SqliMatchStatement.FieldToMatch)
fillTransformations(&statement, self.SqliMatchStatement.TextTransformations)
} else if self.XssMatchStatement != nil {
statement.Type = cloudprovider.WafStatementTypeXssMatch
fillStatement(&statement, self.XssMatchStatement.FieldToMatch)
fillTransformations(&statement, self.XssMatchStatement.TextTransformations)
}
return statement
}
func fillStatement(statement *cloudprovider.SWafStatement, field *wafv2.FieldToMatch) {
if field.AllQueryArguments != nil {
statement.MatchField = cloudprovider.WafMatchFieldQuery
statement.MatchFieldKey = "AllArguments"
} else if field.Body != nil {
statement.MatchField = cloudprovider.WafMatchFieldBody
} else if field.Method != nil {
statement.MatchField = cloudprovider.WafMatchFieldMethod
} else if field.QueryString != nil {
statement.MatchField = cloudprovider.WafMatchFieldQuery
} else if field.SingleHeader != nil {
statement.MatchField = cloudprovider.WafMatchFiledHeader
statement.MatchFieldKey = *field.SingleHeader.Name
} else if field.SingleQueryArgument != nil {
statement.MatchField = cloudprovider.WafMatchFieldQuery
statement.MatchFieldKey = "SingleArgument"
} else if field.UriPath != nil {
statement.MatchField = cloudprovider.WafMatchFiledUriPath
}
}
func fillTransformations(statement *cloudprovider.SWafStatement, trans []*wafv2.TextTransformation) {
values := cloudprovider.TextTransformations{}
for _, tran := range trans {
switch *tran.Type {
case wafv2.TextTransformationTypeNone:
values = append(values, cloudprovider.WafTextTransformationNone)
case wafv2.TextTransformationTypeLowercase:
values = append(values, cloudprovider.WafTextTransformationLowercase)
case wafv2.TextTransformationTypeCmdLine:
values = append(values, cloudprovider.WafTextTransformationCmdLine)
case wafv2.TextTransformationTypeUrlDecode:
values = append(values, cloudprovider.WafTextTransformationUrlDecode)
case wafv2.TextTransformationTypeHtmlEntityDecode:
values = append(values, cloudprovider.WafTextTransformationHtmlEntityDecode)
case wafv2.TextTransformationTypeCompressWhiteSpace:
values = append(values, cloudprovider.WafTextTransformationCompressWithSpace)
}
}
statement.Transformations = &values
}
func fillExcludeRules(statement *cloudprovider.SWafStatement, rules []*wafv2.ExcludedRule) {
values := cloudprovider.SExcludeRules{}
for _, rule := range rules {
values = append(values, cloudprovider.SExcludeRule{Name: *rule.Name})
}
statement.ExcludeRules = &values
}
func (self *sWafRule) GetStatements() ([]cloudprovider.SWafStatement, error) {
if self.Rule.Statement == nil {
return []cloudprovider.SWafStatement{}, nil
}
ret := []cloudprovider.SWafStatement{}
if self.Rule.Statement.AndStatement != nil {
for i := range self.Rule.Statement.AndStatement.Statements {
statement := sWafStatement{self.Rule.Statement.AndStatement.Statements[i]}
ret = append(ret, statement.convert())
}
} else if self.Rule.Statement.OrStatement != nil {
for i := range self.Rule.Statement.OrStatement.Statements {
statement := sWafStatement{self.Rule.Statement.OrStatement.Statements[i]}
ret = append(ret, statement.convert())
}
} else if self.Rule.Statement.NotStatement != nil {
statement := sWafStatement{self.Rule.Statement.NotStatement.Statement}
ret = append(ret, statement.convert())
} else {
statement := sWafStatement{self.Rule.Statement}
ret = append(ret, statement.convert())
}
return ret, nil
}
func (self *SWebAcl) GetRules() ([]cloudprovider.ICloudWafRule, error) {
ret := []cloudprovider.ICloudWafRule{}
for i := range self.sWebDetails.Rules {
ret = append(ret, &sWafRule{
waf: self,
Rule: self.sWebDetails.Rules[i],
})
}
return ret, nil
}
+323
View File
@@ -0,0 +1,323 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package azure
import (
"net/url"
"strings"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
type SGatewayipconfiguration struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Properties struct {
Provisioningstate string `json:"provisioningState"`
Subnet struct {
ID string `json:"id"`
} `json:"subnet"`
} `json:"properties"`
Type string `json:"type"`
}
type SFrontendipconfiguration struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Type string `json:"type"`
Properties struct {
Provisioningstate string `json:"provisioningState"`
Privateipallocationmethod string `json:"privateIPAllocationMethod"`
PublicIPAddress struct {
ID string
}
PrivateIPAddress string
Subnet struct {
ID string `json:"id"`
} `json:"subnet"`
Httplisteners []struct {
ID string `json:"id"`
} `json:"httpListeners"`
} `json:"properties"`
}
type SFrontendport struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Properties struct {
Provisioningstate string `json:"provisioningState"`
Port int `json:"port"`
Httplisteners []struct {
ID string `json:"id"`
} `json:"httpListeners"`
} `json:"properties"`
Type string `json:"type"`
}
type SBackendaddresspool struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Properties struct {
Provisioningstate string `json:"provisioningState"`
Backendaddresses []interface{} `json:"backendAddresses"`
Requestroutingrules []struct {
ID string `json:"id"`
} `json:"requestRoutingRules"`
} `json:"properties"`
Type string `json:"type"`
}
type SBackendhttpsettingscollection struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Properties struct {
Provisioningstate string `json:"provisioningState"`
Port int `json:"port"`
Protocol string `json:"protocol"`
Cookiebasedaffinity string `json:"cookieBasedAffinity"`
Pickhostnamefrombackendaddress bool `json:"pickHostNameFromBackendAddress"`
Requesttimeout int `json:"requestTimeout"`
Requestroutingrules []struct {
ID string `json:"id"`
} `json:"requestRoutingRules"`
} `json:"properties"`
Type string `json:"type"`
}
type SHttplistener struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Properties struct {
Provisioningstate string `json:"provisioningState"`
Frontendipconfiguration struct {
ID string `json:"id"`
} `json:"frontendIPConfiguration"`
Frontendport struct {
ID string `json:"id"`
} `json:"frontendPort"`
Protocol string `json:"protocol"`
Requireservernameindication bool `json:"requireServerNameIndication"`
Requestroutingrules []struct {
ID string `json:"id"`
} `json:"requestRoutingRules"`
} `json:"properties"`
Type string `json:"type"`
}
type SRequestroutingrule struct {
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Properties struct {
Provisioningstate string `json:"provisioningState"`
Ruletype string `json:"ruleType"`
Httplistener struct {
ID string `json:"id"`
} `json:"httpListener"`
Backendaddresspool struct {
ID string `json:"id"`
} `json:"backendAddressPool"`
Backendhttpsettings struct {
ID string `json:"id"`
} `json:"backendHttpSettings"`
} `json:"properties"`
Type string `json:"type"`
}
type SApplicationGatewayProperties struct {
Provisioningstate string `json:"provisioningState"`
Resourceguid string `json:"resourceGuid"`
Sku struct {
Name string `json:"name"`
Tier string `json:"tier"`
Capacity string `json:"capacity"`
} `json:"sku"`
Operationalstate string `json:"operationalState"`
Gatewayipconfigurations []SGatewayipconfiguration `json:"gatewayIPConfigurations"`
Sslcertificates []interface{} `json:"sslCertificates"`
Authenticationcertificates []interface{} `json:"authenticationCertificates"`
Frontendipconfigurations []SFrontendipconfiguration `json:"frontendIPConfigurations"`
Frontendports []SFrontendport `json:"frontendPorts"`
Backendaddresspools []SBackendaddresspool `json:"backendAddressPools"`
Backendhttpsettingscollection []SBackendhttpsettingscollection `json:"backendHttpSettingsCollection"`
Httplisteners []SHttplistener `json:"httpListeners"`
Urlpathmaps []interface{} `json:"urlPathMaps"`
Requestroutingrules []SRequestroutingrule `json:"requestRoutingRules"`
Probes []interface{} `json:"probes"`
Redirectconfigurations []interface{} `json:"redirectConfigurations"`
Webapplicationfirewallconfiguration struct {
Enabled bool `json:"enabled"`
Firewallmode string `json:"firewallMode"`
Rulesettype string `json:"ruleSetType"`
Rulesetversion string `json:"ruleSetVersion"`
Disabledrulegroups []interface{} `json:"disabledRuleGroups"`
Requestbodycheck bool `json:"requestBodyCheck"`
} `json:"webApplicationFirewallConfiguration"`
Enablehttp2 bool `json:"enableHttp2"`
}
type SApplicationGateway struct {
region *SRegion
multicloud.SResourceBase
multicloud.AzureTags
Name string `json:"name"`
ID string `json:"id"`
Etag string `json:"etag"`
Type string `json:"type"`
Location string `json:"location"`
Properties SApplicationGatewayProperties `json:"properties"`
}
func (self *SApplicationGateway) GetName() string {
return self.Name
}
func (self *SApplicationGateway) GetId() string {
return self.ID
}
func (self *SApplicationGateway) GetGlobalId() string {
return strings.ToLower(self.ID)
}
func (self *SApplicationGateway) GetStatus() string {
switch self.Properties.Provisioningstate {
case "Deleting":
return api.APP_GATEWAY_STATUS_DELETING
case "Failed":
return api.APP_GATEWAY_STATUS_CREATE_FAILED
case "Succeeded":
return api.APP_GATEWAY_STATUS_AVAILABLE
case "Updating":
return api.APP_GATEWAY_STATUS_UPDATING
}
return api.APP_GATEWAY_STATUS_AVAILABLE
}
func (self *SApplicationGateway) GetInstanceType() string {
return self.Properties.Sku.Name
}
func (self *SApplicationGateway) GetBackends() ([]cloudprovider.SAppGatewayBackend, error) {
ret := []cloudprovider.SAppGatewayBackend{}
for _, conf := range self.Properties.Backendaddresspools {
backend := cloudprovider.SAppGatewayBackend{
Name: conf.Name,
RoutingRules: []cloudprovider.SAppGatewayRoutingRule{},
}
for _, r := range conf.Properties.Requestroutingrules {
rule := cloudprovider.SAppGatewayRoutingRule{}
for _, _rule := range self.Properties.Requestroutingrules {
if r.ID == _rule.ID {
rule.Name = _rule.Name
rule.Type = _rule.Properties.Ruletype
backend.RoutingRules = append(backend.RoutingRules, rule)
break
}
}
}
ret = append(ret, backend)
}
return ret, nil
}
func (self *SApplicationGateway) GetFrontends() ([]cloudprovider.SAppGatewayFrontend, error) {
ret := []cloudprovider.SAppGatewayFrontend{}
for _, conf := range self.Properties.Frontendipconfigurations {
front := cloudprovider.SAppGatewayFrontend{
Name: conf.Name,
HttpListener: []cloudprovider.SAppGatewayHttpListener{},
}
for _, l := range conf.Properties.Httplisteners {
listener := cloudprovider.SAppGatewayHttpListener{}
for _, p := range self.Properties.Httplisteners {
if strings.ToLower(p.ID) == strings.ToLower(l.ID) {
listener.Name = p.Name
listener.Protocol = p.Properties.Protocol
break
}
}
for _, p := range self.Properties.Frontendports {
for _, _p := range self.Properties.Httplisteners {
if strings.ToLower(_p.ID) == strings.ToLower(l.ID) {
listener.Port = p.Properties.Port
break
}
}
if listener.Port > 0 {
break
}
}
if len(listener.Name) > 0 {
front.HttpListener = append(front.HttpListener, listener)
}
}
if len(conf.Properties.PrivateIPAddress) > 0 {
front.IpAddr = conf.Properties.PrivateIPAddress
front.Type = "Vpc"
} else if len(conf.Properties.PublicIPAddress.ID) > 0 {
eip, err := self.region.GetEip(conf.Properties.PublicIPAddress.ID)
if err != nil {
continue
}
front.IpAddr = eip.GetIpAddr()
front.Type = "Eip"
}
ret = append(ret, front)
}
return ret, nil
}
func (self *SRegion) ListAppGateways() ([]SApplicationGateway, error) {
apps := []SApplicationGateway{}
err := self.list("Microsoft.Network/applicationGateways", url.Values{}, &apps)
if err != nil {
return nil, errors.Wrapf(err, "list")
}
return apps, nil
}
func (self *SRegion) GetApplicationGateway(id string) (*SApplicationGateway, error) {
ret := &SApplicationGateway{region: self}
return ret, self.get(id, url.Values{}, ret)
}
func (self *SRegion) GetICloudApplicationGateways() ([]cloudprovider.ICloudApplicationGateway, error) {
apps, err := self.ListAppGateways()
if err != nil {
return nil, errors.Wrapf(err, "ListAppGateways")
}
ret := []cloudprovider.ICloudApplicationGateway{}
for i := range apps {
apps[i].region = self
ret = append(ret, &apps[i])
}
return ret, nil
}
func (self *SRegion) GetICloudApplicationGatewayById(id string) (cloudprovider.ICloudApplicationGateway, error) {
return self.GetApplicationGateway(id)
}
+15
View File
@@ -435,6 +435,18 @@ func (self *SAzureClient) _apiVersion(resource string, params url.Values) string
if utils.IsInStringArray("publicipaddresses", info) {
return "2018-03-01"
}
if utils.IsInStringArray("frontdoorwebapplicationfirewallmanagedrulesets", info) {
return "2020-11-01"
}
if utils.IsInStringArray("frontdoorwebapplicationfirewallpolicies", info) {
return "2020-11-01"
}
if utils.IsInStringArray("applicationgatewaywebapplicationfirewallpolicies", info) {
return "2020-11-01"
}
if utils.IsInStringArray("applicationgatewayavailablewafrulesets", info) {
return "2018-06-01"
}
return "2018-06-01"
} else if utils.IsInStringArray("microsoft.classicnetwork", info) {
return "2016-04-01"
@@ -488,6 +500,9 @@ func (self *SAzureClient) _list(resource string, params url.Values) (jsonutils.J
return nil, fmt.Errorf("no avaiable subscriptions")
}
path = fmt.Sprintf("subscriptions/%s/%s", subId, resource)
case "Microsoft.Network/frontdoorWebApplicationFirewallPolicies":
path = fmt.Sprintf("subscriptions/%s/resourceGroups/%s/providers/%s", subId, params.Get("resourceGroups"), resource)
params.Del("resourceGroups")
default:
if len(subId) == 0 {
return nil, fmt.Errorf("no avaiable subscriptions")
@@ -0,0 +1,33 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/azure"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type AppGatewayListOptions struct {
}
shellutils.R(&AppGatewayListOptions{}, "app-gateway-list", "List app gateways", func(cli *azure.SRegion, args *AppGatewayListOptions) error {
apps, err := cli.ListAppGateways()
if err != nil {
return err
}
printList(apps, len(apps), 0, 0, []string{})
return nil
})
}
+70
View File
@@ -0,0 +1,70 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/azure"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type RuleGroupListOptions struct {
}
shellutils.R(&RuleGroupListOptions{}, "waf-rule-group-list", "List waf rule groups", func(cli *azure.SRegion, args *RuleGroupListOptions) error {
groups, err := cli.ListAppWafManagedRuleGroup()
if err != nil {
return err
}
printList(groups, len(groups), 0, 0, []string{})
return nil
})
type FrontDoorPolicyListOptions struct {
RESOURCE_GROUP string
}
shellutils.R(&FrontDoorPolicyListOptions{}, "front-door-policy-list", "List front door policies", func(cli *azure.SRegion, args *FrontDoorPolicyListOptions) error {
policies, err := cli.ListFrontDoorWafs(args.RESOURCE_GROUP)
if err != nil {
return err
}
printList(policies, 0, 0, 0, []string{})
return nil
})
type AppGatewayWafListOptions struct {
}
shellutils.R(&AppGatewayWafListOptions{}, "app-gateway-waf-list", "List app gateway wafs", func(cli *azure.SRegion, args *AppGatewayWafListOptions) error {
wafs, err := cli.ListAppWafs()
if err != nil {
return err
}
printList(wafs, 0, 0, 0, []string{})
return nil
})
type AppGatewayWafRuleGroupListOptions struct {
}
shellutils.R(&AppGatewayWafRuleGroupListOptions{}, "app-gateway-waf-rule-group-list", "List app gateway wafs", func(cli *azure.SRegion, args *AppGatewayWafRuleGroupListOptions) error {
group, err := cli.ListAppWafManagedRuleGroup()
if err != nil {
return err
}
printList(group, 0, 0, 0, []string{})
return nil
})
}
+617
View File
@@ -0,0 +1,617 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package azure
import (
"fmt"
"net/url"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
type SMatchvariable struct {
Variablename string `json:"variableName"`
Selector string `json:"selector"`
}
type SMatchcondition struct {
Matchvariables []SMatchvariable `json:"matchVariables"`
Operator string `json:"operator"`
Negationconditon bool `json:"negationConditon"`
Matchvalues []string `json:"matchValues"`
Transforms []string `json:"transforms"`
}
type CustomRule struct {
waf *SAppGatewayWaf
Name string `json:"name"`
Priority int `json:"priority"`
Ruletype string `json:"ruleType"`
//RateLimitThreshold *int `json:"rateLimitThreshold"`
Matchconditions []SMatchcondition `json:"matchConditions"`
Action string `json:"action"`
}
func (self *CustomRule) GetName() string {
return self.Name
}
func (self *CustomRule) GetGlobalId() string {
return fmt.Sprintf("%s-%s", self.waf.GetGlobalId(), self.GetName())
}
func (self *CustomRule) GetDesc() string {
return ""
}
func (self *CustomRule) GetPriority() int {
return self.Priority
}
func (self *CustomRule) Delete() error {
rules := []CustomRule{}
for _, rule := range self.waf.Properties.Customrules {
if rule.Name != self.Name {
rules = append(rules, rule)
}
}
self.waf.Properties.Customrules = rules
return self.waf.region.update(jsonutils.Marshal(self.waf), nil)
}
func wafMatchFieldAndKeyLocal2Cloud(opts cloudprovider.SWafStatement) ([]SMatchvariable, error) {
ret := []SMatchvariable{}
switch opts.MatchField {
case cloudprovider.WafMatchFieldQuery:
ret = append(ret, SMatchvariable{
Variablename: "QueryString",
})
case cloudprovider.WafMatchFieldMethod:
ret = append(ret, SMatchvariable{
Variablename: "RequestMethod",
})
case cloudprovider.WafMatchFiledUriPath:
ret = append(ret, SMatchvariable{
Variablename: "RequestUri",
})
case cloudprovider.WafMatchFiledHeader:
ret = append(ret, SMatchvariable{
Variablename: "RequestHeaders",
Selector: opts.MatchFieldKey,
})
case cloudprovider.WafMatchFiledPostArgs:
ret = append(ret, SMatchvariable{
Variablename: "PostArgs",
Selector: opts.MatchFieldKey,
})
case cloudprovider.WafMatchFieldBody:
ret = append(ret, SMatchvariable{
Variablename: "RequestBody",
})
case cloudprovider.WafMatchFiledCookie:
ret = append(ret, SMatchvariable{
Variablename: "RequestCookies",
Selector: opts.MatchFieldKey,
})
default:
return ret, fmt.Errorf("unsupported match filed %s", opts.MatchField)
}
return ret, nil
}
func wafMatchFieldAndKeyCloud2Local(vars []SMatchvariable) (cloudprovider.TWafMatchField, string, error) {
for _, v := range vars {
switch v.Variablename {
case "QueryString":
return cloudprovider.WafMatchFieldQuery, v.Selector, nil
case "RequestMethod":
return cloudprovider.WafMatchFieldMethod, "", nil
case "RequestUri":
return cloudprovider.WafMatchFiledUriPath, "", nil
case "RequestHeaders":
return cloudprovider.WafMatchFiledHeader, v.Selector, nil
case "PostArgs":
return cloudprovider.WafMatchFiledPostArgs, v.Selector, nil
case "RequestBody":
return cloudprovider.WafMatchFieldBody, "", nil
case "RequestCookies":
return cloudprovider.WafMatchFiledCookie, v.Selector, nil
default:
return "", "", fmt.Errorf("invalid variablename %s", v.Variablename)
}
}
return "", "", nil
}
func wafStatementLocal2Cloud(opts cloudprovider.SWafStatement) (SMatchcondition, error) {
ret := SMatchcondition{}
if opts.Transformations != nil {
for _, tran := range *opts.Transformations {
ret.Transforms = append(ret.Transforms, string(tran))
}
}
if opts.MatchFieldValues != nil {
ret.Matchvalues = *opts.MatchFieldValues
}
ret.Negationconditon = opts.Negation
ret.Operator = string(opts.Operator)
var err error
switch opts.Type {
case cloudprovider.WafStatementTypeIPSet:
ret.Operator = "IPMatch"
ret.Matchvariables = []SMatchvariable{
SMatchvariable{
Variablename: "RemoteAddr",
},
}
case cloudprovider.WafStatementTypeGeoMatch:
ret.Operator = "GeoMatch"
if len(opts.ForwardedIPHeader) == 0 {
ret.Matchvariables = []SMatchvariable{
SMatchvariable{
Variablename: "RemoteAddr",
},
}
} else {
ret.Matchvariables = []SMatchvariable{
SMatchvariable{
Variablename: "RequestHeaders",
Selector: opts.ForwardedIPHeader,
},
}
}
case cloudprovider.WafStatementTypeSize:
switch opts.Operator {
case "LT":
ret.Operator = "LessThan"
case "LE":
ret.Operator = "LessThanOrEqual"
case "GT":
ret.Operator = "GreaterThan"
default:
return ret, fmt.Errorf("invalid operator %s for %s", opts.Operator, opts.Type)
}
ret.Matchvariables, err = wafMatchFieldAndKeyLocal2Cloud(opts)
if err != nil {
return ret, errors.Wrapf(err, "wafMatchFieldAndKeyLocal2Cloud")
}
case cloudprovider.WafStatementTypeByteMatch:
switch opts.Operator {
case "Contains", "EndsWith", "Regex":
case "StartsWith":
ret.Operator = "BeginsWith"
case "Exactly":
ret.Operator = "Equal"
default:
return ret, fmt.Errorf("invalid operator %s for %s", opts.Operator, opts.Type)
}
ret.Matchvariables, err = wafMatchFieldAndKeyLocal2Cloud(opts)
if err != nil {
return ret, errors.Wrapf(err, "wafMatchFieldAndKeyLocal2Cloud")
}
}
return ret, nil
}
func wafRuleLocal2Cloud(opts *cloudprovider.SWafRule) (*CustomRule, error) {
ret := &CustomRule{}
ret.Name = opts.Name
ret.Priority = opts.Priority
ret.Ruletype = "MatchRule"
ret.Matchconditions = []SMatchcondition{}
for _, s := range opts.Statements {
cds, err := wafStatementLocal2Cloud(s)
if err != nil {
return nil, errors.Wrapf(err, "wafStatementLocal2Cloud")
}
ret.Matchconditions = append(ret.Matchconditions, cds)
}
ret.Action = "Block"
if opts.Action != nil {
ret.Action = string(opts.Action.Action)
}
return ret, nil
}
func (self *CustomRule) Update(opts *cloudprovider.SWafRule) error {
rules := []CustomRule{}
for _, rule := range self.waf.Properties.Customrules {
if rule.Name != self.Name {
rules = append(rules, rule)
} else {
rule, err := wafRuleLocal2Cloud(opts)
if err != nil {
return errors.Wrapf(err, "wafRuleLocal2Cloud")
}
rules = append(rules, *rule)
}
}
self.waf.Properties.Customrules = rules
return self.waf.region.update(jsonutils.Marshal(self.waf), nil)
}
func (self *CustomRule) GetAction() *cloudprovider.DefaultAction {
return &cloudprovider.DefaultAction{
Action: cloudprovider.TWafAction(self.Action),
}
}
func (self *CustomRule) GetStatementCondition() cloudprovider.TWafStatementCondition {
return cloudprovider.WafStatementConditionAnd
}
func (self *CustomRule) GetStatements() ([]cloudprovider.SWafStatement, error) {
ret := []cloudprovider.SWafStatement{}
for _, condition := range self.Matchconditions {
trans := cloudprovider.TextTransformations{}
for _, tran := range condition.Transforms {
trans = append(trans, cloudprovider.TWafTextTransformation(tran))
}
values := cloudprovider.TWafMatchFieldValues(condition.Matchvalues)
statement := cloudprovider.SWafStatement{
Negation: condition.Negationconditon,
Transformations: &trans,
MatchFieldValues: &values,
}
statement.MatchField, statement.MatchFieldKey, _ = wafMatchFieldAndKeyCloud2Local(condition.Matchvariables)
switch condition.Operator {
case "IPMatch":
statement.Type = cloudprovider.WafStatementTypeIPSet
case "GeoMatch":
statement.Type = cloudprovider.WafStatementTypeGeoMatch
case "LessThan":
statement.Type = cloudprovider.WafStatementTypeSize
statement.Operator = cloudprovider.WafOperatorLT
case "LessThanOrEqual":
statement.Type = cloudprovider.WafStatementTypeSize
statement.Operator = cloudprovider.WafOperatorLE
case "GreaterThan":
statement.Type = cloudprovider.WafStatementTypeSize
statement.Operator = cloudprovider.WafOperatorGT
case "BeginsWith":
statement.Type = cloudprovider.WafStatementTypeByteMatch
statement.Operator = cloudprovider.WafOperatorStartsWith
case "Contains", "EndsWith", "Regex":
statement.Type = cloudprovider.WafStatementTypeByteMatch
statement.Operator = cloudprovider.TWafOperator(condition.Operator)
case "Equal":
statement.Type = cloudprovider.WafStatementTypeByteMatch
statement.Operator = cloudprovider.WafOperatorExactly
default:
statement.Type = cloudprovider.WafStatementTypeByteMatch
}
ret = append(ret, statement)
}
return ret, nil
}
type ManagedRule struct {
Rulesettype string `json:"ruleSetType"`
Rulesetversion string `json:"ruleSetVersion"`
}
type ManagedRules struct {
waf *SAppGatewayWaf
Managedrulesets []ManagedRule `json:"managedRuleSets"`
}
func (self *ManagedRules) GetName() string {
return fmt.Sprintf("%s Managed rules", self.waf.GetName())
}
func (self *ManagedRules) GetGlobalId() string {
return self.waf.GetGlobalId()
}
func (self *ManagedRules) GetDesc() string {
return ""
}
func (self *ManagedRules) GetPriority() int {
return 0
}
func (self *ManagedRules) GetAction() *cloudprovider.DefaultAction {
return nil
}
func (self *ManagedRules) Delete() error {
return cloudprovider.ErrNotSupported
}
func (self *ManagedRules) Update(opts *cloudprovider.SWafRule) error {
rules := []ManagedRule{}
for _, s := range opts.Statements {
if len(s.ManagedRuleGroupName) == 0 {
return fmt.Errorf("missing managed rule group name")
}
names := strings.Split(s.ManagedRuleGroupName, "_")
if len(names) != 2 {
return fmt.Errorf("invalid managed rule group name %s", s.ManagedRuleGroupName)
}
rules = append(rules, ManagedRule{
Rulesettype: names[0],
Rulesetversion: names[1],
})
}
if len(rules) == 0 {
return fmt.Errorf("missing statements")
}
self.waf.Properties.Managedrules = ManagedRules{
Managedrulesets: rules,
}
return self.waf.region.update(jsonutils.Marshal(self.waf), nil)
}
func (self *ManagedRules) GetStatementCondition() cloudprovider.TWafStatementCondition {
return cloudprovider.WafStatementConditionAnd
}
func (self *ManagedRules) GetStatements() ([]cloudprovider.SWafStatement, error) {
ret := []cloudprovider.SWafStatement{}
for i := range self.Managedrulesets {
ruleGroupName := fmt.Sprintf("%s_%s", self.Managedrulesets[i].Rulesettype, self.Managedrulesets[i].Rulesetversion)
ret = append(ret, cloudprovider.SWafStatement{
ManagedRuleGroupName: ruleGroupName,
Type: cloudprovider.WafStatementTypeManagedRuleGroup,
RuleGroupId: ruleGroupName,
})
}
return ret, nil
}
type SAppGatewayWaf struct {
multicloud.SResourceBase
multicloud.AzureTags
region *SRegion
Name string `json:"name"`
ID string `json:"id"`
Type string `json:"type"`
Location string `json:"location"`
Properties struct {
ApplicationGateways []SApplicationGateway
HttpListeners []struct {
Id string
}
Resourcestate string `json:"resourceState"`
Provisioningstate string `json:"provisioningState"`
Policysettings struct {
State string `json:"state"`
Mode string `json:"mode"`
Maxrequestbodysizeinkb int `json:"maxRequestBodySizeInKb"`
Fileuploadlimitinmb int `json:"fileUploadLimitInMb"`
Requestbodycheck bool `json:"requestBodyCheck"`
} `json:"policySettings"`
Customrules []CustomRule `json:"customRules"`
Managedrules ManagedRules `json:"managedRules"`
} `json:"properties"`
}
func (self *SAppGatewayWaf) GetEnabled() bool {
return self.Properties.Policysettings.State == "Enabled"
}
func (self *SAppGatewayWaf) GetName() string {
return self.Name
}
func (self *SAppGatewayWaf) GetId() string {
return self.ID
}
func (self *SAppGatewayWaf) GetGlobalId() string {
return strings.ToLower(self.ID)
}
func (self *SAppGatewayWaf) Delete() error {
return self.region.del(self.ID)
}
func (self *SAppGatewayWaf) GetWafType() cloudprovider.TWafType {
return cloudprovider.WafTypeAppGateway
}
func (self *SAppGatewayWaf) AddRule(opts *cloudprovider.SWafRule) (cloudprovider.ICloudWafRule, error) {
rule, err := wafRuleLocal2Cloud(opts)
if err != nil {
return nil, errors.Wrapf(err, "wafRuleLocal2Cloud")
}
rule.waf = self
self.Properties.Customrules = append(self.Properties.Customrules, *rule)
err = self.region.update(jsonutils.Marshal(self), nil)
if err != nil {
return nil, errors.Wrapf(err, "update")
}
return rule, nil
}
func (self *SAppGatewayWaf) GetStatus() string {
switch self.Properties.Provisioningstate {
case "Deleting":
return api.WAF_STATUS_DELETING
case "Failed":
return api.WAF_STATUS_CREATE_FAILED
case "Succeeded":
return api.WAF_STATUS_AVAILABLE
case "Updating":
return api.WAF_STATUS_UPDATING
default:
return self.Properties.Provisioningstate
}
}
func (self *SAppGatewayWaf) GetRules() ([]cloudprovider.ICloudWafRule, error) {
ret := []cloudprovider.ICloudWafRule{}
for i := range self.Properties.Customrules {
self.Properties.Customrules[i].waf = self
ret = append(ret, &self.Properties.Customrules[i])
}
self.Properties.Managedrules.waf = self
ret = append(ret, &self.Properties.Managedrules)
return ret, nil
}
func (self *SAppGatewayWaf) Refresh() error {
waf, err := self.region.GetAppGatewayWaf(self.ID)
if err != nil {
return errors.Wrapf(err, "GetAppGatewayWa")
}
return jsonutils.Update(self, waf)
}
func (self *SAppGatewayWaf) GetDefaultAction() *cloudprovider.DefaultAction {
return &cloudprovider.DefaultAction{}
}
func (self *SRegion) ListAppWafs() ([]SAppGatewayWaf, error) {
ret := []SAppGatewayWaf{}
err := self.list("Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies", url.Values{}, &ret)
if err != nil {
return nil, errors.Wrapf(err, "list")
}
return ret, nil
}
type SAppWafRuleGroup struct {
Name string `json:"name"`
ID string `json:"id"`
Type string `json:"type"`
Properties struct {
Provisioningstate string `json:"provisioningState"`
Rulesettype string `json:"ruleSetType"`
Rulesetversion string `json:"ruleSetVersion"`
Rulegroups []struct {
Rulegroupname string `json:"ruleGroupName"`
Description string `json:"description"`
Rules []struct {
Ruleid int `json:"ruleId"`
Description string `json:"description"`
} `json:"rules"`
} `json:"ruleGroups"`
} `json:"properties"`
}
func (self *SRegion) CreateICloudWafInstance(opts *cloudprovider.WafCreateOptions) (cloudprovider.ICloudWafInstance, error) {
switch opts.Type {
case cloudprovider.WafTypeAppGateway:
return self.CreateAppWafInstance(opts.Name, opts.DefaultAction)
default:
return nil, errors.Wrapf(cloudprovider.ErrNoSuchProvder, "invalid waf type %s", opts.Type)
}
}
func (self *SRegion) GetICloudWafInstanceById(id string) (cloudprovider.ICloudWafInstance, error) {
if strings.Contains(id, "microsoft.network/applicationgatewaywebapplicationfirewallpolicies") {
return self.GetAppGatewayWaf(id)
}
return nil, errors.Wrapf(cloudprovider.ErrNotSupported, id)
}
func (self *SRegion) CreateAppWafInstance(name string, action *cloudprovider.DefaultAction) (*SAppGatewayWaf, error) {
mode := cloudprovider.WafActionDetection
if action != nil {
switch action.Action {
case cloudprovider.WafActionDetection, cloudprovider.WafActionPrevention:
mode = action.Action
default:
return nil, errors.Wrapf(cloudprovider.ErrNotSupported, "invalid action %s", action.Action)
}
}
params := map[string]interface{}{
"Type": "Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies",
"Name": name,
"Location": self.Name,
"properties": map[string]interface{}{
"customRules": []string{},
"policySettings": map[string]interface{}{
"fileUploadLimitInMb": 100,
"maxRequestBodySizeInKb": 128,
"mode": mode,
"requestBodyCheck": true,
"state": "Enabled",
},
"managedRules": map[string]interface{}{
"exclusions": []string{},
"managedRuleSets": []map[string]interface{}{
map[string]interface{}{
"ruleSetType": "OWASP",
"ruleSetVersion": "3.1",
"ruleGroupOverrides": []string{},
},
},
},
},
}
ret := &SAppGatewayWaf{region: self}
err := self.create("", jsonutils.Marshal(params), ret)
if err != nil {
return nil, err
}
return ret, nil
}
func (self *SRegion) GetAppGatewayWaf(id string) (*SAppGatewayWaf, error) {
res := &SAppGatewayWaf{region: self}
return res, self.get(id, nil, &res)
}
func (self *SRegion) ListAppWafManagedRuleGroup() ([]SAppWafRuleGroup, error) {
ret := []SAppWafRuleGroup{}
err := self.list("Microsoft.Network/applicationGatewayAvailableWafRuleSets", url.Values{}, &ret)
if err != nil {
return nil, errors.Wrapf(err, "list")
}
return ret, nil
}
func (self *SRegion) GetICloudWafInstances() ([]cloudprovider.ICloudWafInstance, error) {
wafs, err := self.ListAppWafs()
if err != nil {
return nil, errors.Wrapf(err, "ListAppWafs")
}
ret := []cloudprovider.ICloudWafInstance{}
for i := range wafs {
wafs[i].region = self
ret = append(ret, &wafs[i])
}
return ret, nil
}
func (self *SAppGatewayWaf) GetCloudResources() ([]cloudprovider.SCloudResource, error) {
ret := []cloudprovider.SCloudResource{}
for _, ag := range self.Properties.ApplicationGateways {
ret = append(ret, cloudprovider.SCloudResource{
Id: ag.ID,
Type: "app_gateway",
CanDissociate: true,
})
}
for _, lis := range self.Properties.HttpListeners {
ret = append(ret, cloudprovider.SCloudResource{
Id: lis.Id,
Type: "http_listener",
CanDissociate: true,
})
}
return ret, nil
}
+69
View File
@@ -0,0 +1,69 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package azure
import "net/url"
type SFrontDoorProperties struct {
ResourceState string
ProvisioningState string
PolicySettings struct {
EnabledState string
Mode string
RedirectUrl string
CustomBlockResponseStatusCode int
CustomBlockResponseBody string
RequestBodyCheck string
}
CustomRules struct {
Rules []struct{}
}
ManagedRules struct {
ManagedRuleSets []struct {
RuleSetType string
RuleSetVersion string
RuleSetAction string
RuleGroupOverrides []struct {
}
Exclusions []struct{}
}
}
FrontendEndpointLinks []struct{}
RoutingRuleLinks []struct{}
SecurityPolicyLinks []struct{}
}
type SFrontDoorWaf struct {
Id string
Name string
Type string
Tags map[string]string
Location string
Sku struct {
Name string
}
Properties SFrontDoorProperties
}
func (self *SRegion) ListFrontDoorWafs(resGroup string) ([]SFrontDoorWaf, error) {
params := url.Values{}
params.Set("resourceGroups", resGroup)
ret := []SFrontDoorWaf{}
err := self.list("Microsoft.Network/frontdoorWebApplicationFirewallPolicies", params, &ret)
if err != nil {
return nil, err
}
return ret, nil
}
+54
View File
@@ -0,0 +1,54 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package azure
import "net/url"
type SWafRule struct {
RuleId string
Description string
DefaultAction string
DefaultState string
}
type SRuleGroup struct {
ruleGroupName string
description string
Rules []SWafRule
}
type SManagedRuleGroupProperties struct {
ProvisioningState string
RuleSetId string
RuleSetType string
RuleSetVersion string
RuleGroups []SRuleGroup
}
type SManagedRuleGroup struct {
Name string
Id string
Type string
Properties SManagedRuleGroupProperties
}
func (self *SRegion) ListManagedRuleGroups() ([]SManagedRuleGroup, error) {
groups := []SManagedRuleGroup{}
err := self.list("Microsoft.Network/FrontDoorWebApplicationFirewallManagedRuleSets", url.Values{}, &groups)
if err != nil {
return nil, err
}
return groups, nil
}
+32
View File
@@ -174,3 +174,35 @@ func (self *SRegion) CreateICloudAccessGroup(opts *cloudprovider.SAccessGroup) (
func (self *SRegion) CreateICloudFileSystem(opts *cloudprovider.FileSystemCraeteOptions) (cloudprovider.ICloudFileSystem, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateICloudFileSystem")
}
func (self *SRegion) GetICloudApplicationGateways() ([]cloudprovider.ICloudApplicationGateway, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudApplicationGateways")
}
func (self *SRegion) GetICloudApplicationGatewayById(id string) (cloudprovider.ICloudApplicationGateway, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudApplicationGatewayById")
}
func (self *SRegion) GetICloudWafIPSets() ([]cloudprovider.ICloudWafIPSet, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudWafIPSets")
}
func (self *SRegion) GetICloudWafRegexSets() ([]cloudprovider.ICloudWafRegexSet, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudWafRegexSets")
}
func (self *SRegion) GetICloudWafInstances() ([]cloudprovider.ICloudWafInstance, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudWafInstances")
}
func (self *SRegion) GetICloudWafInstanceById(id string) (cloudprovider.ICloudWafInstance, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudWafInstanceById")
}
func (self *SRegion) CreateICloudWafInstance(opts *cloudprovider.WafCreateOptions) (cloudprovider.ICloudWafInstance, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "CreateICloudWafInstance")
}
func (self *SRegion) GetICloudWafRuleGroups() ([]cloudprovider.ICloudWafRuleGroup, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "GetICloudWafRuleGroups")
}
+44 -14
View File
@@ -578,6 +578,44 @@ func (rm *SReceiverManager) filterByOwner(q *sqlchemy.SQuery, owner mcclient.IId
return q
}
func (rm *SReceiverManager) filterByOwnerAndProjectDomain(ctx context.Context, userCred mcclient.TokenCredential, q *sqlchemy.SQuery, scope rbacutils.TRbacScope) (*sqlchemy.SQuery, error) {
if userCred == nil {
return q, nil
}
userIds, err := rm.findUserIdsWithProjectDomain(ctx, userCred, userCred.GetProjectDomainId())
if err != nil {
return nil, errors.Wrap(err, "unable to findUserIdsWithProjectDomain")
}
var projectDomainCondition, ownerCondition sqlchemy.ICondition
switch len(userIds) {
case 0:
projectDomainCondition = nil
case 1:
projectDomainCondition = sqlchemy.Equals(q.Field("id"), userIds[0])
default:
projectDomainCondition = sqlchemy.In(q.Field("id"), userIds)
}
switch scope {
case rbacutils.ScopeDomain:
ownerCondition = sqlchemy.Equals(q.Field("domain_id"), userCred.GetProjectDomainId())
case rbacutils.ScopeProject:
ownerCondition = sqlchemy.Equals(q.Field("id"), userCred.GetUserId())
}
if projectDomainCondition != nil && ownerCondition != nil {
return q.Filter(sqlchemy.OR(projectDomainCondition, ownerCondition)), nil
}
if projectDomainCondition != nil {
return q.Filter(projectDomainCondition), nil
}
if ownerCondition != nil {
return q.Filter(ownerCondition), nil
}
return q, nil
}
func (rm *SReceiverManager) FilterByOwner(q *sqlchemy.SQuery, owner mcclient.IIdentityProvider, scope rbacutils.TRbacScope) *sqlchemy.SQuery {
return q
}
@@ -607,24 +645,16 @@ func (rm *SReceiverManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQue
if len(input.VerifiedContactType) > 0 {
q = rm.VerifiedContactFilter(input.VerifiedContactType, q)
}
ownerId, queryScope, err := db.FetchCheckQueryOwnerScope(ctx, userCred, jsonutils.Marshal(input), rm, policy.PolicyActionList, true)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
if input.ProjectDomainFilter && userCred.GetProjectDomainId() != "" {
userIds, err := rm.findUserIdsWithProjectDomain(ctx, userCred, userCred.GetProjectDomainId())
q, err = rm.filterByOwnerAndProjectDomain(ctx, userCred, q, queryScope)
if err != nil {
return nil, errors.Wrap(err, "unable to findUserIdsWithProjectDomain")
}
switch len(userIds) {
case 0:
q = q.Equals("id", "")
case 1:
q = q.Equals("id", userIds[0])
default:
q = q.In("id", userIds)
return nil, errors.Wrap(err, "unable to filterByOwnerAndProjectDomain")
}
} else {
ownerId, queryScope, err := db.FetchCheckQueryOwnerScope(ctx, userCred, jsonutils.Marshal(input), rm, policy.PolicyActionList, true)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
q = rm.filterByOwner(q, ownerId, queryScope)
}
return q, nil

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