mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
feat(region): waf
This commit is contained in:
@@ -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{})
|
||||
}
|
||||
@@ -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{})
|
||||
}
|
||||
@@ -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{})
|
||||
}
|
||||
@@ -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{})
|
||||
}
|
||||
@@ -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=
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 (
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -165,6 +170,13 @@ type ICloudRegion interface {
|
||||
|
||||
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 {
|
||||
@@ -1289,3 +1301,58 @@ type ICloudApplicationGateway interface {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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{}
|
||||
})
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -1101,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 {
|
||||
@@ -1278,6 +1363,12 @@ func syncPublicCloudProviderInfo(
|
||||
|
||||
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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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", "")
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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", "")
|
||||
}
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -59,6 +59,11 @@ var (
|
||||
"proxysettings",
|
||||
"project_mappings",
|
||||
"app_gateways",
|
||||
"waf_instances",
|
||||
"waf_rules",
|
||||
"waf_rule_groups",
|
||||
"waf_ipsets",
|
||||
"waf_regexsets",
|
||||
}
|
||||
computeUserResources = []string{
|
||||
"keypairs",
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -93,6 +93,8 @@ func InitHandlers(app *appsrv.Application) {
|
||||
models.ScheduledTaskLabelManager,
|
||||
models.DnsRecordSetTrafficPolicyManager,
|
||||
models.CloudimageManager,
|
||||
|
||||
models.WafRuleStatementManager,
|
||||
} {
|
||||
db.RegisterModelManager(manager)
|
||||
}
|
||||
@@ -216,6 +218,14 @@ func InitHandlers(app *appsrv.Application) {
|
||||
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)
|
||||
|
||||
@@ -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,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(¶ms)
|
||||
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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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,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)
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
})
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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,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
|
||||
})
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -182,3 +182,27 @@ func (self *SRegion) GetICloudApplicationGateways() ([]cloudprovider.ICloudAppli
|
||||
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")
|
||||
}
|
||||
|
||||
+15985
File diff suppressed because it is too large
Load Diff
+88
@@ -0,0 +1,88 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
// Package wafv2 provides the client and types for making API
|
||||
// requests to AWS WAFV2.
|
||||
//
|
||||
//
|
||||
// This is the latest version of the AWS WAF API, released in November, 2019.
|
||||
// The names of the entities that you use to access this API, like endpoints
|
||||
// and namespaces, all have the versioning information added, like "V2" or "v2",
|
||||
// to distinguish from the prior version. We recommend migrating your resources
|
||||
// to this version, because it has a number of significant improvements.
|
||||
//
|
||||
// If you used AWS WAF prior to this release, you can't use this AWS WAFV2 API
|
||||
// to access any AWS WAF resources that you created before. You can access your
|
||||
// old rules, web ACLs, and other AWS WAF resources only through the AWS WAF
|
||||
// Classic APIs. The AWS WAF Classic APIs have retained the prior names, endpoints,
|
||||
// and namespaces.
|
||||
//
|
||||
// For information, including how to migrate your AWS WAF resources to this
|
||||
// version, see the AWS WAF Developer Guide (https://docs.aws.amazon.com/waf/latest/developerguide/waf-chapter.html).
|
||||
//
|
||||
// AWS WAF is a web application firewall that lets you monitor the HTTP and
|
||||
// HTTPS requests that are forwarded to Amazon CloudFront, an Amazon API Gateway
|
||||
// REST API, an Application Load Balancer, or an AWS AppSync GraphQL API. AWS
|
||||
// WAF also lets you control access to your content. Based on conditions that
|
||||
// you specify, such as the IP addresses that requests originate from or the
|
||||
// values of query strings, the API Gateway REST API, CloudFront distribution,
|
||||
// the Application Load Balancer, or the AWS AppSync GraphQL API responds to
|
||||
// requests either with the requested content or with an HTTP 403 status code
|
||||
// (Forbidden). You also can configure CloudFront to return a custom error page
|
||||
// when a request is blocked.
|
||||
//
|
||||
// This API guide is for developers who need detailed information about AWS
|
||||
// WAF API actions, data types, and errors. For detailed information about AWS
|
||||
// WAF features and an overview of how to use AWS WAF, see the AWS WAF Developer
|
||||
// Guide (https://docs.aws.amazon.com/waf/latest/developerguide/).
|
||||
//
|
||||
// You can make calls using the endpoints listed in AWS Service Endpoints for
|
||||
// AWS WAF (https://docs.aws.amazon.com/general/latest/gr/rande.html#waf_region).
|
||||
//
|
||||
// * For regional applications, you can use any of the endpoints in the list.
|
||||
// A regional application can be an Application Load Balancer (ALB), an API
|
||||
// Gateway REST API, or an AppSync GraphQL API.
|
||||
//
|
||||
// * For AWS CloudFront applications, you must use the API endpoint listed
|
||||
// for US East (N. Virginia): us-east-1.
|
||||
//
|
||||
// Alternatively, you can use one of the AWS SDKs to access an API that's tailored
|
||||
// to the programming language or platform that you're using. For more information,
|
||||
// see AWS SDKs (http://aws.amazon.com/tools/#SDKs).
|
||||
//
|
||||
// We currently provide two versions of the AWS WAF API: this API and the prior
|
||||
// versions, the classic AWS WAF APIs. This new API provides the same functionality
|
||||
// as the older versions, with the following major improvements:
|
||||
//
|
||||
// * You use one API for both global and regional applications. Where you
|
||||
// need to distinguish the scope, you specify a Scope parameter and set it
|
||||
// to CLOUDFRONT or REGIONAL.
|
||||
//
|
||||
// * You can define a Web ACL or rule group with a single call, and update
|
||||
// it with a single call. You define all rule specifications in JSON format,
|
||||
// and pass them to your rule group or Web ACL calls.
|
||||
//
|
||||
// * The limits AWS WAF places on the use of rules more closely reflects
|
||||
// the cost of running each type of rule. Rule groups include capacity settings,
|
||||
// so you know the maximum cost of a rule group when you use it.
|
||||
//
|
||||
// See https://docs.aws.amazon.com/goto/WebAPI/wafv2-2019-07-29 for more information on this service.
|
||||
//
|
||||
// See wafv2 package documentation for more information.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/wafv2/
|
||||
//
|
||||
// Using the Client
|
||||
//
|
||||
// To contact AWS WAFV2 with the SDK use the New function to create
|
||||
// a new service client. With that client you can make API requests to the service.
|
||||
// These clients are safe to use concurrently.
|
||||
//
|
||||
// See the SDK's documentation for more information on how to use the SDK.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/
|
||||
//
|
||||
// See aws.Config documentation for more information on configuring SDK clients.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
|
||||
//
|
||||
// See the AWS WAFV2 client WAFV2 for more
|
||||
// information on creating client for this service.
|
||||
// https://docs.aws.amazon.com/sdk-for-go/api/service/wafv2/#New
|
||||
package wafv2
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package wafv2
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
// ErrCodeWAFAssociatedItemException for service response error code
|
||||
// "WAFAssociatedItemException".
|
||||
//
|
||||
// AWS WAF couldn’t perform the operation because your resource is being used
|
||||
// by another resource or it’s associated with another resource.
|
||||
ErrCodeWAFAssociatedItemException = "WAFAssociatedItemException"
|
||||
|
||||
// ErrCodeWAFDuplicateItemException for service response error code
|
||||
// "WAFDuplicateItemException".
|
||||
//
|
||||
// AWS WAF couldn’t perform the operation because the resource that you tried
|
||||
// to save is a duplicate of an existing one.
|
||||
ErrCodeWAFDuplicateItemException = "WAFDuplicateItemException"
|
||||
|
||||
// ErrCodeWAFInternalErrorException for service response error code
|
||||
// "WAFInternalErrorException".
|
||||
//
|
||||
// Your request is valid, but AWS WAF couldn’t perform the operation because
|
||||
// of a system problem. Retry your request.
|
||||
ErrCodeWAFInternalErrorException = "WAFInternalErrorException"
|
||||
|
||||
// ErrCodeWAFInvalidOperationException for service response error code
|
||||
// "WAFInvalidOperationException".
|
||||
//
|
||||
// The operation isn't valid.
|
||||
ErrCodeWAFInvalidOperationException = "WAFInvalidOperationException"
|
||||
|
||||
// ErrCodeWAFInvalidParameterException for service response error code
|
||||
// "WAFInvalidParameterException".
|
||||
//
|
||||
// The operation failed because AWS WAF didn't recognize a parameter in the
|
||||
// request. For example:
|
||||
//
|
||||
// * You specified an invalid parameter name or value.
|
||||
//
|
||||
// * Your nested statement isn't valid. You might have tried to nest a statement
|
||||
// that can’t be nested.
|
||||
//
|
||||
// * You tried to update a WebACL with a DefaultAction that isn't among the
|
||||
// types available at DefaultAction.
|
||||
//
|
||||
// * Your request references an ARN that is malformed, or corresponds to
|
||||
// a resource with which a Web ACL cannot be associated.
|
||||
ErrCodeWAFInvalidParameterException = "WAFInvalidParameterException"
|
||||
|
||||
// ErrCodeWAFInvalidPermissionPolicyException for service response error code
|
||||
// "WAFInvalidPermissionPolicyException".
|
||||
//
|
||||
// The operation failed because the specified policy isn't in the proper format.
|
||||
//
|
||||
// The policy specifications must conform to the following:
|
||||
//
|
||||
// * The policy must be composed using IAM Policy version 2012-10-17 or version
|
||||
// 2015-01-01.
|
||||
//
|
||||
// * The policy must include specifications for Effect, Action, and Principal.
|
||||
//
|
||||
// * Effect must specify Allow.
|
||||
//
|
||||
// * Action must specify wafv2:CreateWebACL, wafv2:UpdateWebACL, and wafv2:PutFirewallManagerRuleGroups.
|
||||
// AWS WAF rejects any extra actions or wildcard actions in the policy.
|
||||
//
|
||||
// * The policy must not include a Resource parameter.
|
||||
//
|
||||
// For more information, see IAM Policies (https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html).
|
||||
ErrCodeWAFInvalidPermissionPolicyException = "WAFInvalidPermissionPolicyException"
|
||||
|
||||
// ErrCodeWAFInvalidResourceException for service response error code
|
||||
// "WAFInvalidResourceException".
|
||||
//
|
||||
// AWS WAF couldn’t perform the operation because the resource that you requested
|
||||
// isn’t valid. Check the resource, and try again.
|
||||
ErrCodeWAFInvalidResourceException = "WAFInvalidResourceException"
|
||||
|
||||
// ErrCodeWAFLimitsExceededException for service response error code
|
||||
// "WAFLimitsExceededException".
|
||||
//
|
||||
// AWS WAF couldn’t perform the operation because you exceeded your resource
|
||||
// limit. For example, the maximum number of WebACL objects that you can create
|
||||
// for an AWS account. For more information, see Limits (https://docs.aws.amazon.com/waf/latest/developerguide/limits.html)
|
||||
// in the AWS WAF Developer Guide.
|
||||
ErrCodeWAFLimitsExceededException = "WAFLimitsExceededException"
|
||||
|
||||
// ErrCodeWAFNonexistentItemException for service response error code
|
||||
// "WAFNonexistentItemException".
|
||||
//
|
||||
// AWS WAF couldn’t perform the operation because your resource doesn’t
|
||||
// exist.
|
||||
ErrCodeWAFNonexistentItemException = "WAFNonexistentItemException"
|
||||
|
||||
// ErrCodeWAFOptimisticLockException for service response error code
|
||||
// "WAFOptimisticLockException".
|
||||
//
|
||||
// AWS WAF couldn’t save your changes because you tried to update or delete
|
||||
// a resource that has changed since you last retrieved it. Get the resource
|
||||
// again, make any changes you need to make to the new copy, and retry your
|
||||
// operation.
|
||||
ErrCodeWAFOptimisticLockException = "WAFOptimisticLockException"
|
||||
|
||||
// ErrCodeWAFServiceLinkedRoleErrorException for service response error code
|
||||
// "WAFServiceLinkedRoleErrorException".
|
||||
//
|
||||
// AWS WAF is not able to access the service linked role. This can be caused
|
||||
// by a previous PutLoggingConfiguration request, which can lock the service
|
||||
// linked role for about 20 seconds. Please try your request again. The service
|
||||
// linked role can also be locked by a previous DeleteServiceLinkedRole request,
|
||||
// which can lock the role for 15 minutes or more. If you recently made a call
|
||||
// to DeleteServiceLinkedRole, wait at least 15 minutes and try the request
|
||||
// again. If you receive this same exception again, you will have to wait additional
|
||||
// time until the role is unlocked.
|
||||
ErrCodeWAFServiceLinkedRoleErrorException = "WAFServiceLinkedRoleErrorException"
|
||||
|
||||
// ErrCodeWAFSubscriptionNotFoundException for service response error code
|
||||
// "WAFSubscriptionNotFoundException".
|
||||
ErrCodeWAFSubscriptionNotFoundException = "WAFSubscriptionNotFoundException"
|
||||
|
||||
// ErrCodeWAFTagOperationException for service response error code
|
||||
// "WAFTagOperationException".
|
||||
//
|
||||
// An error occurred during the tagging operation. Retry your request.
|
||||
ErrCodeWAFTagOperationException = "WAFTagOperationException"
|
||||
|
||||
// ErrCodeWAFTagOperationInternalErrorException for service response error code
|
||||
// "WAFTagOperationInternalErrorException".
|
||||
//
|
||||
// AWS WAF couldn’t perform your tagging operation because of an internal
|
||||
// error. Retry your request.
|
||||
ErrCodeWAFTagOperationInternalErrorException = "WAFTagOperationInternalErrorException"
|
||||
|
||||
// ErrCodeWAFUnavailableEntityException for service response error code
|
||||
// "WAFUnavailableEntityException".
|
||||
//
|
||||
// AWS WAF couldn’t retrieve the resource that you requested. Retry your request.
|
||||
ErrCodeWAFUnavailableEntityException = "WAFUnavailableEntityException"
|
||||
)
|
||||
|
||||
var exceptionFromCode = map[string]func(protocol.ResponseMetadata) error{
|
||||
"WAFAssociatedItemException": newErrorWAFAssociatedItemException,
|
||||
"WAFDuplicateItemException": newErrorWAFDuplicateItemException,
|
||||
"WAFInternalErrorException": newErrorWAFInternalErrorException,
|
||||
"WAFInvalidOperationException": newErrorWAFInvalidOperationException,
|
||||
"WAFInvalidParameterException": newErrorWAFInvalidParameterException,
|
||||
"WAFInvalidPermissionPolicyException": newErrorWAFInvalidPermissionPolicyException,
|
||||
"WAFInvalidResourceException": newErrorWAFInvalidResourceException,
|
||||
"WAFLimitsExceededException": newErrorWAFLimitsExceededException,
|
||||
"WAFNonexistentItemException": newErrorWAFNonexistentItemException,
|
||||
"WAFOptimisticLockException": newErrorWAFOptimisticLockException,
|
||||
"WAFServiceLinkedRoleErrorException": newErrorWAFServiceLinkedRoleErrorException,
|
||||
"WAFSubscriptionNotFoundException": newErrorWAFSubscriptionNotFoundException,
|
||||
"WAFTagOperationException": newErrorWAFTagOperationException,
|
||||
"WAFTagOperationInternalErrorException": newErrorWAFTagOperationInternalErrorException,
|
||||
"WAFUnavailableEntityException": newErrorWAFUnavailableEntityException,
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
|
||||
|
||||
package wafv2
|
||||
|
||||
import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/client"
|
||||
"github.com/aws/aws-sdk-go/aws/client/metadata"
|
||||
"github.com/aws/aws-sdk-go/aws/request"
|
||||
"github.com/aws/aws-sdk-go/aws/signer/v4"
|
||||
"github.com/aws/aws-sdk-go/private/protocol"
|
||||
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
|
||||
)
|
||||
|
||||
// WAFV2 provides the API operation methods for making requests to
|
||||
// AWS WAFV2. See this package's package overview docs
|
||||
// for details on the service.
|
||||
//
|
||||
// WAFV2 methods are safe to use concurrently. It is not safe to
|
||||
// modify mutate any of the struct's properties though.
|
||||
type WAFV2 struct {
|
||||
*client.Client
|
||||
}
|
||||
|
||||
// Used for custom client initialization logic
|
||||
var initClient func(*client.Client)
|
||||
|
||||
// Used for custom request initialization logic
|
||||
var initRequest func(*request.Request)
|
||||
|
||||
// Service information constants
|
||||
const (
|
||||
ServiceName = "WAFV2" // Name of service.
|
||||
EndpointsID = "wafv2" // ID to lookup a service endpoint with.
|
||||
ServiceID = "WAFV2" // ServiceID is a unique identifier of a specific service.
|
||||
)
|
||||
|
||||
// New creates a new instance of the WAFV2 client with a session.
|
||||
// If additional configuration is needed for the client instance use the optional
|
||||
// aws.Config parameter to add your extra config.
|
||||
//
|
||||
// Example:
|
||||
// mySession := session.Must(session.NewSession())
|
||||
//
|
||||
// // Create a WAFV2 client from just a session.
|
||||
// svc := wafv2.New(mySession)
|
||||
//
|
||||
// // Create a WAFV2 client with additional configuration
|
||||
// svc := wafv2.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
|
||||
func New(p client.ConfigProvider, cfgs ...*aws.Config) *WAFV2 {
|
||||
c := p.ClientConfig(EndpointsID, cfgs...)
|
||||
return newClient(*c.Config, c.Handlers, c.PartitionID, c.Endpoint, c.SigningRegion, c.SigningName)
|
||||
}
|
||||
|
||||
// newClient creates, initializes and returns a new service client instance.
|
||||
func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint, signingRegion, signingName string) *WAFV2 {
|
||||
svc := &WAFV2{
|
||||
Client: client.New(
|
||||
cfg,
|
||||
metadata.ClientInfo{
|
||||
ServiceName: ServiceName,
|
||||
ServiceID: ServiceID,
|
||||
SigningName: signingName,
|
||||
SigningRegion: signingRegion,
|
||||
PartitionID: partitionID,
|
||||
Endpoint: endpoint,
|
||||
APIVersion: "2019-07-29",
|
||||
JSONVersion: "1.1",
|
||||
TargetPrefix: "AWSWAF_20190729",
|
||||
},
|
||||
handlers,
|
||||
),
|
||||
}
|
||||
|
||||
// Handlers
|
||||
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
|
||||
svc.Handlers.Build.PushBackNamed(jsonrpc.BuildHandler)
|
||||
svc.Handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler)
|
||||
svc.Handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler)
|
||||
svc.Handlers.UnmarshalError.PushBackNamed(
|
||||
protocol.NewUnmarshalErrorHandler(jsonrpc.NewUnmarshalTypedError(exceptionFromCode)).NamedHandler(),
|
||||
)
|
||||
|
||||
// Run custom client initialization if present
|
||||
if initClient != nil {
|
||||
initClient(svc.Client)
|
||||
}
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
// newRequest creates a new request for a WAFV2 operation and runs any
|
||||
// custom request initialization.
|
||||
func (c *WAFV2) newRequest(op *request.Operation, params, data interface{}) *request.Request {
|
||||
req := c.NewRequest(op, params, data)
|
||||
|
||||
// Run custom request initialization if present
|
||||
if initRequest != nil {
|
||||
initRequest(req)
|
||||
}
|
||||
|
||||
return req
|
||||
}
|
||||
Vendored
+1
@@ -183,6 +183,7 @@ github.com/aws/aws-sdk-go/service/route53
|
||||
github.com/aws/aws-sdk-go/service/s3
|
||||
github.com/aws/aws-sdk-go/service/sts
|
||||
github.com/aws/aws-sdk-go/service/sts/stsiface
|
||||
github.com/aws/aws-sdk-go/service/wafv2
|
||||
# github.com/beevik/etree v1.1.0
|
||||
github.com/beevik/etree
|
||||
# github.com/benbjohnson/clock v1.0.0
|
||||
|
||||
Reference in New Issue
Block a user