feat(region): waf

This commit is contained in:
Qu Xuan
2021-04-23 15:46:52 +08:00
parent 257fc28196
commit f3dbe33671
84 changed files with 24597 additions and 12 deletions
+33
View File
@@ -0,0 +1,33 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.WafInstances).WithKeyword("waf").WithContextManager(&modules.Cloudregions)
cmd.List(&compute.WafInstanceListOptions{})
cmd.Delete(&options.BaseIdOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Update(&options.BaseUpdateOptions{})
cmd.Get("cloud-resources", &options.BaseIdOptions{})
cmd.Perform("syncstatus", &options.BaseIdOptions{})
cmd.Create(&compute.WafInstanceCreateOptions{})
}
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.WafIPSetCaches)
cmd.List(&compute.WafIPSetCacheListOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Delete(&options.BaseIdOptions{})
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.WafIPSets)
cmd.List(&compute.WafIPSetListOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Delete(&options.BaseIdOptions{})
}
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.WafRegexSetCaches)
cmd.List(&compute.WafRegexSetCacheListOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Delete(&options.BaseIdOptions{})
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.WafRegexSets)
cmd.List(&compute.WafRegexSetListOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Delete(&options.BaseIdOptions{})
}
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.WafRuleGroups)
cmd.List(&compute.WafRuleGroupListOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Delete(&options.BaseIdOptions{})
}
+32
View File
@@ -0,0 +1,32 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/options"
"yunion.io/x/onecloud/pkg/mcclient/options/compute"
)
func init() {
cmd := shell.NewResourceCmd(&modules.WafRules)
cmd.List(&compute.WafRuleListOptions{})
cmd.Create(&compute.WafRuleOptions{})
cmd.Update(&compute.WafRuleUpdateOptions{})
cmd.Show(&options.BaseIdOptions{})
cmd.Delete(&options.BaseIdOptions{})
cmd.Perform("syncstatus", &options.BaseIdOptions{})
}
-11
View File
@@ -2,14 +2,12 @@ bazil.org/fuse v0.0.0-20180421153158-65cc252bf669 h1:FNCRpXiquG1aoyqcIWVFmpTSKVc
bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0 h1:0E3eE8MX426vUOs7aHfI7aN1BrIzzzf4ccKCSfSjGmc=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.51.0 h1:PvKAVQWCtlGUSlZkGW3QLelKaWq7KYv/MW1EboG8bfM=
cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw=
@@ -32,16 +30,12 @@ github.com/Azure/azure-sdk-for-go v36.1.0+incompatible h1:smHlbChr/JDmsyUqELZXLs
github.com/Azure/azure-sdk-for-go v36.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.9.0 h1:MRvx8gncNaXJqOoLmhNjUAKh33JJF8LyxPhomEtOsjs=
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest v0.9.3 h1:OZEIaBbMdUE/Js+BQKlpO81XlISgipr6yDJ+PSwsgi4=
github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0=
github.com/Azure/go-autorest/autorest v0.9.6 h1:5YWtOnckcudzIw8lPPBcWOnmIFWMtHci1ZWAZulMSx0=
github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630=
github.com/Azure/go-autorest/autorest/adal v0.5.0 h1:q2gDruN08/guU9vAjuPWff0+QIrpH6ediguzdAzXAUU=
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc=
github.com/Azure/go-autorest/autorest/adal v0.8.1 h1:pZdL8o72rK+avFWl+p9nE8RWi1JInZrWJYlnpfXJwHk=
github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
github.com/Azure/go-autorest/autorest/adal v0.8.2 h1:O1X4oexUxnZCaEUGsvMnr8ZGj8HI37tNezwY4npRqA0=
github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q=
@@ -49,12 +43,10 @@ github.com/Azure/go-autorest/autorest/azure/auth v0.4.2 h1:iM6UAvjR97ZIeR93qTcwp
github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM=
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1 h1:LXl088ZQlP0SBppGFsRZonW6hSvwgL5gRByMbvUbx8U=
github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw=
github.com/Azure/go-autorest/autorest/date v0.1.0 h1:YGrhWfrgtFs84+h0o46rJrlmsZtyZRg470CqAXTZaGM=
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/date v0.2.0 h1:yW+Zlqf26583pE43KhfnhFcdmSWlm5Ew6bxipnr/tbM=
github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g=
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0 h1:Ww5g4zThfD/6cLb4z6xxgeyDa7QDkizMkJKe0ysZXp0=
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.3.0 h1:qJumjCaCudz+OcqE9/XtEPfvtOjOmKaui4EOpFI6zZc=
github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM=
@@ -703,10 +695,8 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
@@ -752,7 +742,6 @@ golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8=
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+84
View File
@@ -0,0 +1,84 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
const (
WAF_ACTION_ALLOW = "Allow"
WAF_ACTION_BLOCK = "Block"
WAF_ACTION_PREVENTION = "Prevention"
WAF_ACTION_DETECTION = "Detection"
WAF_STATUS_AVAILABLE = "available"
WAF_STATUS_DELETING = "deleting"
WAF_STATUS_DELETE_FAILED = "delete_failed"
WAF_STATUS_CREATING = "creating"
WAF_STATUS_CREATE_FAILED = "create_failed"
WAF_STATUS_UPDATING = "updating"
WAF_STATUS_UNKNOWN = "unknown"
)
type WafInstanceCreateInput struct {
apis.EnabledStatusInfrasResourceBaseCreateInput
// 阿里云CNAME介入回源地址,支持IP和域名,域名仅支持输入一个
// 此参数和cloud_resources两者必须指定某一个
SourceIps cloudprovider.WafSourceIps `json:"source_ips"`
// 关联云资源列表
// 阿里云要求输入此参数或source_ips
CloudResources []cloudprovider.SCloudResource
CloudregionResourceInput
CloudproviderResourceInput
Type cloudprovider.TWafType
DefaultAction *cloudprovider.DefaultAction
}
type WafInstanceDetails struct {
apis.EnabledStatusInfrasResourceBaseDetails
ManagedResourceInfo
CloudregionResourceInfo
Rules []SWafRule
}
type SWafRule struct {
Id string
Name string
Priority int
Action *cloudprovider.DefaultAction
}
type WafInstanceListInput struct {
apis.EnabledStatusInfrasResourceBaseListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
RegionalFilterListInput
}
type WafSyncstatusInput struct {
}
type WafDeleteRuleInput struct {
WafRuleId string
}
+45
View File
@@ -0,0 +1,45 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import "yunion.io/x/onecloud/pkg/apis"
const (
WAF_IPSET_STATUS_AVAILABLE = "available"
WAF_IPSET_STATUS_DELETING = "deleting"
WAF_IPSET_STATUS_DELETE_FAILED = "delete_failed"
)
type WafIPSetDetails struct {
apis.StatusInfrasResourceBaseDetails
}
type WafIPSetListInput struct {
apis.StatusInfrasResourceBaseListInput
}
type WafIPSetCacheDetails struct {
apis.StatusStandaloneResourceDetails
ManagedResourceInfo
CloudregionResourceInfo
}
type WafIPSetCacheListInput struct {
apis.StatusStandaloneResourceListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
RegionalFilterListInput
}
+45
View File
@@ -0,0 +1,45 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import "yunion.io/x/onecloud/pkg/apis"
const (
WAF_REGEX_SET_STATUS_AVAILABLE = "available"
WAF_REGEX_SET_STATUS_DELETING = "deleting"
WAF_REGEX_SET_STATUS_DELETE_FAILED = "delete_failed"
)
type WafRegexSetDetails struct {
apis.StatusInfrasResourceBaseDetails
}
type WafRegexSetListInput struct {
apis.StatusInfrasResourceBaseListInput
}
type WafRegexSetCacheDetails struct {
apis.StatusStandaloneResourceDetails
ManagedResourceInfo
CloudregionResourceInfo
}
type WafRegexSetCacheListInput struct {
apis.StatusStandaloneResourceListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
RegionalFilterListInput
}
+50
View File
@@ -0,0 +1,50 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import "yunion.io/x/onecloud/pkg/apis"
const (
WAF_RULE_GROUP_STATUS_AVAILABLE = "available"
WAF_RULE_GROUP_STATUS_DELETING = "deleting"
)
type WafRuleGroupDetails struct {
apis.StatusInfrasResourceBaseDetails
}
type WafRuleGroupListInput struct {
apis.StatusInfrasResourceBaseListInput
// 是否是系统RuleGroup
IsSystem *bool `json:"is_system"`
// 云平台
Provider string `json:"provider"`
// 云环境
CloudEnv string `json:"cloud_env"`
}
type WafRuleGroupCacheDetails struct {
apis.StatusStandaloneResourceDetails
ManagedResourceInfo
CloudregionResourceInfo
}
type WafRuleGroupCacheListInput struct {
apis.StatusStandaloneResourceListInput
apis.ExternalizedResourceBaseListInput
ManagedResourceListInput
RegionalFilterListInput
}
+76
View File
@@ -0,0 +1,76 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/onecloud/pkg/apis"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
const (
WAF_RULE_STATUS_AVAILABLE = "available"
WAF_RULE_STATUS_DELETING = "deleting"
WAF_RULE_STATUS_CREATING = "creating"
WAF_RULE_STATUS_CREATE_FAILED = "create_failed"
WAF_RULE_STATUS_DELETE_FAILED = "delete_failed"
WAF_RULE_STATUS_UPDATING = "updating"
WAF_RULE_STATUS_UPDATE_FAILED = "update_failed"
WAF_RULE_STATUS_UNKNOWN = "unknown"
)
type WafRuleListInput struct {
apis.StatusStandaloneResourceListInput
apis.ExternalizedResourceBaseListInput
// WAF实例Id
WafInstanceId string `json:"waf_instance_id"`
// WAF规则组Id
WafRuleGroupId string `json:"waf_rule_group_id"`
}
type WafRuleCreateInput struct {
apis.StatusStandaloneResourceCreateInput
// WAF实例Id
WafInstanceId string `json:"waf_instance_id"`
// 优先级,不可重复
// Azure优先级范围1-100
Priority int `json:"priority"`
// 匹配后默认行为
Action *cloudprovider.DefaultAction `json:"action"`
// enmu: and, or, not
StatementCondition string `json:"statement_condition"`
// swagger: ignore
// WAF规则组Id
WafRuleGroupId string `json:"waf_rule_group_id"`
// 条件表达式
Statements []cloudprovider.SWafStatement
}
type WafRuleDetails struct {
apis.StatusStandaloneResourceDetails
Statements []cloudprovider.SWafStatement
}
type WafRuleUpdateInput struct {
apis.StatusStandaloneResourceBaseUpdateInput
// 条件表达式
Statements []cloudprovider.SWafStatement
}
+1
View File
@@ -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 (
+67
View File
@@ -44,6 +44,11 @@ type ICloudResource interface {
SetTags(tags map[string]string, replace bool) error
}
type ICloudEnabledResource interface {
ICloudResource
GetEnabled() bool
}
type IVirtualResource interface {
ICloudResource
@@ -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
}
+292
View File
@@ -0,0 +1,292 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cloudprovider
import (
"fmt"
"reflect"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/gotypes"
)
type TWafStatementType string
type TWafStatementCondition string
type TWafAction string
type TWafMatchField string
type TWafType string
type TWafOperator string
type TWafTextTransformation string
var (
WafTypeCloudFront = TWafType("CloudFront")
WafTypeRegional = TWafType("Regional")
WafTypeDefault = TWafType("Default")
WafTypeAppGateway = TWafType("AppGateway")
WafStatementTypeByteMatch = TWafStatementType("ByteMatch")
WafStatementTypeGeoMatch = TWafStatementType("GeoMatch")
WafStatementTypeIPSet = TWafStatementType("IPSet")
WafStatementTypeLabelMatch = TWafStatementType("LabelMatch")
WafStatementTypeManagedRuleGroup = TWafStatementType("ManagedRuleGroup")
WafStatementTypeRate = TWafStatementType("Rate")
WafStatementTypeRegexSet = TWafStatementType("RegexSet")
WafStatementTypeRuleGroup = TWafStatementType("RuleGroup")
WafStatementTypeSize = TWafStatementType("Size")
WafStatementTypeSqliMatch = TWafStatementType("SqliMatch")
WafStatementTypeXssMatch = TWafStatementType("XssMatch")
WafStatementConditionAnd = TWafStatementCondition("And")
WafStatementConditionOr = TWafStatementCondition("Or")
WafStatementConditionNot = TWafStatementCondition("Not")
WafStatementConditionNone = TWafStatementCondition("")
WafActionAllow = TWafAction("Allow")
WafActionBlock = TWafAction("Block")
WafActionLog = TWafAction("Log")
WafActionCount = TWafAction("Count")
WafActionAlert = TWafAction("Alert")
WafActionDetection = TWafAction("Detection")
WafActionPrevention = TWafAction("Prevention")
WafActionNone = TWafAction("")
WafMatchFieldBody = TWafMatchField("Body")
WafMatchFieldJsonBody = TWafMatchField("JsonBody")
WafMatchFieldQuery = TWafMatchField("Query")
WafMatchFieldMethod = TWafMatchField("Method")
WafMatchFiledHeader = TWafMatchField("Header")
WafMatchFiledUriPath = TWafMatchField("UriPath")
WafMatchFiledPostArgs = TWafMatchField("PostArgs")
WafMatchFiledCookie = TWafMatchField("Cookie")
// size
WafOperatorEQ = TWafOperator("EQ")
WafOperatorNE = TWafOperator("NE")
WafOperatorLE = TWafOperator("LE")
WafOperatorLT = TWafOperator("LT")
WafOperatorGE = TWafOperator("GE")
WafOperatorGT = TWafOperator("GT")
// string
WafOperatorExactly = TWafOperator("Exactly")
WafOperatorStartsWith = TWafOperator("StartsWith")
WafOperatorEndsWith = TWafOperator("EndsWith")
WafOperatorContains = TWafOperator("Contains")
WafOperatorContainsWord = TWafOperator("ContainsWord")
WafOperatorRegex = TWafOperator("Regex")
WafTextTransformationNone = TWafTextTransformation("")
WafTextTransformationCompressWithSpace = TWafTextTransformation("CompressWithSpace")
WafTextTransformationHtmlEntityDecode = TWafTextTransformation("HtmlEntityDecode")
WafTextTransformationLowercase = TWafTextTransformation("Lowercase")
WafTextTransformationCmdLine = TWafTextTransformation("CmdLine")
WafTextTransformationUrlDecode = TWafTextTransformation("UrlDecode")
// azure
WafTextTransformationTrim = TWafTextTransformation("Trim")
WafTextTransformationUrlEncode = TWafTextTransformation("UrlEncode")
WafTextTransformationRemoveNulls = TWafTextTransformation("RemoveNulls")
)
type TWafMatchFieldValues []string
func (self TWafMatchFieldValues) IsZero() bool {
return len(self) == 0
}
func (self TWafMatchFieldValues) String() string {
return jsonutils.Marshal(self).String()
}
type TextTransformations []TWafTextTransformation
func (self TextTransformations) IsZero() bool {
return len(self) == 0
}
func (self TextTransformations) String() string {
return jsonutils.Marshal(self).String()
}
type SExcludeRule struct {
Name string
}
type SExcludeRules []SExcludeRule
func (self SExcludeRules) IsZero() bool {
return len(self) == 0
}
func (self SExcludeRules) String() string {
return jsonutils.Marshal(self).String()
}
type SWafRule struct {
Name string
Desc string
Action *DefaultAction
StatementCondition TWafStatementCondition
Priority int
Statements []SWafStatement
}
type SWafStatement struct {
// 管理规则组名称
ManagedRuleGroupName string `width:"64" charset:"utf8" nullable:"false" list:"user"`
// 不包含的规则列表
ExcludeRules *SExcludeRules `width:"200" charset:"utf8" nullable:"false" list:"user"`
// 表达式类别
// enmu: ByteMatch, GeoMatch, IPSet, LabelMatch, ManagedRuleGroup, Rate, RegexSet, RuleGroup, Size, SqliMatch, XssMatch
Type TWafStatementType `width:"20" charset:"ascii" nullable:"false" list:"user"`
// 是否取反操作, 仅对Azure生效
Negation bool `nullable:"false" list:"user"`
// 操作类型
// enum: EQ, NE, LE, LT, GE, GT
Operator TWafOperator `width:"20" charset:"ascii" nullable:"false" list:"user"`
// 匹配字段
// enmu: Body, JsonBody, Query, Method, Header, UriPath, PostArgs, Cookie
MatchField TWafMatchField `width:"20" charset:"utf8" nullable:"false" list:"user"`
// 匹配字段的key
MatchFieldKey string `width:"20" charset:"utf8" nullable:"false" list:"user"`
// 匹配字段的值列表
MatchFieldValues *TWafMatchFieldValues `width:"250" charset:"utf8" nullable:"false" list:"user"`
// 进行转换操作
// enmu: CompressWithSpace, HtmlEntityDecode, Lowercase, CmdLine, UrlDecode, Trim, UrlEncode, RemoveNulls
Transformations *TextTransformations `width:"250" charset:"ascii" nullable:"false" list:"user"`
ForwardedIPHeader string `width:"20" charset:"ascii" nullable:"false" list:"user"`
// 搜索字段, 仅Aws有用
SearchString string `width:"64" charset:"utf8" nullable:"false" list:"user"`
IPSetId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
// 正则表达式Id, 目前只读
RegexSetId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
// 自定义规则组Id, 目前只读
RuleGroupId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
// 大小, 仅type=Size时必填
Size *int64 `nullable:"false" list:"user"`
// 速率限制, 仅type=Rate时必填
Limit *int64 `nullable:"false" list:"user"`
}
func (self SWafStatement) GetGlobalId() string {
size, limit := int64(0), int64(0)
if self.Size != nil {
size = *self.Size
}
if self.Limit != nil {
limit = *self.Limit
}
return fmt.Sprintf("%s-%s-%s-%s-%s-%d-%d",
self.Type,
self.MatchField,
self.MatchFieldKey,
self.ManagedRuleGroupName,
self.SearchString,
size,
limit,
)
}
func (self SWafStatement) GetExternalId() string {
return self.GetGlobalId()
}
type DefaultAction struct {
// Allow, Block, Log, Count, Alert, Detection, Prevention
Action TWafAction
// 仅Action为Allow时生效
InsertHeaders map[string]string
// 仅Action为Block时生效
Response string
// 仅Action为Block时生效
ResponseCode *int
// 仅Action为Block时生效
ResponseHeaders map[string]string
}
type WafSourceIps []string
type WafRegexPatterns []string
func (self WafRegexPatterns) IsZero() bool {
return len(self) == 0
}
func (self WafRegexPatterns) String() string {
return jsonutils.Marshal(self).String()
}
type WafAddresses []string
func (self WafAddresses) IsZero() bool {
return len(self) == 0
}
func (self WafAddresses) String() string {
return jsonutils.Marshal(self).String()
}
func (self DefaultAction) IsZero() bool {
return false
}
func (self DefaultAction) String() string {
return jsonutils.Marshal(self).String()
}
type SCloudResource struct {
// 资源Id
Id string
// 资源类型
Type string
// 资源映射端口
Port int
// 是否可以解除关联
CanDissociate bool
}
type WafCreateOptions struct {
Name string
Desc string
CloudResources []SCloudResource
SourceIps WafSourceIps
Type TWafType
DefaultAction *DefaultAction
}
func init() {
gotypes.RegisterSerializable(reflect.TypeOf(&DefaultAction{}), func() gotypes.ISerializable {
return &DefaultAction{}
})
gotypes.RegisterSerializable(reflect.TypeOf(&WafAddresses{}), func() gotypes.ISerializable {
return &WafAddresses{}
})
gotypes.RegisterSerializable(reflect.TypeOf(&TextTransformations{}), func() gotypes.ISerializable {
return &TextTransformations{}
})
gotypes.RegisterSerializable(reflect.TypeOf(&TWafMatchFieldValues{}), func() gotypes.ISerializable {
return &TWafMatchFieldValues{}
})
gotypes.RegisterSerializable(reflect.TypeOf(&SExcludeRules{}), func() gotypes.ISerializable {
return &SExcludeRules{}
})
}
+4
View File
@@ -55,6 +55,8 @@ type SCapabilities struct {
DisabledNatBrands []string `json:",allowempty"`
NasBrands []string `json:",allowempty"`
DisabledNasBrands []string `json:",allowempty"`
WafBrands []string `json:",allowempty"`
DisabledWafBrands []string `json:",allowempty"`
PublicIpBrands []string `json:",allowempty"`
NetworkManageBrands []string `json:",allowempty"`
DisabledNetworkManageBrands []string `json:",allowempty"`
@@ -303,6 +305,7 @@ func getBrands(region *SCloudregion, zone *SZone, domainId string, capa *SCapabi
capa.SamlAuthBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.True, cloudprovider.CLOUD_CAPABILITY_SAML_AUTH)
capa.NatBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.True, cloudprovider.CLOUD_CAPABILITY_NAT)
capa.NasBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.True, cloudprovider.CLOUD_CAPABILITY_NAS)
capa.WafBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.True, cloudprovider.CLOUD_CAPABILITY_WAF)
if utils.IsInStringArray(api.HYPERVISOR_KVM, capa.Hypervisors) || utils.IsInStringArray(api.HYPERVISOR_BAREMETAL, capa.Hypervisors) {
capa.Brands = append(capa.Brands, api.ONECLOUD_BRAND_ONECLOUD)
@@ -324,6 +327,7 @@ func getBrands(region *SCloudregion, zone *SZone, domainId string, capa *SCapabi
capa.DisabledSamlAuthBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.False, cloudprovider.CLOUD_CAPABILITY_SAML_AUTH)
capa.DisabledNatBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.False, cloudprovider.CLOUD_CAPABILITY_NAT)
capa.DisabledNasBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.False, cloudprovider.CLOUD_CAPABILITY_NAS)
capa.DisabledNasBrands, _ = CloudaccountManager.getBrandsOfCapability(region, zone, domainId, tristate.False, cloudprovider.CLOUD_CAPABILITY_WAF)
return
}
+91
View File
@@ -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 {
+7
View File
@@ -178,6 +178,13 @@ type IDBInstanceDriver interface {
IElasticIpDriver
INasDriver
IWafDriver
}
type IWafDriver interface {
ValidateCreateWafInstanceData(ctx context.Context, userCred mcclient.TokenCredential, input api.WafInstanceCreateInput) (api.WafInstanceCreateInput, error)
ValidateCreateWafRuleData(ctx context.Context, userCred mcclient.TokenCredential, waf *SWafInstance, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error)
}
type INasDriver interface {
+55
View File
@@ -52,6 +52,7 @@ type SSkuResourcesMeta struct {
ImageBase string `json:"image_base"`
NatBase string `json:"nat_base"`
NasBase string `json:"nas_base"`
WafBase string `json:"waf_base"`
}
var skuIndex = map[string]string{}
@@ -351,6 +352,19 @@ func (self *SSkuResourcesMeta) getServerSkuIndex() (map[string]string, error) {
return ret, nil
}
func (self *SSkuResourcesMeta) getWafIndex() (map[string]string, error) {
resp, err := self.request(fmt.Sprintf("%s/index.json", self.WafBase))
if err != nil {
return map[string]string{}, errors.Wrapf(err, "request")
}
ret := map[string]string{}
err = resp.Unmarshal(ret)
if err != nil {
return map[string]string{}, errors.Wrapf(err, "resp.Unmarshal")
}
return ret, nil
}
func (self *SSkuResourcesMeta) _get(url string) ([]jsonutils.JSONObject, error) {
if !strings.HasPrefix(url, "http") {
return nil, fmt.Errorf("SkuResourcesMeta.get invalid url %s.expected has prefix 'http'", url)
@@ -523,6 +537,20 @@ func FetchSkuResourcesMeta() (*SSkuResourcesMeta, error) {
return ret, nil
}
func fetchCloudEnvs() ([]string, error) {
accounts := []SCloudaccount{}
q := CloudaccountManager.Query("provider", "access_url").In("provider", CloudproviderManager.GetPublicProviderProvidersQuery()).Distinct()
err := q.All(&accounts)
if err != nil {
return nil, errors.Wrapf(err, "q.All")
}
ret := []string{}
for i := range accounts {
ret = append(ret, apis.GetCloudEnv(accounts[i].Provider, accounts[i].AccessUrl))
}
return ret, nil
}
func fetchSkuSyncCloudregions() []SCloudregion {
cloudregions := []SCloudregion{}
q := CloudregionManager.Query()
@@ -535,3 +563,30 @@ func fetchSkuSyncCloudregions() []SCloudregion {
return cloudregions
}
type sWafGroup struct {
SWafRuleGroup
Rules []SWafRule
}
func (self sWafGroup) GetGlobalId() string {
return self.ExternalId
}
func (self SWafRule) GetGlobalId() string {
return self.ExternalId
}
func (self *SSkuResourcesMeta) getCloudWafGroups(cloudEnv string) ([]sWafGroup, error) {
url := fmt.Sprintf("%s/%s.json", self.WafBase, cloudEnv)
resp, err := self.request(url)
if err != nil {
return nil, errors.Wrapf(err, "_get(%s)", url)
}
ret := []sWafGroup{}
err = resp.Unmarshal(&ret)
if err != nil {
return nil, errors.Wrapf(err, "resp.Unmarshal")
}
return ret, nil
}
+478
View File
@@ -0,0 +1,478 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafInstanceManager struct {
db.SEnabledStatusInfrasResourceBaseManager
db.SExternalizedResourceBaseManager
SManagedResourceBaseManager
SCloudregionResourceBaseManager
}
var WafInstanceManager *SWafInstanceManager
func init() {
WafInstanceManager = &SWafInstanceManager{
SEnabledStatusInfrasResourceBaseManager: db.NewEnabledStatusInfrasResourceBaseManager(
SWafInstance{},
"waf_instances_tbl",
"waf_instance",
"waf_instances",
),
}
WafInstanceManager.SetVirtualObject(WafInstanceManager)
}
type SWafInstance struct {
db.SEnabledStatusInfrasResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
SCloudregionResourceBase
Type cloudprovider.TWafType `width:"20" charset:"ascii" nullable:"false" list:"domain" create:"required"`
DefaultAction *cloudprovider.DefaultAction `charset:"ascii" nullable:"true" list:"domain" create:"domain_optional"`
}
func (manager *SWafInstanceManager) GetContextManagers() [][]db.IModelManager {
return [][]db.IModelManager{
{CloudregionManager},
}
}
func (manager *SWafInstanceManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.WafInstanceCreateInput) (api.WafInstanceCreateInput, error) {
_region, err := validators.ValidateModel(userCred, CloudregionManager, &input.CloudregionId)
if err != nil {
return input, err
}
region := _region.(*SCloudregion)
_provider, err := validators.ValidateModel(userCred, CloudproviderManager, &input.CloudproviderId)
if err != nil {
return input, err
}
provider := _provider.(*SCloudprovider)
if !provider.IsAvailable() {
return input, httperrors.NewInputParameterError("cloudprovider %s not available", provider.Name)
}
for i := range input.CloudResources {
switch input.CloudResources[i].Type {
case LoadbalancerManager.Keyword():
_lb, err := validators.ValidateModel(userCred, LoadbalancerManager, &input.CloudResources[i].Id)
if err != nil {
return input, err
}
lb := _lb.(*SLoadbalancer)
if lb.ManagerId != provider.GetId() {
return input, httperrors.NewConflictError("lb %s does not belong to account %s", lb.Name, provider.GetName())
}
case GuestManager.Keyword():
_server, err := validators.ValidateModel(userCred, GuestManager, &input.CloudResources[i].Id)
if err != nil {
return input, err
}
server := _server.(*SGuest)
host := server.GetHost()
if host.ManagerId != provider.GetId() {
return input, httperrors.NewConflictError("server %s does not belong to account %s", server.Name, provider.GetName())
}
default:
return input, httperrors.NewInputParameterError("invalid %d resource type %s", i, input.CloudResources[i].Type)
}
}
input, err = region.GetDriver().ValidateCreateWafInstanceData(ctx, userCred, input)
if err != nil {
return input, err
}
input.SetEnabled()
input.EnabledStatusInfrasResourceBaseCreateInput, err = manager.SEnabledStatusInfrasResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.EnabledStatusInfrasResourceBaseCreateInput)
if err != nil {
return input, err
}
return input, nil
}
func (self *SWafInstance) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
self.SEnabledStatusInfrasResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
self.StartCreateTask(ctx, userCred, data.(*jsonutils.JSONDict))
}
func (self *SWafInstance) StartCreateTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafCreateTask", self, userCred, params, "", "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_STATUS_CREATING, "")
return task.ScheduleRun(nil)
}
func (manager *SWafInstanceManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafInstanceDetails {
rows := make([]api.WafInstanceDetails, len(objs))
stdRows := manager.SEnabledStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
insIds := make([]string, len(objs))
for i := range rows {
rows[i] = api.WafInstanceDetails{
EnabledStatusInfrasResourceBaseDetails: stdRows[i],
ManagedResourceInfo: managerRows[i],
CloudregionResourceInfo: regionRows[i],
}
ins := objs[i].(*SWafInstance)
insIds[i] = ins.Id
}
type WafRule struct {
api.SWafRule
WafInstanceId string
}
rules := []WafRule{}
q := WafRuleManager.Query().In("waf_instance_id", insIds)
err := q.All(&rules)
if err != nil {
return rows
}
ruleMaps := map[string][]api.SWafRule{}
for _, rule := range rules {
_, ok := ruleMaps[rule.WafInstanceId]
if !ok {
ruleMaps[rule.WafInstanceId] = []api.SWafRule{}
}
ruleMaps[rule.WafInstanceId] = append(ruleMaps[rule.WafInstanceId], rule.SWafRule)
}
for i := range rows {
rows[i].Rules, _ = ruleMaps[insIds[i]]
}
return rows
}
// 列出WAF实例
func (manager *SWafInstanceManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafInstanceListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SEnabledStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ListItemFilter")
}
q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
}
q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
}
q, err = manager.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SWafInstanceManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SEnabledStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SWafInstanceManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafInstanceListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SWafInstanceManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SEnabledStatusInfrasResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ListItemExportKeys")
}
if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
}
}
if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
}
}
return q, nil
}
func (self *SCloudregion) GetWafInstances(managerId string) ([]SWafInstance, error) {
q := WafInstanceManager.Query().Equals("cloudregion_id", self.Id)
if len(managerId) > 0 {
q = q.Equals("manager_id", managerId)
}
wafs := []SWafInstance{}
err := db.FetchModelObjects(WafInstanceManager, q, &wafs)
return wafs, err
}
func (self *SCloudregion) SyncWafInstances(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, exts []cloudprovider.ICloudWafInstance) ([]SWafInstance, []cloudprovider.ICloudWafInstance, compare.SyncResult) {
lockman.LockRawObject(ctx, WafInstanceManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
defer lockman.ReleaseRawObject(ctx, WafInstanceManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
result := compare.SyncResult{}
localWafs := []SWafInstance{}
remoteWafs := []cloudprovider.ICloudWafInstance{}
dbWafs, err := self.GetWafInstances(provider.Id)
if err != nil {
result.Error(err)
return nil, nil, result
}
removed := make([]SWafInstance, 0)
commondb := make([]SWafInstance, 0)
commonext := make([]cloudprovider.ICloudWafInstance, 0)
added := make([]cloudprovider.ICloudWafInstance, 0)
if err := compare.CompareSets(dbWafs, exts, &removed, &commondb, &commonext, &added); err != nil {
result.Error(err)
return nil, nil, result
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err := commondb[i].SyncWithCloudWafInstance(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
syncMetadata(ctx, userCred, &commondb[i], commonext[i])
localWafs = append(localWafs, commondb[i])
remoteWafs = append(remoteWafs, commonext[i])
result.Update()
}
for i := 0; i < len(added); i++ {
newWaf, err := self.newFromCloudWafInstance(ctx, userCred, provider, added[i])
if err != nil {
result.AddError(err)
continue
}
syncMetadata(ctx, userCred, newWaf, added[i])
localWafs = append(localWafs, *newWaf)
remoteWafs = append(remoteWafs, added[i])
result.Add()
}
return localWafs, remoteWafs, result
}
func (self *SWafInstance) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred)
}
func (self *SWafInstance) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafDeleteTask", self, userCred, nil, "", "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (self *SWafInstance) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafInstance) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
rules, err := self.GetWafRules()
if err != nil {
return errors.Wrapf(err, "GetWafRules")
}
for i := range rules {
err = rules[i].RealDelete(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "Delete Rule %s", rules[i].Name)
}
}
return self.SEnabledStatusInfrasResourceBase.Delete(ctx, userCred)
}
func (self *SWafInstance) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.RealDelete(ctx, userCred)
}
func (self *SWafInstance) GetRegion() (*SCloudregion, error) {
region, err := CloudregionManager.FetchById(self.CloudregionId)
if err != nil {
return nil, errors.Wrapf(err, "CloudregionManager.FetchById")
}
return region.(*SCloudregion), nil
}
func (self *SWafInstance) GetIRegion() (cloudprovider.ICloudRegion, error) {
region, err := self.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
provider, err := self.GetDriver()
if err != nil {
return nil, errors.Wrapf(err, "GetDriver")
}
return provider.GetIRegionById(region.ExternalId)
}
func (self *SWafInstance) GetICloudWafInstance() (cloudprovider.ICloudWafInstance, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
iRegion, err := self.GetIRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetIRegion")
}
return iRegion.GetICloudWafInstanceById(self.ExternalId)
}
func (self *SWafInstance) SyncWithCloudWafInstance(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudWafInstance) error {
_, err := db.Update(self, func() error {
self.ExternalId = ext.GetGlobalId()
self.SetEnabled(ext.GetEnabled())
self.DefaultAction = ext.GetDefaultAction()
self.Status = ext.GetStatus()
return nil
})
return err
}
func (self *SCloudregion) newFromCloudWafInstance(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafInstance) (*SWafInstance, error) {
waf := &SWafInstance{}
waf.SetModelManager(WafInstanceManager, waf)
waf.SetEnabled(ext.GetEnabled())
waf.CloudregionId = self.Id
waf.ManagerId = provider.Id
waf.Status = ext.GetStatus()
waf.DefaultAction = ext.GetDefaultAction()
waf.Type = ext.GetWafType()
waf.ExternalId = ext.GetGlobalId()
var err = func() error {
lockman.LockRawObject(ctx, WafInstanceManager.Keyword(), "name")
defer lockman.ReleaseRawObject(ctx, WafInstanceManager.Keyword(), "name")
var err error
waf.Name, err = db.GenerateName(ctx, WafInstanceManager, userCred, ext.GetName())
if err != nil {
return errors.Wrapf(err, "db.GenerateName")
}
return WafInstanceManager.TableSpec().Insert(ctx, waf)
}()
if err != nil {
return nil, err
}
return waf, nil
}
func (self *SWafInstance) AllowGetDetailsCloudResources(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsDomainAllowGetSpec(userCred, self, "cloud-resources")
}
// 获取WAF绑定的资源列表
func (self *SWafInstance) GetDetailsCloudResources(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) ([]cloudprovider.SCloudResource, error) {
iWaf, err := self.GetICloudWafInstance()
if err != nil {
return nil, httperrors.NewGeneralError(errors.Wrapf(err, "GetICloudWafInstance"))
}
return iWaf.GetCloudResources()
}
func (self *SWafInstance) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "syncstatus")
}
// 同步WAF状态
func (self *SWafInstance) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WafSyncstatusInput) (jsonutils.JSONObject, error) {
return nil, StartResourceSyncStatusTask(ctx, userCred, self, "WafSyncstatusTask", "")
}
+367
View File
@@ -0,0 +1,367 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafIPSetCacheManager struct {
db.SStatusStandaloneResourceBaseManager
db.SExternalizedResourceBaseManager
SManagedResourceBaseManager
SCloudregionResourceBaseManager
}
var WafIPSetCacheManager *SWafIPSetCacheManager
func init() {
WafIPSetCacheManager = &SWafIPSetCacheManager{
SStatusStandaloneResourceBaseManager: db.NewStatusStandaloneResourceBaseManager(
SWafIPSetCache{},
"waf_ipset_caches_tbl",
"waf_ipset_cache",
"waf_ipset_caches",
),
}
WafIPSetCacheManager.SetVirtualObject(WafIPSetCacheManager)
}
type SWafIPSetCache struct {
db.SStatusStandaloneResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
SCloudregionResourceBase
Type cloudprovider.TWafType `width:"20" charset:"utf8" nullable:"false" list:"user"`
WafIPSetId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
}
func (manager *SWafIPSetCacheManager) GetContextManagers() [][]db.IModelManager {
return [][]db.IModelManager{
{CloudregionManager},
}
}
func (manager *SWafIPSetCacheManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafIPSetCacheDetails {
rows := make([]api.WafIPSetCacheDetails, len(objs))
ssRows := manager.SStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.WafIPSetCacheDetails{
StatusStandaloneResourceDetails: ssRows[i],
ManagedResourceInfo: managerRows[i],
CloudregionResourceInfo: regionRows[i],
}
}
return rows
}
// 列出WAF IPSet缓存
func (manager *SWafIPSetCacheManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafIPSetCacheListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBase.ListItemFilter")
}
q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
}
q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
}
q, err = manager.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SWafIPSetCacheManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SWafIPSetCacheManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafIPSetCacheListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SWafIPSetCacheManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusStandaloneResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.ListItemExportKeys")
}
if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
}
}
if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
}
}
return q, nil
}
func (self *SWafIPSetCache) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafIPSetCache) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SStatusStandaloneResourceBase.Delete(ctx, userCred)
}
func (self *SWafIPSetCache) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.RealDelete(ctx, userCred)
}
func (self *SWafIPSetCache) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred, "")
}
func (self *SWafIPSetCache) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafIPSetCacheDeleteTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_IPSET_STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (self *SWafIPSetCache) GetRegion() (*SCloudregion, error) {
region, err := CloudregionManager.FetchById(self.CloudregionId)
if err != nil {
return nil, errors.Wrapf(err, "CloudregionManager.FetchById")
}
return region.(*SCloudregion), nil
}
func (self *SWafIPSetCache) GetIRegion() (cloudprovider.ICloudRegion, error) {
region, err := self.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
provider, err := self.GetDriver()
if err != nil {
return nil, errors.Wrapf(err, "GetDriver")
}
return provider.GetIRegionById(region.ExternalId)
}
func (self *SWafIPSetCache) GetICloudWafIPSet() (cloudprovider.ICloudWafIPSet, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
iRegion, err := self.GetIRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetIRegion")
}
caches, err := iRegion.GetICloudWafIPSets()
if err != nil {
return nil, errors.Wrapf(err, "GetICloudWafIPSets")
}
for i := range caches {
if caches[i].GetGlobalId() == self.ExternalId {
return caches[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, self.ExternalId)
}
func (self *SWafIPSetCache) syncWithCloudIPSet(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudWafIPSet) error {
_, err := db.Update(self, func() error {
self.Status = api.WAF_IPSET_STATUS_AVAILABLE
self.Name = ext.GetName()
self.Description = ext.GetDesc()
return nil
})
return err
}
func (self *SCloudregion) GetIPSets(managerId string) ([]SWafIPSetCache, error) {
q := WafIPSetCacheManager.Query().Equals("cloudregion_id", self.Id)
if len(managerId) > 0 {
q = q.Equals("manager_id", managerId)
}
caches := []SWafIPSetCache{}
err := db.FetchModelObjects(WafIPSetCacheManager, q, &caches)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return caches, nil
}
func (self *SCloudregion) findOrCreateWafIPSet(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafIPSet) (*SWafIPSet, error) {
q := WafIPSetManager.Query().Equals("domain_id", provider.DomainId).Equals("addresses", ext.GetAddresses().String())
ipSets := []SWafIPSet{}
err := db.FetchModelObjects(WafIPSetManager, q, &ipSets)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
if len(ipSets) > 0 {
return &ipSets[0], nil
}
ipSet := &SWafIPSet{}
ipSet.SetModelManager(WafIPSetManager, ipSet)
ipSet.Name = ext.GetName()
ipSet.Status = api.WAF_IPSET_STATUS_AVAILABLE
ipSet.DomainId = provider.DomainId
addrs := ext.GetAddresses()
ipSet.Addresses = &addrs
return ipSet, WafIPSetManager.TableSpec().Insert(ctx, ipSet)
}
func (self *SCloudregion) newFromCloudWafIPSet(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafIPSet, ipSetId string) error {
cache := &SWafIPSetCache{}
cache.SetModelManager(WafIPSetCacheManager, cache)
cache.Name = ext.GetName()
cache.WafIPSetId = ipSetId
cache.CloudregionId = self.Id
cache.ManagerId = provider.Id
cache.ExternalId = ext.GetGlobalId()
cache.Status = api.WAF_IPSET_STATUS_AVAILABLE
cache.Type = ext.GetType()
cache.Description = ext.GetDesc()
return WafIPSetCacheManager.TableSpec().Insert(ctx, cache)
}
func (self *SCloudregion) SyncWafIPSets(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, exts []cloudprovider.ICloudWafIPSet) compare.SyncResult {
lockman.LockRawObject(ctx, WafIPSetCacheManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
defer lockman.ReleaseRawObject(ctx, WafIPSetCacheManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
result := compare.SyncResult{}
dbIPSets, err := self.GetIPSets(provider.Id)
if err != nil {
result.Error(err)
return result
}
removed := make([]SWafIPSetCache, 0)
commondb := make([]SWafIPSetCache, 0)
commonext := make([]cloudprovider.ICloudWafIPSet, 0)
added := make([]cloudprovider.ICloudWafIPSet, 0)
err = compare.CompareSets(dbIPSets, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err := commondb[i].syncWithCloudIPSet(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i++ {
ipSet, err := self.findOrCreateWafIPSet(ctx, userCred, provider, added[i])
if err != nil {
result.AddError(err)
continue
}
err = self.newFromCloudWafIPSet(ctx, userCred, provider, added[i], ipSet.Id)
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
+151
View File
@@ -0,0 +1,151 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafIPSetManager struct {
db.SStatusInfrasResourceBaseManager
}
var WafIPSetManager *SWafIPSetManager
func init() {
WafIPSetManager = &SWafIPSetManager{
SStatusInfrasResourceBaseManager: db.NewStatusInfrasResourceBaseManager(
SWafIPSet{},
"waf_ipsets_tbl",
"waf_ipset",
"waf_ipsets",
),
}
WafIPSetManager.SetVirtualObject(WafIPSetManager)
}
type SWafIPSet struct {
db.SStatusInfrasResourceBase
Addresses *cloudprovider.WafAddresses `list:"domain" update:"domain" create:"required"`
}
func (manager *SWafIPSetManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafIPSetDetails {
rows := make([]api.WafIPSetDetails, len(objs))
siRows := manager.SStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.WafIPSetDetails{
StatusInfrasResourceBaseDetails: siRows[i],
}
}
return rows
}
// 列出WAF IPSets
func (manager *SWafIPSetManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafIPSetListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SWafIPSetManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SWafIPSetManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafIPSetListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SWafIPSetManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusInfrasResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ListItemExportKeys")
}
return q, nil
}
func (self *SWafIPSet) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafIPSet) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SStatusInfrasResourceBase.Delete(ctx, userCred)
}
func (self *SWafIPSet) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred, "")
}
func (self *SWafIPSet) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafIPSetDeleteTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_IPSET_STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (self *SWafIPSet) GetCaches() ([]SWafIPSetCache, error) {
q := WafIPSetCacheManager.Query().Equals("waf_ipset_id", self.Id)
caches := []SWafIPSetCache{}
err := db.FetchModelObjects(WafIPSetCacheManager, q, &caches)
return caches, err
}
+367
View File
@@ -0,0 +1,367 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafRegexSetCacheManager struct {
db.SStatusStandaloneResourceBaseManager
db.SExternalizedResourceBaseManager
SManagedResourceBaseManager
SCloudregionResourceBaseManager
}
var WafRegexSetCacheManager *SWafRegexSetCacheManager
func init() {
WafRegexSetCacheManager = &SWafRegexSetCacheManager{
SStatusStandaloneResourceBaseManager: db.NewStatusStandaloneResourceBaseManager(
SWafRegexSetCache{},
"waf_regexset_caches_tbl",
"waf_regexset_cache",
"waf_regexset_caches",
),
}
WafRegexSetCacheManager.SetVirtualObject(WafRegexSetCacheManager)
}
type SWafRegexSetCache struct {
db.SStatusStandaloneResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
SCloudregionResourceBase
Type cloudprovider.TWafType `width:"20" charset:"utf8" nullable:"false" list:"user"`
WafRegexSetId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
}
func (manager *SWafRegexSetCacheManager) GetContextManagers() [][]db.IModelManager {
return [][]db.IModelManager{
{CloudregionManager},
}
}
func (manager *SWafRegexSetCacheManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafRegexSetCacheDetails {
rows := make([]api.WafRegexSetCacheDetails, len(objs))
ssRows := manager.SStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.WafRegexSetCacheDetails{
StatusStandaloneResourceDetails: ssRows[i],
ManagedResourceInfo: managerRows[i],
CloudregionResourceInfo: regionRows[i],
}
}
return rows
}
// 列出WAF RegexSet缓存
func (manager *SWafRegexSetCacheManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRegexSetCacheListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBase.ListItemFilter")
}
q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
}
q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
}
q, err = manager.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SWafRegexSetCacheManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SWafRegexSetCacheManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRegexSetCacheListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SWafRegexSetCacheManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusStandaloneResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.ListItemExportKeys")
}
if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
}
}
if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
}
}
return q, nil
}
func (self *SWafRegexSetCache) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafRegexSetCache) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SStatusStandaloneResourceBase.Delete(ctx, userCred)
}
func (self *SWafRegexSetCache) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.RealDelete(ctx, userCred)
}
func (self *SWafRegexSetCache) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred, "")
}
func (self *SWafRegexSetCache) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafRegexSetCacheDeleteTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_REGEX_SET_STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (self *SWafRegexSetCache) GetRegion() (*SCloudregion, error) {
region, err := CloudregionManager.FetchById(self.CloudregionId)
if err != nil {
return nil, errors.Wrapf(err, "CloudregionManager.FetchById")
}
return region.(*SCloudregion), nil
}
func (self *SWafRegexSetCache) GetIRegion() (cloudprovider.ICloudRegion, error) {
region, err := self.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
provider, err := self.GetDriver()
if err != nil {
return nil, errors.Wrapf(err, "GetDriver")
}
return provider.GetIRegionById(region.ExternalId)
}
func (self *SWafRegexSetCache) GetICloudWafRegexSet() (cloudprovider.ICloudWafRegexSet, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
iRegion, err := self.GetIRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetIRegion")
}
caches, err := iRegion.GetICloudWafRegexSets()
if err != nil {
return nil, errors.Wrapf(err, "GetICloudWafRegexSets")
}
for i := range caches {
if caches[i].GetGlobalId() == self.ExternalId {
return caches[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, self.ExternalId)
}
func (self *SWafRegexSetCache) syncWithCloudRegexSet(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudWafRegexSet) error {
_, err := db.Update(self, func() error {
self.Status = api.WAF_IPSET_STATUS_AVAILABLE
self.Name = ext.GetName()
self.Description = ext.GetDesc()
return nil
})
return err
}
func (self *SCloudregion) GetRegexSets(managerId string) ([]SWafRegexSetCache, error) {
q := WafRegexSetCacheManager.Query().Equals("cloudregion_id", self.Id)
if len(managerId) > 0 {
q = q.Equals("manager_id", managerId)
}
caches := []SWafRegexSetCache{}
err := db.FetchModelObjects(WafRegexSetCacheManager, q, &caches)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return caches, nil
}
func (self *SCloudregion) findOrCreateWafRegexSet(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafRegexSet) (*SWafRegexSet, error) {
q := WafRegexSetManager.Query().Equals("domain_id", provider.DomainId).Equals("regex_patterns", ext.GetRegexPatterns().String())
patternSets := []SWafRegexSet{}
err := db.FetchModelObjects(WafRegexSetManager, q, &patternSets)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
if len(patternSets) > 0 {
return &patternSets[0], nil
}
ps := &SWafRegexSet{}
ps.SetModelManager(WafRegexSetManager, ps)
ps.Name = ext.GetName()
ps.Status = api.WAF_IPSET_STATUS_AVAILABLE
ps.DomainId = provider.DomainId
patterns := ext.GetRegexPatterns()
ps.RegexPatterns = &patterns
return ps, WafRegexSetManager.TableSpec().Insert(ctx, ps)
}
func (self *SCloudregion) newFromCloudWafRegexSet(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafRegexSet, ipSetId string) error {
cache := &SWafRegexSetCache{}
cache.SetModelManager(WafRegexSetCacheManager, cache)
cache.Name = ext.GetName()
cache.WafRegexSetId = ipSetId
cache.CloudregionId = self.Id
cache.ManagerId = provider.Id
cache.ExternalId = ext.GetGlobalId()
cache.Status = api.WAF_IPSET_STATUS_AVAILABLE
cache.Type = ext.GetType()
cache.Description = ext.GetDesc()
return WafRegexSetCacheManager.TableSpec().Insert(ctx, cache)
}
func (self *SCloudregion) SyncWafRegexSets(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, exts []cloudprovider.ICloudWafRegexSet) compare.SyncResult {
lockman.LockRawObject(ctx, WafRegexSetCacheManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
defer lockman.ReleaseRawObject(ctx, WafRegexSetCacheManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
result := compare.SyncResult{}
dbRegexSets, err := self.GetRegexSets(provider.Id)
if err != nil {
result.Error(err)
return result
}
removed := make([]SWafRegexSetCache, 0)
commondb := make([]SWafRegexSetCache, 0)
commonext := make([]cloudprovider.ICloudWafRegexSet, 0)
added := make([]cloudprovider.ICloudWafRegexSet, 0)
err = compare.CompareSets(dbRegexSets, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err := commondb[i].syncWithCloudRegexSet(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i++ {
ipSet, err := self.findOrCreateWafRegexSet(ctx, userCred, provider, added[i])
if err != nil {
result.AddError(err)
continue
}
err = self.newFromCloudWafRegexSet(ctx, userCred, provider, added[i], ipSet.Id)
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
+151
View File
@@ -0,0 +1,151 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafRegexSetManager struct {
db.SStatusInfrasResourceBaseManager
}
var WafRegexSetManager *SWafRegexSetManager
func init() {
WafRegexSetManager = &SWafRegexSetManager{
SStatusInfrasResourceBaseManager: db.NewStatusInfrasResourceBaseManager(
SWafRegexSet{},
"waf_regexsets_tbl",
"waf_regexset",
"waf_regexsets",
),
}
WafRegexSetManager.SetVirtualObject(WafRegexSetManager)
}
type SWafRegexSet struct {
db.SStatusInfrasResourceBase
RegexPatterns *cloudprovider.WafRegexPatterns `list:"domain" update:"domain" create:"required"`
}
func (manager *SWafRegexSetManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafRegexSetDetails {
rows := make([]api.WafRegexSetDetails, len(objs))
siRows := manager.SStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.WafRegexSetDetails{
StatusInfrasResourceBaseDetails: siRows[i],
}
}
return rows
}
// 列出WAF RegexSets
func (manager *SWafRegexSetManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRegexSetListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SWafRegexSetManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SWafRegexSetManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRegexSetListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SWafRegexSetManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusInfrasResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ListItemExportKeys")
}
return q, nil
}
func (self *SWafRegexSet) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafRegexSet) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SStatusInfrasResourceBase.Delete(ctx, userCred)
}
func (self *SWafRegexSet) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred, "")
}
func (self *SWafRegexSet) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafRegexSetDeleteTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_REGEX_SET_STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (self *SWafRegexSet) GetCaches() ([]SWafRegexSetCache, error) {
q := WafRegexSetCacheManager.Query().Equals("waf_regexset_id", self.Id)
caches := []SWafRegexSetCache{}
err := db.FetchModelObjects(WafRegexSetCacheManager, q, &caches)
return caches, err
}
+367
View File
@@ -0,0 +1,367 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafRuleGroupCacheManager struct {
db.SStatusStandaloneResourceBaseManager
db.SExternalizedResourceBaseManager
SManagedResourceBaseManager
SCloudregionResourceBaseManager
}
var WafRuleGroupCacheManager *SWafRuleGroupCacheManager
func init() {
WafRuleGroupCacheManager = &SWafRuleGroupCacheManager{
SStatusStandaloneResourceBaseManager: db.NewStatusStandaloneResourceBaseManager(
SWafRuleGroupCache{},
"waf_rule_group_caches_tbl",
"waf_rule_group_cache",
"waf_rule_group_caches",
),
}
WafRuleGroupCacheManager.SetVirtualObject(WafRuleGroupCacheManager)
}
type SWafRuleGroupCache struct {
db.SStatusStandaloneResourceBase
db.SExternalizedResourceBase
SManagedResourceBase
SCloudregionResourceBase
Type cloudprovider.TWafType `width:"20" charset:"utf8" nullable:"false" list:"user"`
WafRuleGroupId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
}
func (manager *SWafRuleGroupCacheManager) GetContextManagers() [][]db.IModelManager {
return [][]db.IModelManager{
{CloudregionManager},
}
}
func (manager *SWafRuleGroupCacheManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafRuleGroupCacheDetails {
rows := make([]api.WafRuleGroupCacheDetails, len(objs))
ssRows := manager.SStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.WafRuleGroupCacheDetails{
StatusStandaloneResourceDetails: ssRows[i],
ManagedResourceInfo: managerRows[i],
CloudregionResourceInfo: regionRows[i],
}
}
return rows
}
// 列出WAF RuleGroup缓存
func (manager *SWafRuleGroupCacheManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRuleGroupCacheListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBase.ListItemFilter")
}
q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
}
q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
}
q, err = manager.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
}
return q, nil
}
func (manager *SWafRuleGroupCacheManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
q, err = manager.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SWafRuleGroupCacheManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRuleGroupCacheListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusStandaloneResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
}
q, err = manager.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SWafRuleGroupCacheManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusStandaloneResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusStandaloneResourceBaseManager.ListItemExportKeys")
}
if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
}
}
if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
}
}
return q, nil
}
func (self *SWafRuleGroupCache) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafRuleGroupCache) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.SStatusStandaloneResourceBase.Delete(ctx, userCred)
}
func (self *SWafRuleGroupCache) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.RealDelete(ctx, userCred)
}
func (self *SWafRuleGroupCache) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred, "")
}
func (self *SWafRuleGroupCache) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafRuleGroupCacheDeleteTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_RULE_GROUP_STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (self *SWafRuleGroupCache) GetRegion() (*SCloudregion, error) {
region, err := CloudregionManager.FetchById(self.CloudregionId)
if err != nil {
return nil, errors.Wrapf(err, "CloudregionManager.FetchById")
}
return region.(*SCloudregion), nil
}
func (self *SWafRuleGroupCache) GetIRegion() (cloudprovider.ICloudRegion, error) {
region, err := self.GetRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetRegion")
}
provider, err := self.GetDriver()
if err != nil {
return nil, errors.Wrapf(err, "GetDriver")
}
return provider.GetIRegionById(region.ExternalId)
}
func (self *SWafRuleGroupCache) GetICloudWafRuleGroup() (cloudprovider.ICloudWafRuleGroup, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
iRegion, err := self.GetIRegion()
if err != nil {
return nil, errors.Wrapf(err, "GetIRegion")
}
caches, err := iRegion.GetICloudWafRuleGroups()
if err != nil {
return nil, errors.Wrapf(err, "GetICloudWafRuleGroups")
}
for i := range caches {
if caches[i].GetGlobalId() == self.ExternalId {
return caches[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, self.ExternalId)
}
func (self *SWafRuleGroupCache) syncWithCloudRuleGroup(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudWafRuleGroup) error {
_, err := db.Update(self, func() error {
self.Status = api.WAF_RULE_GROUP_STATUS_AVAILABLE
self.Name = ext.GetName()
self.Type = ext.GetWafType()
self.Description = ext.GetDesc()
return nil
})
return err
}
func (self *SCloudregion) GetRuleGroups(managerId string) ([]SWafRuleGroupCache, error) {
q := WafRuleGroupCacheManager.Query().Equals("cloudregion_id", self.Id)
if len(managerId) > 0 {
q = q.Equals("manager_id", managerId)
}
caches := []SWafRuleGroupCache{}
err := db.FetchModelObjects(WafRuleGroupCacheManager, q, &caches)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return caches, nil
}
func (self *SCloudregion) createWafRuleGroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafRuleGroup) (*SWafRuleGroup, error) {
rg := &SWafRuleGroup{}
rg.SetModelManager(WafRuleGroupManager, rg)
rg.Name = ext.GetName()
rg.Status = api.WAF_RULE_GROUP_STATUS_AVAILABLE
rg.Description = ext.GetDesc()
rg.DomainId = provider.DomainId
return rg, WafRuleGroupManager.TableSpec().Insert(ctx, rg)
}
func (self *SCloudregion) createRuleGroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafRuleGroup) (*SWafRuleGroup, error) {
rg := &SWafRuleGroup{}
rg.SetModelManager(WafRuleGroupManager, rg)
rg.Name = ext.GetName()
rg.Status = api.WAF_RULE_GROUP_STATUS_AVAILABLE
rg.Description = ext.GetDesc()
rg.DomainId = provider.DomainId
return rg, WafRuleGroupManager.TableSpec().Insert(ctx, rg)
}
func (self *SCloudregion) newFromCloudWafRuleGroup(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafRuleGroup) error {
rg, err := self.createRuleGroup(ctx, userCred, provider, ext)
if err != nil {
return errors.Wrapf(err, "createRuleGroup")
}
cache := &SWafRuleGroupCache{}
cache.SetModelManager(WafRuleGroupCacheManager, cache)
cache.Name = ext.GetName()
cache.WafRuleGroupId = rg.Id
cache.CloudregionId = self.Id
cache.ManagerId = provider.Id
cache.ExternalId = ext.GetGlobalId()
cache.Status = api.WAF_RULE_GROUP_STATUS_AVAILABLE
cache.Type = ext.GetWafType()
cache.Description = ext.GetDesc()
return WafRuleGroupCacheManager.TableSpec().Insert(ctx, cache)
}
func (self *SCloudregion) SyncWafRuleGroups(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, exts []cloudprovider.ICloudWafRuleGroup) compare.SyncResult {
lockman.LockRawObject(ctx, WafRuleGroupCacheManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
defer lockman.ReleaseRawObject(ctx, WafRuleGroupCacheManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
result := compare.SyncResult{}
dbRuleGroups, err := self.GetRuleGroups(provider.Id)
if err != nil {
result.Error(err)
return result
}
removed := make([]SWafRuleGroupCache, 0)
commondb := make([]SWafRuleGroupCache, 0)
commonext := make([]cloudprovider.ICloudWafRuleGroup, 0)
added := make([]cloudprovider.ICloudWafRuleGroup, 0)
err = compare.CompareSets(dbRuleGroups, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err := commondb[i].syncWithCloudRuleGroup(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i++ {
err = self.newFromCloudWafRuleGroup(ctx, userCred, provider, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
+305
View File
@@ -0,0 +1,305 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafRuleGroupManager struct {
db.SStatusInfrasResourceBaseManager
db.SExternalizedResourceBaseManager
}
var wafIndex map[string]string
var WafRuleGroupManager *SWafRuleGroupManager
func init() {
WafRuleGroupManager = &SWafRuleGroupManager{
SStatusInfrasResourceBaseManager: db.NewStatusInfrasResourceBaseManager(
SWafRuleGroup{},
"waf_rule_groups_tbl",
"waf_rule_group",
"waf_rule_groups",
),
}
wafIndex = map[string]string{}
WafRuleGroupManager.SetVirtualObject(WafRuleGroupManager)
}
type SWafRuleGroup struct {
db.SStatusInfrasResourceBase
db.SExternalizedResourceBase
// 支持的WAF类型,仅is_system=true时有效
WafType cloudprovider.TWafType `width:"40" charset:"ascii" list:"domain" nullable:"false"`
Provider string `width:"20" charset:"ascii" list:"domain" nullable:"false"`
CloudEnv string `width:"20" charset:"ascii" list:"domain" nullable:"false"`
IsSystem bool `nullable:"false" default:"false" list:"domain" update:"domain" create:"optional"`
}
func (manager *SWafRuleGroupManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafRuleGroupDetails {
rows := make([]api.WafRuleGroupDetails, len(objs))
siRows := manager.SStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
for i := range rows {
rows[i] = api.WafRuleGroupDetails{
StatusInfrasResourceBaseDetails: siRows[i],
}
}
return rows
}
// 列出WAF RuleGroups
func (manager *SWafRuleGroupManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRuleGroupListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ListItemFilter")
}
if query.IsSystem != nil {
q = q.Equals("is_system", *query.IsSystem)
}
if len(query.Provider) > 0 {
q = q.Equals("provider", query.Provider)
}
if len(query.CloudEnv) > 0 {
q = q.Equals("cloud_env", query.CloudEnv)
}
return q, nil
}
func (manager *SWafRuleGroupManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
if err == nil {
return q, nil
}
return q, httperrors.ErrNotFound
}
func (manager *SWafRuleGroupManager) OrderByExtraFields(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRuleGroupListInput,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.StatusInfrasResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.OrderByExtraFields")
}
return q, nil
}
func (manager *SWafRuleGroupManager) ListItemExportKeys(ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
keys stringutils2.SSortedStrings,
) (*sqlchemy.SQuery, error) {
q, err := manager.SStatusInfrasResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
if err != nil {
return nil, errors.Wrap(err, "SStatusInfrasResourceBaseManager.ListItemExportKeys")
}
return q, nil
}
func (self *SWafRuleGroup) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafRuleGroup) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
rules, err := self.GetWafRules()
if err != nil {
return errors.Wrapf(err, "GetWafRules")
}
for i := range rules {
err = rules[i].Delete(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "Delete rule %s %s", rules[i].Id, rules[i].Name)
}
}
return self.SStatusInfrasResourceBase.Delete(ctx, userCred)
}
func (self *SSkuResourcesMeta) GetWafGroups(cloudEnv string) ([]SWafRuleGroup, error) {
q := WafRuleGroupManager.Query().Equals("cloud_env", cloudEnv).IsTrue("is_system")
groups := []SWafRuleGroup{}
err := db.FetchModelObjects(WafRuleGroupManager, q, &groups)
return groups, err
}
func (self *SWafRuleGroup) syncWithCloudSku(ctx context.Context, userCred mcclient.TokenCredential, ext sWafGroup) error {
_, err := db.Update(self, func() error {
self.Name = ext.Name
self.Description = ext.Description
self.IsPublic = true
self.Status = api.WAF_RULE_GROUP_STATUS_AVAILABLE
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update")
}
result, err := self.SyncManagedWafRules(ctx, userCred, ext.Rules)
if err != nil {
return errors.Wrapf(err, "SyncManagedWafRules")
}
log.Debugf("Sync waf group %s rule result: %s", self.Name, result.Result())
return nil
}
func (self *SSkuResourcesMeta) newFromCloudWafGroup(ctx context.Context, userCred mcclient.TokenCredential, ext sWafGroup) error {
group := &ext.SWafRuleGroup
group.SetModelManager(WafRuleGroupManager, group)
group.Status = api.WAF_RULE_GROUP_STATUS_AVAILABLE
group.IsPublic = true
err := WafRuleGroupManager.TableSpec().Insert(ctx, group)
if err != nil {
return errors.Wrapf(err, "Insert")
}
result, err := group.SyncManagedWafRules(ctx, userCred, ext.Rules)
if err != nil {
return errors.Wrapf(err, "SyncManagedWafRules")
}
log.Debugf("Sync waf group %s rule result: %s", group.Name, result.Result())
return nil
}
func (self *SSkuResourcesMeta) SyncWafGroups(ctx context.Context, userCred mcclient.TokenCredential, cloudEnv string) compare.SyncResult {
lockman.LockRawObject(ctx, cloudEnv, "waf-rule-group")
defer lockman.ReleaseRawObject(ctx, cloudEnv, "waf-rule-group")
result := compare.SyncResult{}
exts, err := self.getCloudWafGroups(cloudEnv)
if err != nil {
result.Error(errors.Wrapf(err, "getWafGroups(%s)", cloudEnv))
return result
}
dbGroup, err := self.GetWafGroups(cloudEnv)
if err != nil {
result.Error(errors.Wrapf(err, "GetWafGroups"))
return result
}
removed := make([]SWafRuleGroup, 0)
commondb := make([]SWafRuleGroup, 0)
commonext := make([]sWafGroup, 0)
added := make([]sWafGroup, 0)
err = compare.CompareSets(dbGroup, exts, &removed, &commondb, &commonext, &added)
if err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i += 1 {
err = removed[i].RealDelete(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i += 1 {
err = commondb[i].syncWithCloudSku(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i += 1 {
err = self.newFromCloudWafGroup(ctx, userCred, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func SyncWafGroups(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
err := func() error {
cloudEnvs, err := fetchCloudEnvs()
if err != nil {
return errors.Wrapf(err, "fetchCloudEnvs")
}
meta, err := FetchSkuResourcesMeta()
if err != nil {
return errors.Wrapf(err, "FetchSkuResourcesMeta")
}
index, err := meta.getWafIndex()
if err != nil {
return errors.Wrapf(err, "getWafIndex")
}
for _, cloudEnv := range cloudEnvs {
newMd5, ok := index[cloudEnv]
if !ok {
continue
}
oldMd5, _ := wafIndex[cloudEnv]
if newMd5 == EMPTY_MD5 {
log.Infof("%s Waf group is empty skip syncing", cloudEnv)
continue
}
if len(oldMd5) > 0 && newMd5 == oldMd5 {
log.Infof("%s Waf group not Changed skip syncing", cloudEnv)
continue
}
result := meta.SyncWafGroups(ctx, userCred, cloudEnv)
log.Infof("sync %s waf group result: %s", cloudEnv, result.Result())
wafIndex[cloudEnv] = newMd5
}
return nil
}()
if err != nil {
log.Errorf("SyncWafGroups: error: %v", err)
}
}
+193
View File
@@ -0,0 +1,193 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/pkg/util/stringutils"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/mcclient"
)
type SWafRuleStatementManager struct {
db.SResourceBaseManager
}
var WafRuleStatementManager *SWafRuleStatementManager
func init() {
WafRuleStatementManager = &SWafRuleStatementManager{
SResourceBaseManager: db.NewResourceBaseManager(
SWafRuleStatement{},
"waf_rule_statements_tbl",
"waf_rule_statement",
"waf_rule_statements",
),
}
WafRuleStatementManager.SetVirtualObject(WafRuleStatementManager)
}
type SWafRuleStatement struct {
db.SResourceBase
Id string `width:"128" charset:"ascii" primary:"true" list:"user"`
cloudprovider.SWafStatement
WafRuleId string `width:"36" charset:"ascii" nullable:"false" list:"user"`
}
func (self *SWafRuleStatement) BeforeInsert() {
if len(self.Id) == 0 {
self.Id = stringutils.UUID4()
}
}
func (self *SWafRuleStatement) GetId() string {
return self.Id
}
func (self *SWafRule) GetRuleStatements() ([]SWafRuleStatement, error) {
q := WafRuleStatementManager.Query().Equals("waf_rule_id", self.Id)
statements := []SWafRuleStatement{}
err := db.FetchModelObjects(WafRuleStatementManager, q, &statements)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return statements, nil
}
func (self *SWafRuleStatement) syncWithStatement(ctx context.Context, userCred mcclient.TokenCredential, statement cloudprovider.SWafStatement) error {
_, err := db.Update(self, func() error {
self.SWafStatement = statement
switch self.Type {
case cloudprovider.WafStatementTypeIPSet:
if len(self.IPSetId) > 0 {
_cache, err := db.FetchByExternalId(WafIPSetCacheManager, self.IPSetId)
if err != nil {
log.Errorf("WafIPSetCacheManager(%s) error: %v", self.IPSetId, err)
} else {
cache := _cache.(*SWafIPSetCache)
self.IPSetId = cache.WafIPSetId
}
}
case cloudprovider.WafStatementTypeRegexSet:
if len(self.RegexSetId) > 0 {
_cache, err := db.FetchByExternalId(WafRegexSetCacheManager, self.RegexSetId)
if err != nil {
log.Errorf("WafRegexSetCacheManager(%s) error: %v", self.RegexSetId, err)
} else {
cache := _cache.(*SWafRegexSetCache)
self.RegexSetId = cache.WafRegexSetId
}
}
}
return nil
})
return err
}
func (self *SWafRule) newFromCloudStatement(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.SWafStatement) error {
statement := &SWafRuleStatement{}
statement.SetModelManager(WafRuleStatementManager, statement)
statement.WafRuleId = self.Id
statement.SWafStatement = ext
switch statement.Type {
case cloudprovider.WafStatementTypeIPSet:
if len(statement.IPSetId) > 0 {
_cache, err := db.FetchByExternalId(WafIPSetCacheManager, statement.IPSetId)
if err != nil {
log.Errorf("WafIPSetCacheManager(%s) error: %v", statement.IPSetId, err)
} else {
cache := _cache.(*SWafIPSetCache)
statement.IPSetId = cache.WafIPSetId
}
}
case cloudprovider.WafStatementTypeRegexSet:
if len(statement.RegexSetId) > 0 {
_cache, err := db.FetchByExternalId(WafRegexSetCacheManager, statement.RegexSetId)
if err != nil {
log.Errorf("WafRegexSetCacheManager(%s) error: %v", statement.RegexSetId, err)
} else {
cache := _cache.(*SWafRegexSetCache)
statement.RegexSetId = cache.WafRegexSetId
}
}
}
return WafRuleStatementManager.TableSpec().Insert(ctx, statement)
}
func (self *SWafRule) SyncStatements(ctx context.Context, userCred mcclient.TokenCredential, rule cloudprovider.ICloudWafRule) error {
lockman.LockRawObject(ctx, WafRuleManager.Keyword(), self.Id)
defer lockman.ReleaseRawObject(ctx, WafRuleManager.Keyword(), self.Id)
dbStatements, err := self.GetRuleStatements()
if err != nil {
return errors.Wrapf(err, "GetRuleStatements")
}
exts, err := rule.GetStatements()
if err != nil {
return errors.Wrapf(err, "GetStatements")
}
result := compare.SyncResult{}
removed := make([]SWafRuleStatement, 0)
commondb := make([]SWafRuleStatement, 0)
commonext := make([]cloudprovider.SWafStatement, 0)
added := make([]cloudprovider.SWafStatement, 0)
err = compare.CompareSets(dbStatements, exts, &removed, &commondb, &commonext, &added)
if err != nil {
return errors.Wrapf(err, "compare.CompareSets")
}
for i := 0; i < len(removed); i++ {
err := removed[i].Delete(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err := commondb[i].syncWithStatement(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i++ {
err := self.newFromCloudStatement(ctx, userCred, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
log.Debugf("sync statements for rule %s result: %s", self.Name, result.Result())
return nil
}
+583
View File
@@ -0,0 +1,583 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package models
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/compare"
"yunion.io/x/sqlchemy"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/lockman"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/util/rbacutils"
"yunion.io/x/onecloud/pkg/util/stringutils2"
)
type SWafRuleManager struct {
db.SStatusStandaloneResourceBaseManager
db.SExternalizedResourceBaseManager
}
var WafRuleManager *SWafRuleManager
func init() {
WafRuleManager = &SWafRuleManager{
SStatusStandaloneResourceBaseManager: db.NewStatusStandaloneResourceBaseManager(
SWafRule{},
"waf_rules_tbl",
"waf_rule",
"waf_rules",
),
}
WafRuleManager.SetVirtualObject(WafRuleManager)
}
type SWafRule struct {
db.SStatusStandaloneResourceBase
db.SExternalizedResourceBase
// 规则优先级
Priority int `nullable:"false" list:"domain" create:"required"`
// 规则默认行为
Action *cloudprovider.DefaultAction `charset:"utf8" nullable:"false" list:"user" update:"domain" create:"required"`
// 条件
StatementConditon cloudprovider.TWafStatementCondition `width:"20" charset:"ascii" nullable:"false" list:"domain" create:"optional"`
// 规则组的id
WafRuleGroupId string `width:"36" charset:"ascii" nullable:"false" list:"domain" create:"optional"`
// 所属waf实例id
WafInstanceId string `width:"36" charset:"ascii" nullable:"false" list:"domain" create:"optional"`
}
func (manager *SWafRuleManager) FetchUniqValues(ctx context.Context, data jsonutils.JSONObject) jsonutils.JSONObject {
values := struct {
WafRuleGroupId string
WafInstanceId string
}{}
data.Unmarshal(&values)
return jsonutils.Marshal(values)
}
func (manager *SWafRuleManager) FilterByUniqValues(q *sqlchemy.SQuery, values jsonutils.JSONObject) *sqlchemy.SQuery {
data := struct {
WafRuleGroupId string
WafInstanceId string
}{}
if len(data.WafRuleGroupId) > 0 {
q = q.Equals("waf_rule_group_id", data.WafRuleGroupId)
}
if len(data.WafInstanceId) > 0 {
q = q.Equals("waf_instance_id", data.WafInstanceId)
}
return q
}
func (manager *SWafRuleManager) FetchOwnerId(ctx context.Context, data jsonutils.JSONObject) (mcclient.IIdentityProvider, error) {
values := struct {
WafRuleGroupId string
WafInstanceId string
}{}
data.Unmarshal(&values)
if len(values.WafInstanceId) > 0 {
ins, err := db.FetchById(WafInstanceManager, values.WafInstanceId)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchById(WafInstanceManager, %s)", values.WafInstanceId)
}
waf := ins.(*SWafInstance)
return waf.GetOwnerId(), nil
}
if len(values.WafRuleGroupId) > 0 {
rg, err := db.FetchById(WafRuleGroupManager, values.WafRuleGroupId)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchById(WafRuleGroupManager, %s)", values.WafRuleGroupId)
}
return rg.GetOwnerId(), nil
}
return db.FetchDomainInfo(ctx, data)
}
func (manager *SWafRuleManager) FilterByOwner(q *sqlchemy.SQuery, userCred mcclient.IIdentityProvider, scope rbacutils.TRbacScope) *sqlchemy.SQuery {
sq1 := WafInstanceManager.Query("id")
sq1 = db.SharableManagerFilterByOwner(WafInstanceManager, sq1, userCred, scope)
sq2 := WafRuleGroupManager.Query("id")
sq2 = db.SharableManagerFilterByOwner(WafRuleGroupManager, sq2, userCred, scope)
return q.Filter(sqlchemy.OR(
sqlchemy.In(q.Field("waf_instance_id"), sq1.SubQuery()),
sqlchemy.In(q.Field("waf_rule_group_id"), sq2.SubQuery()),
))
}
func (manager *SWafRuleManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error) {
if len(input.WafInstanceId) > 0 {
ins, err := validators.ValidateModel(userCred, WafInstanceManager, &input.WafInstanceId)
if err != nil {
return input, err
}
waf := ins.(*SWafInstance)
if waf.Status != api.WAF_STATUS_AVAILABLE {
return input, httperrors.NewInvalidStatusError("waf %s status is not available", waf.Name)
}
region, err := waf.GetRegion()
if err != nil {
return input, httperrors.NewGeneralError(errors.Wrapf(err, "GetRegion"))
}
input, err = region.GetDriver().ValidateCreateWafRuleData(ctx, userCred, waf, input)
if err != nil {
return input, err
}
} else if len(input.WafRuleGroupId) > 0 {
return input, httperrors.NewInputParameterError("not implement")
} else {
return input, httperrors.NewMissingParameterError("waf_instance_id")
}
var err error
input.StatusStandaloneResourceCreateInput, err = manager.SStatusStandaloneResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.StatusStandaloneResourceCreateInput)
if err != nil {
return input, err
}
return input, nil
}
func (self *SWafRule) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
self.SStatusStandaloneResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
input := &api.WafRuleCreateInput{}
data.Unmarshal(input)
for _, s := range input.Statements {
statement := &SWafRuleStatement{}
statement.SetModelManager(WafRuleStatementManager, statement)
statement.SWafStatement = s
statement.WafRuleId = self.Id
WafRuleStatementManager.TableSpec().Insert(ctx, statement)
}
self.StartCreateTask(ctx, userCred)
}
func (self *SWafRule) StartCreateTask(ctx context.Context, userCred mcclient.TokenCredential) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafRuleCreateTask", self, userCred, nil, "", "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_RULE_STATUS_CREATING, "")
return task.ScheduleRun(nil)
}
// 列出WAF规则
func (manager *SWafRuleManager) ListItemFilter(
ctx context.Context,
q *sqlchemy.SQuery,
userCred mcclient.TokenCredential,
query api.WafRuleListInput,
) (*sqlchemy.SQuery, error) {
var err error
q, err = manager.SStatusStandaloneResourceBaseManager.ListItemFilter(ctx, q, userCred, query.StatusStandaloneResourceListInput)
if err != nil {
return nil, errors.Wrap(err, "SEnabledStatusStandaloneResourceBaseManager.ListItemFilter")
}
q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
if err != nil {
return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
}
if len(query.WafInstanceId) > 0 {
_, err := validators.ValidateModel(userCred, WafInstanceManager, &query.WafInstanceId)
if err != nil {
return nil, err
}
q = q.Equals("waf_instance_id", query.WafInstanceId)
}
if len(query.WafRuleGroupId) > 0 {
_, err := validators.ValidateModel(userCred, WafRuleGroupManager, &query.WafRuleGroupId)
if err != nil {
return nil, err
}
q = q.Equals("waf_rule_group_id", query.WafRuleGroupId)
}
return q, nil
}
func (manager *SWafRuleManager) FetchCustomizeColumns(
ctx context.Context,
userCred mcclient.TokenCredential,
query jsonutils.JSONObject,
objs []interface{},
fields stringutils2.SSortedStrings,
isList bool,
) []api.WafRuleDetails {
rows := make([]api.WafRuleDetails, len(objs))
stdRows := manager.SStatusStandaloneResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
ruleIds := make([]string, len(objs))
for i := range rows {
rows[i] = api.WafRuleDetails{
StatusStandaloneResourceDetails: stdRows[i],
}
ruleIds[i] = objs[i].(*SWafRule).Id
}
q := WafRuleStatementManager.Query().In("waf_rule_id", ruleIds)
statements := []SWafRuleStatement{}
err := q.All(&statements)
if err != nil {
return rows
}
statementMaps := map[string][]cloudprovider.SWafStatement{}
for i := range statements {
_, ok := statementMaps[statements[i].WafRuleId]
if !ok {
statementMaps[statements[i].WafRuleId] = []cloudprovider.SWafStatement{}
}
statementMaps[statements[i].WafRuleId] = append(statementMaps[statements[i].WafRuleId], statements[i].SWafStatement)
}
for i := range rows {
rows[i].Statements, _ = statementMaps[ruleIds[i]]
}
return rows
}
func (self *SWafRule) GetWafInstance() (*SWafInstance, error) {
waf, err := WafInstanceManager.FetchById(self.WafInstanceId)
if err != nil {
return nil, errors.Wrapf(err, "WafInstanceManager.FetchById(%s)", self.WafInstanceId)
}
return waf.(*SWafInstance), nil
}
func (self *SWafRule) GetWafRuleGroup() (*SWafRuleGroup, error) {
rg, err := WafRuleGroupManager.FetchById(self.WafRuleGroupId)
if err != nil {
return nil, errors.Wrapf(err, "WafRuleGroupManager.FetchById(%s)", self.WafRuleGroupId)
}
return rg.(*SWafRuleGroup), nil
}
func (self *SWafRule) GetOwnerId() mcclient.IIdentityProvider {
if len(self.WafInstanceId) > 0 {
ins, err := self.GetWafInstance()
if err != nil {
return nil
}
return ins.GetOwnerId()
}
if len(self.WafRuleGroupId) > 0 {
rg, err := self.GetWafRuleGroup()
if err != nil {
return nil
}
return rg.GetOwnerId()
}
return nil
}
func (manager *SWafRuleManager) ResourceScope() rbacutils.TRbacScope {
return rbacutils.ScopeDomain
}
func (self *SWafInstance) GetWafRules() ([]SWafRule, error) {
q := WafRuleManager.Query().Equals("waf_instance_id", self.Id)
rules := []SWafRule{}
err := db.FetchModelObjects(WafRuleManager, q, &rules)
if err != nil {
return nil, errors.Wrapf(err, "db.FetchModelObjects")
}
return rules, nil
}
func (self *SWafRule) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
return self.StartDeleteTask(ctx, userCred)
}
func (self *SWafRule) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafRuleDeleteTask", self, userCred, nil, "", "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_RULE_STATUS_DELETING, "")
return task.ScheduleRun(nil)
}
func (self *SWafRule) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
return nil
}
func (self *SWafRule) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
statements, err := self.GetRuleStatements()
if err != nil {
return errors.Wrapf(err, "GetRuleStatements")
}
for i := range statements {
err = statements[i].Delete(ctx, userCred)
if err != nil {
return errors.Wrapf(err, "Delete statement %s(%s)", statements[i].Type, statements[i].MatchField)
}
}
return self.SStatusStandaloneResourceBase.Delete(ctx, userCred)
}
func (self *SWafRule) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
return self.RealDelete(ctx, userCred)
}
func (self *SWafRule) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WafRuleUpdateInput) (api.WafRuleUpdateInput, error) {
var err error
if len(input.Name) > 0 && input.Name != self.Name {
return input, httperrors.NewInputParameterError("Not allow update rule name")
}
input.StatusStandaloneResourceBaseUpdateInput, err = self.SStatusStandaloneResourceBase.ValidateUpdateData(ctx, userCred, query, input.StatusStandaloneResourceBaseUpdateInput)
if err != nil {
return input, err
}
return input, nil
}
func (self *SWafRule) PostUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) {
self.SStatusStandaloneResourceBase.PostUpdate(ctx, userCred, query, data)
input := api.WafRuleUpdateInput{}
data.Unmarshal(&input)
statements, err := self.GetRuleStatements()
if err != nil {
return
}
for i := len(input.Statements); i < len(statements); i++ {
statements[i].Delete(ctx, userCred)
}
for i := len(statements); i < len(input.Statements); i++ {
statement := &SWafRuleStatement{}
statement.SetModelManager(WafRuleStatementManager, statement)
statement.SWafStatement = input.Statements[i]
statement.WafRuleId = self.Id
WafRuleStatementManager.TableSpec().Insert(ctx, statement)
}
for i := 0; i < len(input.Statements) && i < len(statements); i++ {
db.Update(&statements[i], func() error {
statements[i].SWafStatement = input.Statements[i]
return nil
})
}
self.StartUpdateTask(ctx, userCred, "")
}
func (self *SWafRule) StartUpdateTask(ctx context.Context, userCred mcclient.TokenCredential, parentTaskId string) error {
task, err := taskman.TaskManager.NewTask(ctx, "WafRuleUpdateTask", self, userCred, nil, parentTaskId, "", nil)
if err != nil {
return errors.Wrapf(err, "NewTask")
}
self.SetStatus(userCred, api.WAF_RULE_STATUS_UPDATING, "")
return task.ScheduleRun(nil)
}
func (self *SWafRule) SyncWithCloudRule(ctx context.Context, userCred mcclient.TokenCredential, rule cloudprovider.ICloudWafRule) error {
_, err := db.Update(self, func() error {
self.Action = rule.GetAction()
self.StatementConditon = rule.GetStatementCondition()
self.Priority = rule.GetPriority()
self.Status = api.WAF_RULE_STATUS_AVAILABLE
self.Name = rule.GetName()
self.ExternalId = rule.GetGlobalId()
return nil
})
if err != nil {
return errors.Wrapf(err, "db.Update")
}
return self.SyncStatements(ctx, userCred, rule)
}
func (self *SWafInstance) newFromCloudRule(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudWafRule) error {
rule := &SWafRule{}
rule.SetModelManager(WafRuleManager, rule)
rule.WafInstanceId = self.Id
rule.Name = ext.GetName()
rule.Description = ext.GetDesc()
rule.ExternalId = ext.GetGlobalId()
rule.Action = ext.GetAction()
rule.StatementConditon = ext.GetStatementCondition()
rule.Priority = ext.GetPriority()
rule.Status = api.WAF_RULE_STATUS_AVAILABLE
err := WafRuleManager.TableSpec().Insert(ctx, rule)
if err != nil {
return errors.Wrapf(err, "Insert")
}
return rule.SyncStatements(ctx, userCred, ext)
}
func (self *SWafInstance) SyncWafRules(ctx context.Context, userCred mcclient.TokenCredential, exts []cloudprovider.ICloudWafRule) compare.SyncResult {
lockman.LockRawObject(ctx, WafInstanceManager.Keyword(), self.Id)
defer lockman.ReleaseRawObject(ctx, WafInstanceManager.Keyword(), self.Id)
result := compare.SyncResult{}
dbRules, err := self.GetWafRules()
if err != nil {
result.Error(err)
return result
}
removed := make([]SWafRule, 0)
commondb := make([]SWafRule, 0)
commonext := make([]cloudprovider.ICloudWafRule, 0)
added := make([]cloudprovider.ICloudWafRule, 0)
if err := compare.CompareSets(dbRules, exts, &removed, &commondb, &commonext, &added); err != nil {
result.Error(err)
return result
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(commondb); i++ {
err := commondb[i].SyncWithCloudRule(ctx, userCred, commonext[i])
if err != nil {
result.UpdateError(err)
continue
}
result.Update()
}
for i := 0; i < len(added); i++ {
err := self.newFromCloudRule(ctx, userCred, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result
}
func (self *SWafRuleGroup) GetWafRules() ([]SWafRule, error) {
q := WafRuleManager.Query().Equals("waf_rule_group_id", self.Id)
rules := []SWafRule{}
err := db.FetchModelObjects(WafRuleManager, q, &rules)
return rules, err
}
func (self *SWafRuleGroup) newFromManagedRule(ctx context.Context, userCred mcclient.TokenCredential, ext SWafRule) error {
ext.SetModelManager(WafRuleManager, &ext)
ext.WafRuleGroupId = self.Id
return WafRuleManager.TableSpec().Insert(ctx, &ext)
}
func (self *SWafRuleGroup) SyncManagedWafRules(ctx context.Context, userCred mcclient.TokenCredential, exts []SWafRule) (compare.SyncResult, error) {
lockman.LockRawObject(ctx, WafRuleGroupManager.Keyword(), self.Id)
defer lockman.ReleaseRawObject(ctx, WafRuleGroupManager.Keyword(), self.Id)
result := compare.SyncResult{}
dbRules, err := self.GetWafRules()
if err != nil {
return result, errors.Wrapf(err, "GetWafRules")
}
removed := make([]SWafRule, 0)
commondb := make([]SWafRule, 0)
commonext := make([]SWafRule, 0)
added := make([]SWafRule, 0)
err = compare.CompareSets(dbRules, exts, &removed, &commondb, &commonext, &added)
if err != nil {
return result, errors.Wrapf(err, "compare.CompareSets")
}
for i := 0; i < len(removed); i++ {
err := removed[i].syncRemove(ctx, userCred)
if err != nil {
result.DeleteError(err)
continue
}
result.Delete()
}
for i := 0; i < len(added); i++ {
err := self.newFromManagedRule(ctx, userCred, added[i])
if err != nil {
result.AddError(err)
continue
}
result.Add()
}
return result, nil
}
func (self *SWafRule) GetICloudWafInstance() (cloudprovider.ICloudWafInstance, error) {
ins, err := self.GetWafInstance()
if err != nil {
return nil, errors.Wrapf(err, "GetWafInstance")
}
iWaf, err := ins.GetICloudWafInstance()
if err != nil {
return nil, errors.Wrapf(err, "GetICloudWafInstance")
}
return iWaf, nil
}
func (self *SWafRule) GetICloudWafRule() (cloudprovider.ICloudWafRule, error) {
if len(self.ExternalId) == 0 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
}
if len(self.WafInstanceId) > 0 {
iWaf, err := self.GetICloudWafInstance()
if err != nil {
return nil, errors.Wrapf(err, "GetICloudWafInstance")
}
rules, err := iWaf.GetRules()
if err != nil {
return nil, errors.Wrapf(err, "GetWafRules")
}
for i := range rules {
if rules[i].GetGlobalId() == self.ExternalId {
return rules[i], nil
}
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, self.ExternalId)
}
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "")
}
func (self *SWafRule) AllowPerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
ins, _ := self.GetWafInstance()
if ins != nil {
return ins.IsOwner(userCred) || db.IsDomainAllowPerform(userCred, self, "syncstatus")
}
return db.IsDomainAllowPerform(userCred, self, "syncstatus")
}
// 同步WAF规则状态
func (self *SWafRule) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WafSyncstatusInput) (jsonutils.JSONObject, error) {
return nil, StartResourceSyncStatusTask(ctx, userCred, self, "WafRuleSyncstatusTask", "")
}
+12
View File
@@ -162,6 +162,18 @@ var (
Extra: []string{"saml"},
Result: rbacutils.Allow,
},
{
Service: api.SERVICE_TYPE,
Resource: "waf_rules",
Action: PolicyActionGet,
Result: rbacutils.Allow,
},
{
Service: api.SERVICE_TYPE,
Resource: "waf_rules",
Action: PolicyActionList,
Result: rbacutils.Allow,
},
},
},
{
+5
View File
@@ -59,6 +59,11 @@ var (
"proxysettings",
"project_mappings",
"app_gateways",
"waf_instances",
"waf_rules",
"waf_rule_groups",
"waf_ipsets",
"waf_regexsets",
}
computeUserResources = []string{
"keypairs",
+16
View File
@@ -25,6 +25,7 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/regutils"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
@@ -1530,3 +1531,18 @@ func (self *SAliyunRegionDriver) RequestSyncAccessGroup(ctx context.Context, use
})
return nil
}
func (self *SAliyunRegionDriver) ValidateCreateWafInstanceData(ctx context.Context, userCred mcclient.TokenCredential, input api.WafInstanceCreateInput) (api.WafInstanceCreateInput, error) {
if !regutils.DOMAINNAME_REG.MatchString(input.Name) {
return input, httperrors.NewInputParameterError("invalid domain name %s", input.Name)
}
input.Type = cloudprovider.WafTypeDefault
if len(input.SourceIps) == 0 && len(input.CloudResources) == 0 {
return input, httperrors.NewMissingParameterError("source_ips")
}
return input, nil
}
func (self *SAliyunRegionDriver) ValidateCreateWafRuleData(ctx context.Context, userCred mcclient.TokenCredential, waf *models.SWafInstance, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error) {
return input, httperrors.NewUnsupportOperationError("not supported create rule")
}
+30
View File
@@ -1559,3 +1559,33 @@ func (self *SAwsRegionDriver) RequestAssociateEip(ctx context.Context, userCred
})
return nil
}
func (self *SAwsRegionDriver) ValidateCreateWafInstanceData(ctx context.Context, userCred mcclient.TokenCredential, input api.WafInstanceCreateInput) (api.WafInstanceCreateInput, error) {
if len(input.Type) == 0 {
input.Type = cloudprovider.WafTypeRegional
}
switch input.Type {
case cloudprovider.WafTypeRegional:
case cloudprovider.WafTypeCloudFront:
_region, err := models.CloudregionManager.FetchById(input.CloudregionId)
if err != nil {
return input, err
}
region := _region.(*models.SCloudregion)
if !strings.HasSuffix(region.ExternalId, "us-east-1") {
return input, httperrors.NewUnsupportOperationError("only us-east-1 support %s", input.Type)
}
default:
return input, httperrors.NewInputParameterError("Invalid aws waf type %s", input.Type)
}
if input.DefaultAction == nil {
input.DefaultAction = &cloudprovider.DefaultAction{
Action: cloudprovider.WafActionAllow,
}
}
return input, nil
}
func (self *SAwsRegionDriver) ValidateCreateWafRuleData(ctx context.Context, userCred mcclient.TokenCredential, waf *models.SWafInstance, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error) {
return input, nil
}
+28
View File
@@ -83,3 +83,31 @@ func (self *SAzureRegionDriver) ValidateCreateVpcData(ctx context.Context, userC
}
return input, nil
}
func (self *SAzureRegionDriver) ValidateCreateWafInstanceData(ctx context.Context, userCred mcclient.TokenCredential, input api.WafInstanceCreateInput) (api.WafInstanceCreateInput, error) {
if len(input.Type) == 0 {
input.Type = cloudprovider.WafTypeAppGateway
}
switch input.Type {
case cloudprovider.WafTypeAppGateway:
default:
return input, httperrors.NewInputParameterError("Invalid azure waf type %s", input.Type)
}
if input.DefaultAction == nil {
input.DefaultAction = &cloudprovider.DefaultAction{}
}
if len(input.DefaultAction.Action) == 0 {
input.DefaultAction.Action = cloudprovider.WafActionDetection
}
switch input.DefaultAction.Action {
case cloudprovider.WafActionPrevention:
case cloudprovider.WafActionDetection:
default:
return input, httperrors.NewInputParameterError("invalid default action %s", input.DefaultAction.Action)
}
return input, nil
}
func (self *SAzureRegionDriver) ValidateCreateWafRuleData(ctx context.Context, userCred mcclient.TokenCredential, waf *models.SWafInstance, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error) {
return input, nil
}
+8
View File
@@ -451,3 +451,11 @@ func (self *SBaseRegionDriver) RequestAssociatEip(ctx context.Context, userCred
func (self *SBaseRegionDriver) RequestSyncAccessGroup(ctx context.Context, userCred mcclient.TokenCredential, fs *models.SFileSystem, mt *models.SMountTarget, ag *models.SAccessGroup, task taskman.ITask) error {
return errors.Wrapf(cloudprovider.ErrNotImplemented, "RequestSyncAccessGroup")
}
func (self *SBaseRegionDriver) ValidateCreateWafInstanceData(ctx context.Context, userCred mcclient.TokenCredential, input api.WafInstanceCreateInput) (api.WafInstanceCreateInput, error) {
return input, errors.Wrapf(cloudprovider.ErrNotImplemented, "ValidateCreateWafInstanceData")
}
func (self *SBaseRegionDriver) ValidateCreateWafRuleData(ctx context.Context, userCred mcclient.TokenCredential, waf *models.SWafInstance, input api.WafRuleCreateInput) (api.WafRuleCreateInput, error) {
return input, errors.Wrapf(cloudprovider.ErrNotImplemented, "ValidateCreateWafRuleData")
}
+10
View File
@@ -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)
+1
View File
@@ -152,6 +152,7 @@ func StartService() {
cron.AddJobEveryFewHour("SnapshotsCleanup", 1, 35, 0, models.SnapshotManager.CleanupSnapshots, false)
cron.AddJobAtIntervalsWithStartRun("SyncSkus", time.Duration(opts.ServerSkuSyncIntervalMinutes)*time.Minute, models.SyncServerSkus, true)
cron.AddJobAtIntervalsWithStartRun("SyncManagedWafGroups", time.Duration(opts.ServerSkuSyncIntervalMinutes)*time.Minute, models.SyncWafGroups, true)
cron.AddJobEveryFewDays("SyncDBInstanceSkus", opts.SyncSkusDay, opts.SyncSkusHour, 0, 0, models.SyncDBInstanceSkus, true)
cron.AddJobEveryFewDays("SyncNatSkus", opts.SyncSkusDay, opts.SyncSkusHour, 0, 0, models.SyncNatSkus, false)
+77
View File
@@ -0,0 +1,77 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafCreateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafCreateTask{})
}
func (self *WafCreateTask) taskFailed(ctx context.Context, waf *models.SWafInstance, err error) {
waf.SetStatus(self.UserCred, api.WAF_STATUS_CREATE_FAILED, err.Error())
db.OpsLog.LogEvent(waf, db.ACT_ALLOCATE_FAIL, err, self.UserCred)
logclient.AddActionLogWithStartable(self, waf, logclient.ACT_ALLOCATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
waf := obj.(*models.SWafInstance)
iRegion, err := waf.GetIRegion()
if err != nil {
self.taskFailed(ctx, waf, errors.Wrapf(err, "GetIRegion"))
return
}
params := api.WafInstanceCreateInput{}
self.GetParams().Unmarshal(&params)
opts := &cloudprovider.WafCreateOptions{
Name: waf.Name,
Desc: waf.Description,
Type: waf.Type,
DefaultAction: waf.DefaultAction,
CloudResources: params.CloudResources,
SourceIps: params.SourceIps,
}
iWaf, err := iRegion.CreateICloudWafInstance(opts)
if err != nil {
self.taskFailed(ctx, waf, errors.Wrapf(err, "CreateICloudWafInstance"))
return
}
cloudprovider.WaitStatus(iWaf, api.WAF_STATUS_AVAILABLE, time.Second*5, time.Minute*5)
waf.SyncWithCloudWafInstance(ctx, self.GetUserCred(), iWaf)
rules, err := iWaf.GetRules()
if err == nil {
waf.SyncWafRules(ctx, self.GetUserCred(), rules)
}
self.SetStageComplete(ctx, nil)
}
+73
View File
@@ -0,0 +1,73 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafDeleteTask{})
}
func (self *WafDeleteTask) taskFailed(ctx context.Context, waf *models.SWafInstance, err error) {
waf.SetStatus(self.UserCred, api.WAF_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, waf, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
waf := obj.(*models.SWafInstance)
iWaf, err := waf.GetICloudWafInstance()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
self.taskComplete(ctx, waf)
return
}
self.taskFailed(ctx, waf, errors.Wrapf(err, "GetICloudWafInstance"))
return
}
err = iWaf.Delete()
if err != nil {
self.taskFailed(ctx, waf, errors.Wrapf(err, "iWaf.Delete"))
return
}
err = cloudprovider.WaitDeleted(iWaf, time.Second*5, time.Minute*5)
if err != nil {
self.taskFailed(ctx, waf, errors.Wrapf(err, "WaitDeleted"))
return
}
self.taskComplete(ctx, waf)
}
func (self *WafDeleteTask) taskComplete(ctx context.Context, waf *models.SWafInstance) {
waf.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,67 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafIPSetCacheDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafIPSetCacheDeleteTask{})
}
func (self *WafIPSetCacheDeleteTask) taskFailed(ctx context.Context, cache *models.SWafIPSetCache, err error) {
cache.SetStatus(self.UserCred, api.WAF_IPSET_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, cache, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafIPSetCacheDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
cache := obj.(*models.SWafIPSetCache)
iCache, err := cache.GetICloudWafIPSet()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
self.taskComplete(ctx, cache)
return
}
self.taskFailed(ctx, cache, errors.Wrapf(err, "GetICloudWafIPSet"))
return
}
err = iCache.Delete()
if err != nil {
self.taskFailed(ctx, cache, errors.Wrapf(err, "iCache.Delete"))
return
}
self.taskComplete(ctx, cache)
}
func (self *WafIPSetCacheDeleteTask) taskComplete(ctx context.Context, cache *models.SWafIPSetCache) {
cache.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,75 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafIPSetDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafIPSetDeleteTask{})
}
func (self *WafIPSetDeleteTask) taskFailed(ctx context.Context, ipset *models.SWafIPSet, err error) {
ipset.SetStatus(self.UserCred, api.WAF_IPSET_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, ipset, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafIPSetDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
ipset := obj.(*models.SWafIPSet)
caches, err := ipset.GetCaches()
if err != nil {
self.taskFailed(ctx, ipset, errors.Wrapf(err, "GetCaches"))
return
}
for i := range caches {
iCache, err := caches[i].GetICloudWafIPSet()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
caches[i].RealDelete(ctx, self.GetUserCred())
continue
}
self.taskFailed(ctx, ipset, errors.Wrapf(err, "GetICloudWafIPSet"))
return
}
err = iCache.Delete()
if err != nil {
self.taskFailed(ctx, ipset, errors.Wrapf(err, "iCache.Delete"))
return
}
caches[i].RealDelete(ctx, self.GetUserCred())
}
self.taskComplete(ctx, ipset)
}
func (self *WafIPSetDeleteTask) taskComplete(ctx context.Context, ipset *models.SWafIPSet) {
ipset.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,67 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafRegexSetCacheDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafRegexSetCacheDeleteTask{})
}
func (self *WafRegexSetCacheDeleteTask) taskFailed(ctx context.Context, cache *models.SWafRegexSetCache, err error) {
cache.SetStatus(self.UserCred, api.WAF_REGEX_SET_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, cache, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafRegexSetCacheDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
cache := obj.(*models.SWafRegexSetCache)
iCache, err := cache.GetICloudWafRegexSet()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
self.taskComplete(ctx, cache)
return
}
self.taskFailed(ctx, cache, errors.Wrapf(err, "GetICloudWafRegexSet"))
return
}
err = iCache.Delete()
if err != nil {
self.taskFailed(ctx, cache, errors.Wrapf(err, "iCache.Delete"))
return
}
self.taskComplete(ctx, cache)
}
func (self *WafRegexSetCacheDeleteTask) taskComplete(ctx context.Context, cache *models.SWafRegexSetCache) {
cache.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,75 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafRegexSetDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafRegexSetDeleteTask{})
}
func (self *WafRegexSetDeleteTask) taskFailed(ctx context.Context, regexset *models.SWafRegexSet, err error) {
regexset.SetStatus(self.UserCred, api.WAF_REGEX_SET_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, regexset, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafRegexSetDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
regexset := obj.(*models.SWafRegexSet)
caches, err := regexset.GetCaches()
if err != nil {
self.taskFailed(ctx, regexset, errors.Wrapf(err, "GetCaches"))
return
}
for i := range caches {
iCache, err := caches[i].GetICloudWafRegexSet()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
caches[i].RealDelete(ctx, self.GetUserCred())
continue
}
self.taskFailed(ctx, regexset, errors.Wrapf(err, "GetICloudWafRegexSet"))
return
}
err = iCache.Delete()
if err != nil {
self.taskFailed(ctx, regexset, errors.Wrapf(err, "iCache.Delete"))
return
}
caches[i].RealDelete(ctx, self.GetUserCred())
}
self.taskComplete(ctx, regexset)
}
func (self *WafRegexSetDeleteTask) taskComplete(ctx context.Context, regexset *models.SWafRegexSet) {
regexset.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
+79
View File
@@ -0,0 +1,79 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafRuleCreateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafRuleCreateTask{})
}
func (self *WafRuleCreateTask) taskFailed(ctx context.Context, rule *models.SWafRule, err error) {
rule.SetStatus(self.UserCred, api.WAF_RULE_STATUS_CREATE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, rule, logclient.ACT_ALLOCATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafRuleCreateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
rule := obj.(*models.SWafRule)
iWaf, err := rule.GetICloudWafInstance()
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "GetICloudWafInstance"))
return
}
opts := cloudprovider.SWafRule{
Name: rule.Name,
Desc: rule.Description,
Action: rule.Action,
Priority: rule.Priority,
Statements: []cloudprovider.SWafStatement{},
}
opts.StatementCondition = rule.StatementConditon
statements, err := rule.GetRuleStatements()
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "GetRuleStatements"))
return
}
for i := range statements {
opts.Statements = append(opts.Statements, statements[i].SWafStatement)
}
iRule, err := iWaf.AddRule(&opts)
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "iWaf.AddRule"))
return
}
rule.SyncWithCloudRule(ctx, self.GetUserCred(), iRule)
self.taskComplete(ctx, rule)
}
func (self *WafRuleCreateTask) taskComplete(ctx context.Context, rule *models.SWafRule) {
self.SetStageComplete(ctx, nil)
}
+67
View File
@@ -0,0 +1,67 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafRuleDeleteTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafRuleDeleteTask{})
}
func (self *WafRuleDeleteTask) taskFailed(ctx context.Context, rule *models.SWafRule, err error) {
rule.SetStatus(self.UserCred, api.WAF_RULE_STATUS_DELETE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, rule, logclient.ACT_DELETE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafRuleDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
rule := obj.(*models.SWafRule)
iRule, err := rule.GetICloudWafRule()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
self.taskComplete(ctx, rule)
return
}
self.taskFailed(ctx, rule, errors.Wrapf(err, "GetICloudWafRule"))
return
}
err = iRule.Delete()
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "iRule.Delete"))
return
}
self.taskComplete(ctx, rule)
}
func (self *WafRuleDeleteTask) taskComplete(ctx context.Context, rule *models.SWafRule) {
rule.RealDelete(ctx, self.GetUserCred())
self.SetStageComplete(ctx, nil)
}
@@ -0,0 +1,55 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafRuleSyncstatusTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafRuleSyncstatusTask{})
}
func (self *WafRuleSyncstatusTask) taskFailed(ctx context.Context, rule *models.SWafRule, err error) {
rule.SetStatus(self.UserCred, api.WAF_RULE_STATUS_UNKNOWN, err.Error())
logclient.AddActionLogWithStartable(self, rule, logclient.ACT_SYNC_STATUS, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafRuleSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
rule := obj.(*models.SWafRule)
iRule, err := rule.GetICloudWafRule()
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "GetICloudWafRule"))
return
}
rule.SyncWithCloudRule(ctx, self.GetUserCred(), iRule)
self.SetStageComplete(ctx, nil)
}
+84
View File
@@ -0,0 +1,84 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafRuleUpdateTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafRuleUpdateTask{})
}
func (self *WafRuleUpdateTask) taskFailed(ctx context.Context, rule *models.SWafRule, err error) {
rule.SetStatus(self.UserCred, api.WAF_RULE_STATUS_UPDATE_FAILED, err.Error())
logclient.AddActionLogWithStartable(self, rule, logclient.ACT_UPDATE, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafRuleUpdateTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
rule := obj.(*models.SWafRule)
iRule, err := rule.GetICloudWafRule()
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "GetICloudWafRule"))
return
}
opts := cloudprovider.SWafRule{
Name: rule.Name,
Desc: rule.Description,
Action: rule.Action,
Priority: rule.Priority,
Statements: []cloudprovider.SWafStatement{},
}
opts.StatementCondition = rule.StatementConditon
statements, err := rule.GetRuleStatements()
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "GetRuleStatements"))
return
}
for i := range statements {
opts.Statements = append(opts.Statements, statements[i].SWafStatement)
}
err = iRule.Update(&opts)
if err != nil {
self.taskFailed(ctx, rule, errors.Wrapf(err, "iRule.Update"))
return
}
self.taskComplete(ctx, rule)
}
func (self *WafRuleUpdateTask) taskComplete(ctx context.Context, rule *models.SWafRule) {
rule.SetStatus(self.UserCred, api.WAF_RULE_STATUS_AVAILABLE, "")
self.SetStageComplete(ctx, nil)
}
+59
View File
@@ -0,0 +1,59 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package tasks
import (
"context"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudcommon/db"
"yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
"yunion.io/x/onecloud/pkg/compute/models"
"yunion.io/x/onecloud/pkg/util/logclient"
)
type WafSyncstatusTask struct {
taskman.STask
}
func init() {
taskman.RegisterTask(WafSyncstatusTask{})
}
func (self *WafSyncstatusTask) taskFailed(ctx context.Context, waf *models.SWafInstance, err error) {
waf.SetStatus(self.UserCred, api.WAF_STATUS_UNKNOWN, err.Error())
logclient.AddActionLogWithStartable(self, waf, logclient.ACT_SYNC_STATUS, err, self.UserCred, false)
self.SetStageFailed(ctx, jsonutils.NewString(err.Error()))
}
func (self *WafSyncstatusTask) OnInit(ctx context.Context, obj db.IStandaloneModel, body jsonutils.JSONObject) {
waf := obj.(*models.SWafInstance)
iWaf, err := waf.GetICloudWafInstance()
if err != nil {
self.taskFailed(ctx, waf, errors.Wrapf(err, "GetICloudWafInstance"))
return
}
waf.SyncWithCloudWafInstance(ctx, self.GetUserCred(), iWaf)
rules, err := iWaf.GetRules()
if err == nil {
result := waf.SyncWafRules(ctx, self.GetUserCred(), rules)
log.Infof("Sync waf %s rules result: %s", waf.Name, result.Result())
}
self.SetStageComplete(ctx, nil)
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
WafInstances modulebase.ResourceManager
)
func init() {
WafInstances = NewComputeManager("waf_instance", "waf_instances",
[]string{"ID", "Name", "Enabled", "Status", "Cloudregion_Id", "Region", "Rules", "Public_Scope", "Domain_Id", "Domain", "Metadata"},
[]string{})
registerCompute(&WafInstances)
}
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
WafIPSetCaches modulebase.ResourceManager
)
func init() {
WafIPSetCaches = NewComputeManager("waf_ipset_cache", "waf_ipset_caches",
[]string{"ID", "Name", "Status", "Cloudregion", "Provider", "Account", "Type", "Domain_Id", "Domain", "Metadata"},
[]string{})
registerCompute(&WafIPSetCaches)
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
WafIPSets modulebase.ResourceManager
)
func init() {
WafIPSets = NewComputeManager("waf_ipset", "waf_ipsets",
[]string{"ID", "Name", "Status", "Addresses", "Domain_Id", "Domain", "Metadata"},
[]string{})
registerCompute(&WafIPSets)
}
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
WafRegexSetCaches modulebase.ResourceManager
)
func init() {
WafRegexSetCaches = NewComputeManager("waf_regexset_cache", "waf_regexset_caches",
[]string{"ID", "Name", "Status", "Cloudregion", "Provider", "Account", "Type", "Domain_Id", "Domain", "Metadata"},
[]string{})
registerCompute(&WafRegexSetCaches)
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
WafRegexSets modulebase.ResourceManager
)
func init() {
WafRegexSets = NewComputeManager("waf_regexset", "waf_regexsets",
[]string{"ID", "Name", "Status", "Addresses", "Domain_Id", "Domain", "Metadata"},
[]string{})
registerCompute(&WafRegexSets)
}
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
WafRuleGroups modulebase.ResourceManager
)
func init() {
WafRuleGroups = NewComputeManager("waf_rule_group", "waf_rule_groups",
[]string{"ID", "Name", "Status", "Domain_Id", "Domain", "Is_System", "Rules"},
[]string{})
registerCompute(&WafRuleGroups)
}
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package modules
import "yunion.io/x/onecloud/pkg/mcclient/modulebase"
var (
WafRules modulebase.ResourceManager
)
func init() {
WafRules = NewComputeManager("waf_rule", "waf_rules",
[]string{"ID", "Name", "Status", "Priority", "Action", "Statement_Condition", "Statements"},
[]string{})
registerCompute(&WafRules)
}
@@ -0,0 +1,40 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type WafInstanceListOptions struct {
options.BaseListOptions
}
func (opts *WafInstanceListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
type WafInstanceCreateOptions struct {
options.BaseCreateOptions
CloudregionId string
CloudproviderId string
SourceIps []string
}
func (opts *WafInstanceCreateOptions) Params() (jsonutils.JSONObject, error) {
return jsonutils.Marshal(opts), nil
}
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type WafIPSetListOptions struct {
options.BaseListOptions
}
func (opts *WafIPSetListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
type WafIPSetCacheListOptions struct {
options.BaseListOptions
}
func (opts *WafIPSetCacheListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
@@ -0,0 +1,37 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type WafRegexSetListOptions struct {
options.BaseListOptions
}
func (opts *WafRegexSetListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
type WafRegexSetCacheListOptions struct {
options.BaseListOptions
}
func (opts *WafRegexSetCacheListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
@@ -0,0 +1,39 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type WafRuleGroupListOptions struct {
options.BaseListOptions
IsSystem bool
}
func (opts *WafRuleGroupListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
type WafRuleGroupCacheListOptions struct {
options.BaseListOptions
}
func (opts *WafRuleGroupCacheListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
+60
View File
@@ -0,0 +1,60 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package compute
import (
"io/ioutil"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/mcclient/options"
)
type WafRuleListOptions struct {
options.BaseListOptions
WafInstanceId string
WafRuleGroupId string
}
func (opts *WafRuleListOptions) Params() (jsonutils.JSONObject, error) {
return options.ListStructToParams(opts)
}
type WafRuleOptions struct {
RULE_FILE string
}
func (opts *WafRuleOptions) Params() (jsonutils.JSONObject, error) {
data, err := ioutil.ReadFile(opts.RULE_FILE)
if err != nil {
return nil, errors.Wrapf(err, "ioutils.ReadFile")
}
ret, err := jsonutils.Parse(data)
if err != nil {
return nil, err
}
return ret, nil
}
type WafRuleUpdateOptions struct {
options.BaseIdOptions
WafRuleOptions
}
func (opts *WafRuleUpdateOptions) Params() (jsonutils.JSONObject, error) {
return opts.WafRuleOptions.Params()
}
+6 -1
View File
@@ -65,6 +65,7 @@ const (
ALIYUN_CDN_API_VERSION = "2018-05-10"
ALIYUN_IMS_API_VERSION = "2019-08-15"
ALIYUN_NAS_API_VERSION = "2017-06-26"
ALIYUN_WAF_API_VERSION = "2019-09-10"
ALIYUN_SERVICE_ECS = "ecs"
ALIYUN_SERVICE_VPC = "vpc"
@@ -179,7 +180,10 @@ func jsonRequest(client *sdk.Client, domain, apiVersion, apiName string, params
"OperationUnsupported.EipNatBWPCheck": // create nat snat
retry = true
default:
if strings.HasPrefix(code, "EntityNotExist.") || strings.HasSuffix(code, ".NotFound") {
if strings.HasPrefix(code, "EntityNotExist.") || strings.HasSuffix(code, ".NotFound") || strings.HasSuffix(code, "NotExist") {
if strings.HasPrefix(apiName, "Delete") {
return jsonutils.NewDict(), nil
}
return nil, errors.Wrap(cloudprovider.ErrNotFound, err.Error())
}
return nil, err
@@ -639,6 +643,7 @@ func (region *SAliyunClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_SAML_AUTH,
cloudprovider.CLOUD_CAPABILITY_NAT,
cloudprovider.CLOUD_CAPABILITY_NAS,
cloudprovider.CLOUD_CAPABILITY_WAF,
}
return caps
}
+12
View File
@@ -136,6 +136,18 @@ func (self *SRegion) ecsRequest(apiName string, params map[string]string) (jsonu
return jsonRequest(client, endpoint, ALIYUN_API_VERSION, apiName, params, self.client.debug)
}
func (self *SRegion) wafRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
client, err := self.getSdkClient()
if err != nil {
return nil, err
}
if self.RegionId != "cn-hangzhou" && self.RegionId != "ap-southeast-1" {
return nil, cloudprovider.ErrNotSupported
}
endpoint := fmt.Sprintf("wafopenapi.%s.aliyuncs.com", self.RegionId)
return jsonRequest(client, endpoint, ALIYUN_WAF_API_VERSION, apiName, params, self.client.debug)
}
func (self *SRegion) rdsRequest(apiName string, params map[string]string) (jsonutils.JSONObject, error) {
client, err := self.getSdkClient()
if err != nil {
+73
View File
@@ -0,0 +1,73 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package shell
import (
"fmt"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/multicloud/aliyun"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type WafShowOptions struct {
}
shellutils.R(&WafShowOptions{}, "waf-instance-show", "Show waf instance", func(cli *aliyun.SRegion, args *WafShowOptions) error {
waf, err := cli.DescribeInstanceSpecInfo()
if err != nil {
return err
}
printObject(waf)
return nil
})
type WafIdOptions struct {
ID string
}
shellutils.R(&WafIdOptions{}, "waf-instance-delete", "Delete waf instance", func(cli *aliyun.SRegion, args *WafIdOptions) error {
return cli.DeleteInstance(args.ID)
})
shellutils.R(&WafIdOptions{}, "waf-domain-list", "List waf instance domains", func(cli *aliyun.SRegion, args *WafIdOptions) error {
domains, err := cli.DescribeDomainNames(args.ID)
if err != nil {
return errors.Wrapf(err, "DescribeDomainNames")
}
fmt.Println("domains: ", domains)
return nil
})
type WafDomainIdOptions struct {
ID string
DOMAIN string
}
shellutils.R(&WafDomainIdOptions{}, "waf-domain-show", "Show waf domain", func(cli *aliyun.SRegion, args *WafDomainIdOptions) error {
domain, err := cli.DescribeDomain(args.ID, args.DOMAIN)
if err != nil {
return err
}
printObject(domain)
return nil
})
shellutils.R(&WafDomainIdOptions{}, "waf-domain-delete", "Delete waf domain", func(cli *aliyun.SRegion, args *WafDomainIdOptions) error {
return cli.DeleteDomain(args.ID, args.DOMAIN)
})
}
+61
View File
@@ -0,0 +1,61 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aliyun
import (
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SInstanceSpecs struct {
Code int
Value bool
}
type SWafInstance struct {
Version string
InstanceSpecInfos []SInstanceSpecs
InstanceId string
ExpireTime uint64
}
func (self *SRegion) DescribeInstanceSpecInfo() (*SWafInstance, error) {
params := map[string]string{
"RegionId": self.RegionId,
}
resp, err := self.wafRequest("DescribeInstanceSpecInfo", params)
if err != nil {
return nil, errors.Wrapf(err, "DescribeInstanceSpecInfo")
}
ret := &SWafInstance{}
err = resp.Unmarshal(&ret)
if err != nil {
return nil, errors.Wrapf(err, "resp.Unmarshal")
}
if len(ret.InstanceId) == 0 {
return nil, cloudprovider.ErrNotFound
}
return ret, nil
}
func (self *SRegion) DeleteInstance(id string) error {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": id,
}
_, err := self.wafRequest("DeleteInstance", params)
return errors.Wrapf(err, "DeleteInstance")
}
+502
View File
@@ -0,0 +1,502 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aliyun
import (
"fmt"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
type SWafDomain struct {
multicloud.SResourceBase
multicloud.AliyunTags
region *SRegion
insId string
name string
Httptouserip int `json:"HttpToUserIp"`
Httpport []int `json:"HttpPort"`
Isaccessproduct int `json:"IsAccessProduct"`
Resourcegroupid string `json:"ResourceGroupId"`
Readtime int `json:"ReadTime"`
Sourceips []string `json:"SourceIps"`
Ipfollowstatus int `json:"IpFollowStatus"`
Clustertype int `json:"ClusterType"`
Loadbalancing int `json:"LoadBalancing"`
Cname string `json:"Cname"`
Writetime int `json:"WriteTime"`
HTTP2Port []interface{} `json:"Http2Port"`
Version int `json:"Version"`
Httpsredirect int `json:"HttpsRedirect"`
Connectiontime int `json:"ConnectionTime"`
Accesstype string `json:"AccessType"`
Httpsport []interface{} `json:"HttpsPort"`
}
func (self *SRegion) DescribeDomain(id, domain string) (*SWafDomain, error) {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": id,
"Domain": domain,
}
resp, err := self.wafRequest("DescribeDomain", params)
if err != nil {
return nil, errors.Wrapf(err, "DescribeDomain")
}
ret := &SWafDomain{region: self, name: domain, insId: id}
err = resp.Unmarshal(ret, "Domain")
if err != nil {
return nil, errors.Wrapf(err, "resp.Unmarshal")
}
return ret, nil
}
func (self *SRegion) DeleteDomain(id, domain string) error {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": id,
"Domain": domain,
}
_, err := self.wafRequest("DeleteDomain", params)
return errors.Wrapf(err, "DeleteDomain")
}
func (self *SRegion) DescribeDomainNames(id string) ([]string, error) {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": id,
}
resp, err := self.wafRequest("DescribeDomainNames", params)
if err != nil {
return nil, errors.Wrapf(err, "DescribeDomainNames")
}
domains := []string{}
err = resp.Unmarshal(&domains, "DomainNames")
return domains, errors.Wrapf(err, "resp.Unmarshal")
}
func (self *SRegion) SetDomainRuleGroup(insId, domain, ruleGroupId string) error {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": insId,
"Domains": domain,
"RuleGroupId": ruleGroupId,
}
_, err := self.wafRequest("SetDomainRuleGroup", params)
return err
}
func (self *SRegion) DescribeDomainRuleGroup(insId, domain string) (string, error) {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": insId,
"Domain": domain,
}
resp, err := self.wafRequest("DescribeDomainRuleGroup", params)
if err != nil {
return "", errors.Wrapf(err, "DescribeDomainRuleGroup")
}
return resp.GetString("RuleGroupId")
}
func (self *SRegion) GetICloudWafInstances() ([]cloudprovider.ICloudWafInstance, error) {
ins, err := self.DescribeInstanceSpecInfo()
if err != nil {
if errors.Cause(err) == cloudprovider.ErrNotFound {
return []cloudprovider.ICloudWafInstance{}, nil
}
return nil, errors.Wrapf(err, "DescribeInstanceSpecInfo")
}
domains, err := self.DescribeDomainNames(ins.InstanceId)
if err != nil {
return nil, errors.Wrapf(err, "DescribeDomainNames")
}
ret := []cloudprovider.ICloudWafInstance{}
for i := range domains {
domain, err := self.DescribeDomain(ins.InstanceId, domains[i])
if err != nil {
return nil, errors.Wrapf(err, "DescribeDomain %s", domains[i])
}
domain.region = self
domain.insId = ins.InstanceId
domain.name = domains[i]
ret = append(ret, domain)
}
return ret, nil
}
func (self *SRegion) GetICloudWafInstanceById(id string) (cloudprovider.ICloudWafInstance, error) {
ins, err := self.DescribeInstanceSpecInfo()
if err != nil {
return nil, errors.Wrapf(err, "DescribeInstanceSpecInfo")
}
return self.DescribeDomain(ins.InstanceId, id)
}
func (self *SWafDomain) GetId() string {
return self.name
}
func (self *SWafDomain) GetStatus() string {
return api.WAF_STATUS_AVAILABLE
}
func (self *SWafDomain) GetWafType() cloudprovider.TWafType {
return cloudprovider.WafTypeDefault
}
func (self *SWafDomain) GetEnabled() bool {
return true
}
func (self *SWafDomain) GetName() string {
return self.name
}
func (self *SWafDomain) GetGlobalId() string {
return self.name
}
func (self *SWafDomain) Delete() error {
return self.region.DeleteDomain(self.insId, self.name)
}
func (self *SWafDomain) GetDefaultAction() *cloudprovider.DefaultAction {
return &cloudprovider.DefaultAction{
Action: cloudprovider.WafActionAllow,
InsertHeaders: map[string]string{},
}
}
type ManagedRuleGroup struct {
waf *SWafDomain
insId string
domain string
ruleGroupId string
}
func (self *ManagedRuleGroup) GetName() string {
return "RuleGroup"
}
func (self *ManagedRuleGroup) GetDesc() string {
return "规则组"
}
func (self *ManagedRuleGroup) GetGlobalId() string {
return fmt.Sprintf("%s-%s", self.insId, self.domain)
}
func (self *ManagedRuleGroup) GetPriority() int {
return 0
}
func (self *ManagedRuleGroup) GetAction() *cloudprovider.DefaultAction {
return nil
}
func (self *ManagedRuleGroup) Delete() error {
return cloudprovider.ErrNotSupported
}
func (self *ManagedRuleGroup) Update(opts *cloudprovider.SWafRule) error {
for _, statement := range opts.Statements {
if len(statement.RuleGroupId) == 0 {
return self.waf.region.SetDomainRuleGroup(self.insId, self.domain, statement.RuleGroupId)
} else if len(statement.ManagedRuleGroupName) > 0 {
switch statement.ManagedRuleGroupName {
case "严格规则":
return self.waf.region.SetDomainRuleGroup(self.insId, self.domain, "1011")
case "中等规则":
return self.waf.region.SetDomainRuleGroup(self.insId, self.domain, "1012")
case "宽松规则":
return self.waf.region.SetDomainRuleGroup(self.insId, self.domain, "1013")
}
}
}
return nil
}
func (self *ManagedRuleGroup) GetStatementCondition() cloudprovider.TWafStatementCondition {
return cloudprovider.WafStatementConditionNone
}
func (self *ManagedRuleGroup) GetStatements() ([]cloudprovider.SWafStatement, error) {
groupName := self.ruleGroupId
switch self.ruleGroupId {
case "1011":
groupName = "严格规则"
case "1012":
groupName = "中等规则"
case "1013":
groupName = "宽松规则"
}
return []cloudprovider.SWafStatement{
cloudprovider.SWafStatement{
ManagedRuleGroupName: groupName,
RuleGroupId: self.ruleGroupId,
},
}, nil
}
type SDefenseTypeRule struct {
insId string
domain string
defenseType string
action cloudprovider.TWafAction
}
func (self *SDefenseTypeRule) GetName() string {
switch self.defenseType {
case "waf":
return "正则防护引擎"
case "dld":
return "大数据深度学习引擎"
case "ac_cc":
return "CC安全防护"
case "antifraud":
return "数据风控"
case "normalized":
return "主动防御"
}
return self.defenseType
}
func (self *SDefenseTypeRule) GetDesc() string {
return ""
}
func (self *SDefenseTypeRule) GetGlobalId() string {
return fmt.Sprintf("%s-%s-%s", self.insId, self.domain, self.defenseType)
}
func (self *SDefenseTypeRule) GetPriority() int {
return 0
}
func (self *SDefenseTypeRule) GetAction() *cloudprovider.DefaultAction {
return &cloudprovider.DefaultAction{
Action: self.action,
}
}
func (self *SDefenseTypeRule) GetStatementCondition() cloudprovider.TWafStatementCondition {
return cloudprovider.WafStatementConditionNone
}
func (self *SDefenseTypeRule) GetStatements() ([]cloudprovider.SWafStatement, error) {
return []cloudprovider.SWafStatement{}, nil
}
func (self *SDefenseTypeRule) Delete() error {
return cloudprovider.ErrNotSupported
}
func (self *SDefenseTypeRule) Update(opts *cloudprovider.SWafRule) error {
return cloudprovider.ErrNotSupported
}
func (self *SWafDomain) GetRules() ([]cloudprovider.ICloudWafRule, error) {
ruleGroupId, err := self.region.DescribeDomainRuleGroup(self.insId, self.name)
if err != nil {
return nil, errors.Wrapf(err, "DescribeDomainRuleGroup")
}
ret := []cloudprovider.ICloudWafRule{}
ret = append(ret, &ManagedRuleGroup{
waf: self,
insId: self.insId,
domain: self.name,
ruleGroupId: ruleGroupId,
})
for _, defenseType := range []string{
"waf",
"dld",
"ac_cc",
"antifraud",
"normalized",
} {
act, _ := self.region.DescribeProtectionModuleMode(self.insId, self.name, defenseType)
ret = append(ret, &SDefenseTypeRule{
insId: self.insId,
domain: self.name,
defenseType: defenseType,
action: act,
})
}
return ret, nil
}
type SIpSegement struct {
IpV6s string
Ips string
}
func (self *SRegion) DescribeWafSourceIpSegment(insId string) (*SIpSegement, error) {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": insId,
}
resp, err := self.wafRequest("DescribeWafSourceIpSegment", params)
if err != nil {
return nil, errors.Wrapf(err, "DescribeWafSourceIpSegment")
}
ret := &SIpSegement{}
err = resp.Unmarshal(ret)
if err != nil {
return nil, errors.Wrapf(err, "")
}
return ret, nil
}
func (self *SRegion) CreateICloudWafInstance(opts *cloudprovider.WafCreateOptions) (cloudprovider.ICloudWafInstance, error) {
ins, err := self.DescribeInstanceSpecInfo()
if err != nil {
return nil, errors.Wrapf(err, "DescribeInstanceSpecInfo")
}
waf, err := self.CreateDomain(ins.InstanceId, opts.Name, opts.SourceIps, opts.CloudResources)
if err != nil {
return nil, errors.Wrapf(err, "CreateDomain")
}
return waf, nil
}
func (self *SRegion) CreateDomain(insId, domain string, sourceIps []string, cloudResources []cloudprovider.SCloudResource) (*SWafDomain, error) {
params := map[string]string{
"RegionId": self.RegionId,
"InstanceId": insId,
"Domain": domain,
"IsAccessProduct": "0",
"HttpPort": `["80"]`,
"HttpsPort": `["443"]`,
"Http2Port": `["80", "443"]`,
}
if len(sourceIps) > 0 {
params["SourceIps"] = jsonutils.Marshal(sourceIps).String()
params["AccessType"] = "waf-cloud-dns"
} else if len(cloudResources) > 0 {
ins := jsonutils.NewArray()
for _, res := range cloudResources {
ins.Add(jsonutils.Marshal(map[string]interface{}{"InstanceId": res.Id, "Port": res.Port}))
}
params["CloudNativeInstances"] = ins.String()
params["AccessType"] = "waf-cloud-native"
} else {
return nil, errors.Error("missing source ips")
}
_, err := self.wafRequest("CreateDomain", params)
if err != nil {
return nil, errors.Wrapf(err, "CreateDomain")
}
return self.DescribeDomain(insId, domain)
}
func (self *SWafDomain) AddRule(opts *cloudprovider.SWafRule) (cloudprovider.ICloudWafRule, error) {
return nil, errors.Wrapf(cloudprovider.ErrNotSupported, "AddRule")
}
func (self *SWafDomain) Refresh() error {
domain, err := self.region.DescribeDomain(self.insId, self.name)
if err != nil {
return errors.Wrapf(err, "DescribeDomain")
}
return jsonutils.Update(self, domain)
}
func (self *SWafDomain) GetCloudResources() ([]cloudprovider.SCloudResource, error) {
ret := []cloudprovider.SCloudResource{}
if len(self.Cname) > 0 {
ret = append(ret, cloudprovider.SCloudResource{
Type: "cname",
Id: self.Cname,
CanDissociate: false,
})
}
ipseg, err := self.region.DescribeWafSourceIpSegment(self.insId)
if err == nil {
ret = append(ret, cloudprovider.SCloudResource{
Type: "segment_ipv4",
Id: ipseg.Ips,
CanDissociate: false,
})
ret = append(ret, cloudprovider.SCloudResource{
Type: "segment_ipv6",
Id: ipseg.IpV6s,
CanDissociate: false,
})
}
return ret, nil
}
func (self *SRegion) DescribeProtectionModuleMode(insId, domain, defenseType string) (cloudprovider.TWafAction, error) {
params := map[string]string{
"RegionId": self.RegionId,
"Domain": domain,
"InstanceId": insId,
"DefenseType": defenseType,
}
resp, err := self.wafRequest("DescribeProtectionModuleMode", params)
if err != nil {
return cloudprovider.WafActionNone, errors.Wrapf(err, "DescribeProtectionModuleMode %s", defenseType)
}
if !resp.Contains("Mode") {
return cloudprovider.WafActionNone, nil
}
mode, _ := resp.Int("Mode")
switch defenseType {
case "waf":
if mode == 0 {
return cloudprovider.WafActionBlock, nil
}
if mode == 1 {
return cloudprovider.WafActionAlert, nil
}
case "dld":
if mode == 0 {
return cloudprovider.WafActionAlert, nil
}
if mode == 1 {
return cloudprovider.WafActionBlock, nil
}
case "ac_cc":
if mode == 0 {
return cloudprovider.WafActionAllow, nil
}
if mode == 1 {
return cloudprovider.WafActionBlock, nil
}
case "antifraud":
if mode == 0 {
return cloudprovider.WafActionAlert, nil
}
if mode == 1 || mode == 2 {
return cloudprovider.WafActionBlock, nil
}
case "normalized":
if mode == 0 {
return cloudprovider.WafActionAlert, nil
}
if mode == 1 {
return cloudprovider.WafActionBlock, nil
}
}
return cloudprovider.WafActionNone, nil
}
+1
View File
@@ -586,6 +586,7 @@ func (self *SAwsClient) GetCapabilities() []string {
cloudprovider.CLOUD_CAPABILITY_CLOUDID,
cloudprovider.CLOUD_CAPABILITY_DNSZONE,
cloudprovider.CLOUD_CAPABILITY_SAML_AUTH,
cloudprovider.CLOUD_CAPABILITY_WAF,
}
return caps
}
+13
View File
@@ -39,6 +39,7 @@ import (
"github.com/aws/aws-sdk-go/service/organizations"
"github.com/aws/aws-sdk-go/service/resourcegroupstaggingapi"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/wafv2"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
@@ -139,6 +140,7 @@ type SRegion struct {
s3Client *s3.S3
elbv2Client *elbv2.ELBV2
acmClient *acm.ACM
wafClient *wafv2.WAFV2
organizationClient *organizations.Organizations
resourceGroupTagClient *resourcegroupstaggingapi.ResourceGroupsTaggingAPI
@@ -189,6 +191,17 @@ func (self *SRegion) getIamClient() (*iam.IAM, error) {
return self.iamClient, nil
}
func (self *SRegion) getWafClient() (*wafv2.WAFV2, error) {
if self.wafClient == nil {
s, err := self.getAwsSession()
if err != nil {
return nil, errors.Wrapf(err, "getAwsSession")
}
self.wafClient = wafv2.New(s)
}
return self.wafClient, nil
}
func (self *SRegion) GetS3Client() (*s3.S3, error) {
if self.s3Client == nil {
s, err := self.getAwsSession()
+210
View File
@@ -0,0 +1,210 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package shell
import (
"fmt"
"io/ioutil"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud/aws"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type WafRuleGroupListOptions struct {
Scope string `choices:"CLOUDFRONT|REGIONAL" default:"REGIONAL"`
}
shellutils.R(&WafRuleGroupListOptions{}, "waf-managed-rule-group-list", "List waf managed rule group", func(cli *aws.SRegion, args *WafRuleGroupListOptions) error {
groups, err := cli.ListAvailableManagedRuleGroups(args.Scope)
if err != nil {
return err
}
printList(groups, 0, 0, 0, []string{})
return nil
})
shellutils.R(&WafRuleGroupListOptions{}, "waf-rule-group-list", "List waf rule group", func(cli *aws.SRegion, args *WafRuleGroupListOptions) error {
groups, err := cli.ListRuleGroups(args.Scope)
if err != nil {
return err
}
printList(groups, 0, 0, 0, []string{})
return nil
})
type WafRuleGroupShowOptions struct {
ID string
NAME string
SCOPE string
}
shellutils.R(&WafRuleGroupShowOptions{}, "waf-rule-group-show", "Show waf rule group", func(cli *aws.SRegion, args *WafRuleGroupShowOptions) error {
group, err := cli.GetRuleGroup(args.ID, args.NAME, args.SCOPE)
if err != nil {
return err
}
printObject(group)
return nil
})
type WafManagedRuleGroupShowOptions struct {
NAME string
SCOPE string
VendorName string `default:"AWS"`
}
shellutils.R(&WafManagedRuleGroupShowOptions{}, "waf-managed-rule-group-show", "Show waf rule group", func(cli *aws.SRegion, args *WafManagedRuleGroupShowOptions) error {
group, err := cli.DescribeManagedRuleGroup(args.NAME, args.SCOPE, args.VendorName)
if err != nil {
return err
}
printObject(group)
return nil
})
type RuleGroupDeleteOptions struct {
ID string
NAME string
SCOPE string
LOCK_TOKEN string
}
shellutils.R(&RuleGroupDeleteOptions{}, "waf-rule-group-delete", "Delete waf ip set", func(cli *aws.SRegion, args *RuleGroupDeleteOptions) error {
return cli.DeleteRuleGroup(args.ID, args.NAME, args.SCOPE, args.LOCK_TOKEN)
})
type IPSetListOptions struct {
Scope string `choices:"CLOUDFRONT|REGIONAL" default:"REGIONAL"`
}
shellutils.R(&IPSetListOptions{}, "waf-ipset-list", "List waf ip sets", func(cli *aws.SRegion, args *IPSetListOptions) error {
ipsets, err := cli.ListIPSets(args.Scope)
if err != nil {
return err
}
printList(ipsets, 0, 0, 0, []string{})
return nil
})
type WafIPSetShowOptions struct {
ID string
NAME string
SCOPE string
}
shellutils.R(&WafIPSetShowOptions{}, "waf-ipset-show", "Show waf ip sets", func(cli *aws.SRegion, args *WafIPSetShowOptions) error {
ipset, err := cli.GetIPSet(args.ID, args.NAME, args.SCOPE)
if err != nil {
return err
}
printObject(ipset)
return nil
})
type WafIPSetDeleteOptions struct {
ID string
NAME string
SCOPE string
LOCK_TOKEN string
}
shellutils.R(&WafIPSetDeleteOptions{}, "waf-ipset-delete", "Delete waf ip set", func(cli *aws.SRegion, args *WafIPSetDeleteOptions) error {
return cli.DeleteIPSet(args.ID, args.NAME, args.SCOPE, args.LOCK_TOKEN)
})
type WafListOptions struct {
Scope string `choices:"CLOUDFRONT|REGIONAL" default:"REGIONAL"`
}
shellutils.R(&WafListOptions{}, "waf-list", "List web acls", func(cli *aws.SRegion, args *WafListOptions) error {
acls, err := cli.ListWebACLs(args.Scope)
if err != nil {
return err
}
printList(acls, 0, 0, 0, []string{})
return nil
})
type WafShowOptions struct {
ID string
NAME string
SCOPE string
}
shellutils.R(&WafShowOptions{}, "waf-show", "Show web acl", func(cli *aws.SRegion, args *WafShowOptions) error {
webAcl, err := cli.GetWebAcl(args.ID, args.NAME, args.SCOPE)
if err != nil {
return err
}
printObject(webAcl)
return nil
})
type WafDeleteOptions struct {
ID string
NAME string
SCOPE string
LOCK_TOKEN string
}
shellutils.R(&WafDeleteOptions{}, "waf-delete", "Delete web acl", func(cli *aws.SRegion, args *WafDeleteOptions) error {
return cli.DeleteWebAcl(args.ID, args.NAME, args.SCOPE, args.LOCK_TOKEN)
})
type WafResourceListOptions struct {
ResType string `choices:"APPLICATION_LOAD_BALANCER|API_GATEWAY|APPSYNC"`
ARN string
}
shellutils.R(&WafResourceListOptions{}, "waf-res-list", "List web acl resource", func(cli *aws.SRegion, args *WafResourceListOptions) error {
res, err := cli.ListResourcesForWebACL(args.ResType, args.ARN)
if err != nil {
return err
}
fmt.Println("res:", res)
return nil
})
type WafAddRuleOptions struct {
WafShowOptions
RULE_FILE string
}
shellutils.R(&WafAddRuleOptions{}, "waf-add-rule", "Add web acl rule", func(cli *aws.SRegion, args *WafAddRuleOptions) error {
waf, err := cli.GetWebAcl(args.ID, args.NAME, args.SCOPE)
if err != nil {
return errors.Wrapf(err, "GetWebAcl")
}
data, err := ioutil.ReadFile(args.RULE_FILE)
if err != nil {
return errors.Wrapf(err, "ReadFile")
}
params, err := jsonutils.Parse(data)
if err != nil {
return errors.Wrapf(err, "Parse")
}
rule := &cloudprovider.SWafRule{}
params.Unmarshal(rule)
_, err = waf.AddRule(rule)
return err
})
}
+536
View File
@@ -0,0 +1,536 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aws
import (
"strings"
"github.com/aws/aws-sdk-go/service/wafv2"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
const (
SCOPE_REGIONAL = "REGIONAL"
SCOPE_CLOUDFRONT = "CLOUDFRONT"
)
var (
WAF_SCOPES = []string{
SCOPE_REGIONAL,
SCOPE_CLOUDFRONT,
}
)
type SWafRule struct {
Action struct {
Block struct {
} `json:"Block"`
} `json:"Action"`
Name string `json:"Name"`
}
type SVisibilityConfig struct {
CloudWatchMetricsEnabled bool
MetricName string
SampledRequestsEnabled bool
}
type SWebAcl struct {
multicloud.SResourceBase
multicloud.AwsTags
region *SRegion
sWebDetails
scope string
ARN string
Description string
Id string
LockToken string
Name string
LabelNamespace string
Capacity int
ManagedByFirewallManager bool
VisibilityConfig SVisibilityConfig
}
func (self *SRegion) ListWebACLs(scope string) ([]SWebAcl, error) {
if scope == SCOPE_CLOUDFRONT && self.RegionId != "us-east-1" {
return []SWebAcl{}, nil
}
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
ret := []SWebAcl{}
input := wafv2.ListWebACLsInput{}
input.SetScope(scope)
for {
resp, err := client.ListWebACLs(&input)
if err != nil {
return nil, errors.Wrapf(err, "ListWebACLs")
}
part := []SWebAcl{}
jsonutils.Update(&part, resp.WebACLs)
ret = append(ret, part...)
if resp.NextMarker == nil || len(*resp.NextMarker) == 0 {
break
}
input.SetNextMarker(*resp.NextMarker)
}
return ret, nil
}
func (self *SRegion) GetWebAcl(id, name, scope string) (*SWebAcl, error) {
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
input := wafv2.GetWebACLInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
resp, err := client.GetWebACL(&input)
if err != nil {
if _, ok := err.(*wafv2.WAFNonexistentItemException); ok {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, err.Error())
}
return nil, errors.Wrapf(err, "GetWebAcl")
}
ret := &SWebAcl{region: self, scope: scope, sWebDetails: sWebDetails{resp.WebACL}, LockToken: *resp.LockToken}
return ret, jsonutils.Update(ret, resp.WebACL)
}
func (self *SRegion) DeleteWebAcl(id, name, scope, lockToken string) error {
client, err := self.getWafClient()
if err != nil {
return errors.Wrapf(err, "getWafClient")
}
input := wafv2.DeleteWebACLInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
input.SetLockToken(lockToken)
_, err = client.DeleteWebACL(&input)
return errors.Wrapf(err, "DeleteWebACL")
}
func (self *SRegion) ListResourcesForWebACL(resType, arn string) ([]string, error) {
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
input := wafv2.ListResourcesForWebACLInput{}
input.SetResourceType(resType)
input.SetWebACLArn(arn)
resp, err := client.ListResourcesForWebACL(&input)
if err != nil {
return nil, errors.Wrapf(err, "ListResourcesForWebACL")
}
ret := []string{}
for _, id := range resp.ResourceArns {
ret = append(ret, *id)
}
return ret, nil
}
func (self *SRegion) GetICloudWafInstanceById(id string) (cloudprovider.ICloudWafInstance, error) {
idInfo := strings.Split(id, "/")
if len(idInfo) != 4 {
return nil, errors.Wrapf(cloudprovider.ErrNotFound, "invalid arn %s", id)
}
scope := SCOPE_CLOUDFRONT
if strings.HasSuffix(idInfo[0], "regional") {
scope = SCOPE_REGIONAL
}
ins, err := self.GetWebAcl(idInfo[3], idInfo[2], scope)
if err != nil {
return nil, errors.Wrapf(err, "GetWebAcl(%s, %s, %s)", idInfo[3], idInfo[2], scope)
}
return ins, nil
}
func (self *SRegion) GetICloudWafInstances() ([]cloudprovider.ICloudWafInstance, error) {
ret := []cloudprovider.ICloudWafInstance{}
for _, scope := range WAF_SCOPES {
ins, err := self.ListWebACLs(scope)
if err != nil {
return nil, errors.Wrapf(err, "ListWebACLs")
}
for i := range ins {
ins[i].region = self
ins[i].scope = scope
ret = append(ret, &ins[i])
}
}
return ret, nil
}
func (self *SWebAcl) GetEnabled() bool {
return true
}
func (self *SWebAcl) GetGlobalId() string {
return self.ARN
}
func (self *SWebAcl) GetName() string {
return self.Name
}
func (self *SWebAcl) GetId() string {
return self.ARN
}
func (self *SWebAcl) GetWafType() cloudprovider.TWafType {
if self.scope == SCOPE_CLOUDFRONT {
return cloudprovider.WafTypeCloudFront
}
return cloudprovider.WafTypeRegional
}
func (self *SWebAcl) GetStatus() string {
return api.WAF_STATUS_AVAILABLE
}
func (self *SWebAcl) GetDefaultAction() *cloudprovider.DefaultAction {
ret := &cloudprovider.DefaultAction{}
if self.WebACL != nil && self.WebACL.DefaultAction != nil {
action := self.WebACL.DefaultAction
if action.Allow != nil {
ret.Action = cloudprovider.WafActionAllow
} else if action.Block != nil {
ret.Action = cloudprovider.WafActionBlock
}
}
return ret
}
func (self *SWebAcl) Refresh() error {
acl, err := self.region.GetWebAcl(self.Id, self.Name, self.scope)
if err != nil {
return errors.Wrapf(err, "GetWebAcl")
}
return jsonutils.Update(self, acl)
}
func (self *SWebAcl) Delete() error {
return self.region.DeleteWebAcl(self.Id, self.Name, self.scope, self.LockToken)
}
func (self *SRegion) CreateICloudWafInstance(opts *cloudprovider.WafCreateOptions) (cloudprovider.ICloudWafInstance, error) {
waf, err := self.CreateWebAcl(opts.Name, opts.Desc, opts.Type, opts.DefaultAction)
if err != nil {
return nil, errors.Wrapf(err, "CreateWebAcl")
}
return waf, nil
}
func (self *SRegion) CreateWebAcl(name, desc string, wafType cloudprovider.TWafType, action *cloudprovider.DefaultAction) (*SWebAcl, error) {
input := wafv2.CreateWebACLInput{}
input.SetName(name)
if len(desc) > 0 {
input.SetDescription(desc)
}
switch wafType {
case cloudprovider.WafTypeRegional, cloudprovider.WafTypeCloudFront:
input.SetScope(strings.ToUpper(string(wafType)))
default:
return nil, errors.Errorf("invalid waf type %s", wafType)
}
if action != nil {
defaultAction := wafv2.DefaultAction{}
switch action.Action {
case cloudprovider.WafActionAllow:
defaultAction.Allow = &wafv2.AllowAction{}
case cloudprovider.WafActionBlock:
defaultAction.Block = &wafv2.BlockAction{}
}
input.SetDefaultAction(&defaultAction)
}
visib := &wafv2.VisibilityConfig{}
visib.SetSampledRequestsEnabled(true)
visib.SetCloudWatchMetricsEnabled(true)
visib.SetMetricName(name)
input.SetVisibilityConfig(visib)
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
output, err := client.CreateWebACL(&input)
if err != nil {
return nil, errors.Wrapf(err, "CreateWebAcl")
}
return self.GetWebAcl(*output.Summary.Id, name, *input.Scope)
}
func reverseConvertField(opts cloudprovider.SWafStatement) *wafv2.FieldToMatch {
ret := &wafv2.FieldToMatch{}
switch opts.MatchField {
case cloudprovider.WafMatchFieldBody:
body := &wafv2.Body{}
ret.SetBody(body)
case cloudprovider.WafMatchFieldJsonBody:
case cloudprovider.WafMatchFieldMethod:
method := &wafv2.Method{}
ret.SetMethod(method)
case cloudprovider.WafMatchFieldQuery:
switch opts.MatchFieldKey {
case "SingleArgument":
query := &wafv2.SingleQueryArgument{}
ret.SetSingleQueryArgument(query)
case "AllArguments":
query := &wafv2.AllQueryArguments{}
ret.SetAllQueryArguments(query)
default:
query := &wafv2.QueryString{}
ret.SetQueryString(query)
}
case cloudprovider.WafMatchFiledHeader:
head := &wafv2.SingleHeader{}
head.SetName(opts.MatchFieldKey)
ret.SetSingleHeader(head)
case cloudprovider.WafMatchFiledUriPath:
uri := &wafv2.UriPath{}
ret.SetUriPath(uri)
}
return ret
}
func reverseConvertStatement(statement cloudprovider.SWafStatement) *wafv2.Statement {
ret := &wafv2.Statement{}
trans := []*wafv2.TextTransformation{}
if statement.Transformations != nil {
for i, tran := range *statement.Transformations {
t := &wafv2.TextTransformation{}
switch tran {
case cloudprovider.WafTextTransformationNone:
t.SetType(wafv2.TextTransformationTypeNone)
case cloudprovider.WafTextTransformationLowercase:
t.SetType(wafv2.TextTransformationTypeLowercase)
case cloudprovider.WafTextTransformationCmdLine:
t.SetType(wafv2.TextTransformationTypeCmdLine)
case cloudprovider.WafTextTransformationUrlDecode:
t.SetType(wafv2.TextTransformationTypeUrlDecode)
case cloudprovider.WafTextTransformationHtmlEntityDecode:
t.SetType(wafv2.TextTransformationTypeHtmlEntityDecode)
case cloudprovider.WafTextTransformationCompressWithSpace:
t.SetType(wafv2.TextTransformationTypeCompressWhiteSpace)
}
t.SetPriority(int64(i))
trans = append(trans, t)
}
}
rules := []*wafv2.ExcludedRule{}
if statement.ExcludeRules != nil {
for _, r := range *statement.ExcludeRules {
name := r.Name
rules = append(rules, &wafv2.ExcludedRule{
Name: &name,
})
}
}
field := reverseConvertField(statement)
switch statement.Type {
case cloudprovider.WafStatementTypeRate:
rate := &wafv2.RateBasedStatement{}
rate.SetLimit(*statement.Limit)
fd := &wafv2.ForwardedIPConfig{}
if len(statement.ForwardedIPHeader) > 0 {
fd.SetHeaderName(statement.ForwardedIPHeader)
rate.SetForwardedIPConfig(fd)
}
ret.SetRateBasedStatement(rate)
case cloudprovider.WafStatementTypeIPSet:
ipset := &wafv2.IPSetReferenceStatement{}
ipset.SetARN(statement.IPSetId)
fd := &wafv2.IPSetForwardedIPConfig{}
if len(statement.ForwardedIPHeader) > 0 {
fd.SetHeaderName(statement.ForwardedIPHeader)
ipset.SetIPSetForwardedIPConfig(fd)
}
ret.SetIPSetReferenceStatement(ipset)
case cloudprovider.WafStatementTypeXssMatch:
xss := &wafv2.XssMatchStatement{}
if len(trans) > 0 {
xss.SetTextTransformations(trans)
}
field := &wafv2.FieldToMatch{}
xss.SetFieldToMatch(field)
xss.SetTextTransformations(trans)
ret.SetXssMatchStatement(xss)
case cloudprovider.WafStatementTypeSize:
size := &wafv2.SizeConstraintStatement{}
size.SetFieldToMatch(field)
size.SetSize(*statement.Size)
ret.SetSizeConstraintStatement(size)
case cloudprovider.WafStatementTypeGeoMatch:
geo := &wafv2.GeoMatchStatement{}
values := []*string{}
if statement.MatchFieldValues != nil {
for i := range *statement.MatchFieldValues {
v := (*statement.MatchFieldValues)[i]
values = append(values, &v)
}
geo.SetCountryCodes(values)
}
fd := &wafv2.ForwardedIPConfig{}
if len(statement.ForwardedIPHeader) > 0 {
fd.SetHeaderName(statement.ForwardedIPHeader)
geo.SetForwardedIPConfig(fd)
}
ret.SetGeoMatchStatement(geo)
case cloudprovider.WafStatementTypeRegexSet:
regex := &wafv2.RegexPatternSetReferenceStatement{}
regex.SetARN(statement.RegexSetId)
if len(trans) > 0 {
regex.SetTextTransformations(trans)
}
regex.SetFieldToMatch(field)
ret.SetRegexPatternSetReferenceStatement(regex)
case cloudprovider.WafStatementTypeByteMatch:
bm := &wafv2.ByteMatchStatement{}
if len(trans) > 0 {
bm.SetTextTransformations(trans)
}
bm.SetSearchString([]byte(statement.SearchString))
if len(statement.Operator) > 0 {
bm.SetPositionalConstraint(string(statement.Operator))
}
bm.SetFieldToMatch(field)
ret.SetByteMatchStatement(bm)
case cloudprovider.WafStatementTypeRuleGroup:
rg := &wafv2.RuleGroupReferenceStatement{}
rg.SetARN(statement.RuleGroupId)
if len(rules) > 0 {
rg.SetExcludedRules(rules)
}
ret.SetRuleGroupReferenceStatement(rg)
case cloudprovider.WafStatementTypeSqliMatch:
sqli := &wafv2.SqliMatchStatement{}
if len(trans) > 0 {
sqli.SetTextTransformations(trans)
}
sqli.SetFieldToMatch(field)
ret.SetSqliMatchStatement(sqli)
case cloudprovider.WafStatementTypeLabelMatch:
case cloudprovider.WafStatementTypeManagedRuleGroup:
rg := &wafv2.ManagedRuleGroupStatement{}
rg.SetName(statement.ManagedRuleGroupName)
rg.SetVendorName("aws")
if len(rules) > 0 {
rg.SetExcludedRules(rules)
}
ret.SetManagedRuleGroupStatement(rg)
}
return ret
}
func (self *SWebAcl) AddRule(opts *cloudprovider.SWafRule) (cloudprovider.ICloudWafRule, error) {
input := &wafv2.UpdateWebACLInput{}
input.SetLockToken(self.LockToken)
input.SetId(self.Id)
input.SetName(self.Name)
input.SetScope(self.scope)
input.SetDescription(self.Description)
input.SetDefaultAction(self.sWebDetails.DefaultAction)
input.SetVisibilityConfig(self.sWebDetails.VisibilityConfig)
rules := self.sWebDetails.Rules
rule := &wafv2.Rule{}
rule.SetName(opts.Name)
rule.SetPriority(int64(opts.Priority))
action := &wafv2.RuleAction{}
if opts.Action != nil {
switch opts.Action.Action {
case cloudprovider.WafActionAllow:
allow := &wafv2.AllowAction{}
action.SetAllow(allow)
case cloudprovider.WafActionBlock:
block := &wafv2.BlockAction{}
action.SetBlock(block)
case cloudprovider.WafActionCount:
count := &wafv2.CountAction{}
action.SetCount(count)
}
}
rule.SetAction(action)
visib := &wafv2.VisibilityConfig{}
visib.SetSampledRequestsEnabled(false)
visib.SetCloudWatchMetricsEnabled(true)
visib.SetMetricName(opts.Name)
rule.SetVisibilityConfig(visib)
statement := &wafv2.Statement{}
switch opts.StatementCondition {
case cloudprovider.WafStatementConditionOr:
ss := &wafv2.OrStatement{}
for _, s := range opts.Statements {
ss.Statements = append(ss.Statements, reverseConvertStatement(s))
}
statement.SetOrStatement(ss)
case cloudprovider.WafStatementConditionAnd:
ss := &wafv2.AndStatement{}
for _, s := range opts.Statements {
ss.Statements = append(ss.Statements, reverseConvertStatement(s))
}
statement.SetAndStatement(ss)
case cloudprovider.WafStatementConditionNot:
ss := &wafv2.NotStatement{}
for _, s := range opts.Statements {
ss.SetStatement(reverseConvertStatement(s))
break
}
statement.SetNotStatement(ss)
case cloudprovider.WafStatementConditionNone:
for _, s := range opts.Statements {
statement = reverseConvertStatement(s)
break
}
}
rule.SetStatement(statement)
rules = append(rules, rule)
input.SetRules(rules)
client, err := self.region.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
_, err = client.UpdateWebACL(input)
if err != nil {
return nil, errors.Wrapf(err, "UpdateWebACL")
}
ret := &sWafRule{waf: self, Rule: rule}
return ret, nil
}
func (self *SWebAcl) GetCloudResources() ([]cloudprovider.SCloudResource, error) {
ret := []cloudprovider.SCloudResource{}
for _, resType := range []string{"APPLICATION_LOAD_BALANCER", "API_GATEWAY", "APPSYNC"} {
resIds, err := self.region.ListResourcesForWebACL(resType, self.ARN)
if err != nil {
return nil, errors.Wrapf(err, "ListResourcesForWebACL(%s, %s)", resType, self.ARN)
}
for _, resId := range resIds {
ret = append(ret, cloudprovider.SCloudResource{
Id: resId,
Type: resType,
})
}
}
return ret, nil
}
+146
View File
@@ -0,0 +1,146 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aws
import (
"github.com/aws/aws-sdk-go/service/wafv2"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type SWafIPSet struct {
region *SRegion
scope string
Addresses []string
ARN string
Description string
Id string
LockToken string
Name string
}
func (self *SWafIPSet) GetName() string {
return self.Name
}
func (self *SWafIPSet) GetDesc() string {
return self.Description
}
func (self *SWafIPSet) GetGlobalId() string {
return self.ARN
}
func (self *SWafIPSet) GetType() cloudprovider.TWafType {
switch self.scope {
case SCOPE_CLOUDFRONT:
return cloudprovider.WafTypeCloudFront
case SCOPE_REGIONAL:
return cloudprovider.WafTypeRegional
}
return cloudprovider.TWafType(self.scope)
}
func (self *SWafIPSet) GetAddresses() cloudprovider.WafAddresses {
if len(self.Addresses) == 0 {
ipSet, err := self.region.GetIPSet(self.Id, self.Name, self.scope)
if err != nil {
return cloudprovider.WafAddresses{}
}
return ipSet.Addresses
}
return self.Addresses
}
func (self *SWafIPSet) Delete() error {
return self.region.DeleteIPSet(self.Id, self.Name, self.scope, self.LockToken)
}
func (self *SRegion) ListIPSets(scope string) ([]SWafIPSet, error) {
if scope == SCOPE_CLOUDFRONT && self.RegionId != "us-east-1" {
return []SWafIPSet{}, nil
}
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
ret := []SWafIPSet{}
input := wafv2.ListIPSetsInput{}
input.SetScope(scope)
for {
resp, err := client.ListIPSets(&input)
if err != nil {
return nil, errors.Wrapf(err, "ListIPSets")
}
part := []SWafIPSet{}
jsonutils.Update(&part, resp.IPSets)
ret = append(ret, part...)
if resp.NextMarker == nil || len(*resp.NextMarker) == 0 {
break
}
input.SetNextMarker(*resp.NextMarker)
}
return ret, nil
}
func (self *SRegion) GetIPSet(id, name, scope string) (*SWafIPSet, error) {
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
input := wafv2.GetIPSetInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
resp, err := client.GetIPSet(&input)
if err != nil {
return nil, errors.Wrapf(err, "GetIPSet")
}
ret := &SWafIPSet{LockToken: *resp.LockToken}
return ret, jsonutils.Update(ret, resp.IPSet)
}
func (self *SRegion) DeleteIPSet(id, name, scope, lockToken string) error {
client, err := self.getWafClient()
if err != nil {
return errors.Wrapf(err, "getWafClient")
}
input := wafv2.DeleteIPSetInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
input.SetLockToken(lockToken)
_, err = client.DeleteIPSet(&input)
return errors.Wrapf(err, "DeleteIPSet")
}
func (self *SRegion) GetICloudWafIPSets() ([]cloudprovider.ICloudWafIPSet, error) {
ret := []cloudprovider.ICloudWafIPSet{}
for _, scope := range WAF_SCOPES {
part, err := self.ListIPSets(scope)
if err != nil {
return nil, errors.Wrapf(err, "ListIPSets(%s)", scope)
}
for i := range part {
part[i].scope = scope
part[i].region = self
ret = append(ret, &part[i])
}
}
return ret, nil
}
+155
View File
@@ -0,0 +1,155 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aws
import (
"github.com/aws/aws-sdk-go/service/wafv2"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type RegularExpression struct {
RegexString string
}
type SWafRegexSet struct {
region *SRegion
scope string
RegularExpressionList []RegularExpression
ARN string
Description string
Id string
LockToken string
Name string
}
func (self *SWafRegexSet) GetName() string {
return self.Name
}
func (self *SWafRegexSet) GetDesc() string {
return self.Description
}
func (self *SWafRegexSet) GetGlobalId() string {
return self.ARN
}
func (self *SWafRegexSet) GetType() cloudprovider.TWafType {
switch self.scope {
case SCOPE_REGIONAL:
return cloudprovider.WafTypeRegional
case SCOPE_CLOUDFRONT:
return cloudprovider.WafTypeCloudFront
default:
return cloudprovider.TWafType(self.scope)
}
}
func (self *SWafRegexSet) GetRegexPatterns() cloudprovider.WafRegexPatterns {
if len(self.RegularExpressionList) == 0 {
rSet, err := self.region.GetRegexSet(self.Id, self.Name, self.scope)
if err != nil {
return cloudprovider.WafRegexPatterns{}
}
jsonutils.Update(self, rSet)
}
ret := cloudprovider.WafRegexPatterns{}
for _, r := range self.RegularExpressionList {
ret = append(ret, r.RegexString)
}
return ret
}
func (self *SWafRegexSet) Delete() error {
return self.region.DeleteRegexSet(self.Id, self.Name, self.scope, self.LockToken)
}
func (self *SRegion) ListRegexSets(scope string) ([]SWafRegexSet, error) {
if scope == SCOPE_CLOUDFRONT && self.RegionId != "us-east-1" {
return []SWafRegexSet{}, nil
}
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
ret := []SWafRegexSet{}
input := wafv2.ListRegexPatternSetsInput{}
input.SetScope(scope)
for {
resp, err := client.ListRegexPatternSets(&input)
if err != nil {
return nil, errors.Wrapf(err, "ListRegexPatternSets")
}
part := []SWafRegexSet{}
jsonutils.Update(&part, resp.RegexPatternSets)
ret = append(ret, part...)
if resp.NextMarker == nil || len(*resp.NextMarker) == 0 {
break
}
input.SetNextMarker(*resp.NextMarker)
}
return ret, nil
}
func (self *SRegion) GetRegexSet(id, name, scope string) (*SWafRegexSet, error) {
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
input := wafv2.GetRegexPatternSetInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
resp, err := client.GetRegexPatternSet(&input)
if err != nil {
return nil, errors.Wrapf(err, "GetRegexPatternSet")
}
ret := &SWafRegexSet{LockToken: *resp.LockToken}
return ret, jsonutils.Update(ret, resp.RegexPatternSet)
}
func (self *SRegion) DeleteRegexSet(id, name, scope, lockToken string) error {
client, err := self.getWafClient()
if err != nil {
return errors.Wrapf(err, "getWafClient")
}
input := wafv2.DeleteRegexPatternSetInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
input.SetLockToken(lockToken)
_, err = client.DeleteRegexPatternSet(&input)
return errors.Wrapf(err, "DeleteRegexPatternSet")
}
func (self *SRegion) GetICloudWafRegexSets() ([]cloudprovider.ICloudWafRegexSet, error) {
ret := []cloudprovider.ICloudWafRegexSet{}
for _, scope := range WAF_SCOPES {
part, err := self.ListRegexSets(scope)
if err != nil {
return nil, errors.Wrapf(err, "ListRegexSets(%s)", scope)
}
for i := range part {
part[i].scope = scope
part[i].region = self
ret = append(ret, &part[i])
}
}
return ret, nil
}
+135
View File
@@ -0,0 +1,135 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aws
import (
"github.com/aws/aws-sdk-go/service/wafv2"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
)
type SWafRuleGroup struct {
Description string
Name string
VendorName string
Capacity int `json:"Capacity"`
Rules []SWafRule
}
func (self *SRegion) ListAvailableManagedRuleGroups(scope string) ([]SWafRuleGroup, error) {
if scope == SCOPE_CLOUDFRONT && self.RegionId != "us-east-1" {
return []SWafRuleGroup{}, nil
}
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
ret := []SWafRuleGroup{}
input := wafv2.ListAvailableManagedRuleGroupsInput{}
input.SetScope(scope)
for {
resp, err := client.ListAvailableManagedRuleGroups(&input)
if err != nil {
return nil, errors.Wrapf(err, "ListAvailableManagedRuleGroups")
}
part := []SWafRuleGroup{}
jsonutils.Update(&part, resp.ManagedRuleGroups)
ret = append(ret, part...)
if resp.NextMarker == nil || len(*resp.NextMarker) == 0 {
break
}
input.SetNextMarker(*resp.NextMarker)
}
return ret, nil
}
func (self *SRegion) DescribeManagedRuleGroup(name, scope, vendorName string) (*SWafRuleGroup, error) {
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
input := wafv2.DescribeManagedRuleGroupInput{}
input.SetName(name)
input.SetScope(scope)
input.SetVendorName(vendorName)
resp, err := client.DescribeManagedRuleGroup(&input)
if err != nil {
return nil, err
}
ret := &SWafRuleGroup{
Name: name,
VendorName: vendorName,
}
return ret, jsonutils.Update(ret, resp)
}
func (self *SRegion) ListRuleGroups(scope string) ([]SWafRuleGroup, error) {
if scope == SCOPE_CLOUDFRONT && self.RegionId != "us-east-1" {
return []SWafRuleGroup{}, nil
}
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
ret := []SWafRuleGroup{}
input := wafv2.ListRuleGroupsInput{}
input.SetScope(scope)
for {
resp, err := client.ListRuleGroups(&input)
if err != nil {
return nil, errors.Wrapf(err, "ListRuleGroups")
}
part := []SWafRuleGroup{}
jsonutils.Update(&part, resp.RuleGroups)
ret = append(ret, part...)
if resp.NextMarker == nil || len(*resp.NextMarker) == 0 {
break
}
input.SetNextMarker(*resp.NextMarker)
}
return ret, nil
}
func (self *SRegion) GetRuleGroup(id, name, scope string) (*SWafRuleGroup, error) {
client, err := self.getWafClient()
if err != nil {
return nil, errors.Wrapf(err, "getWafClient")
}
input := wafv2.GetRuleGroupInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
resp, err := client.GetRuleGroup(&input)
if err != nil {
return nil, errors.Wrapf(err, "GetRuleGroup")
}
ret := &SWafRuleGroup{}
return ret, jsonutils.Update(ret, resp.RuleGroup)
}
func (self *SRegion) DeleteRuleGroup(id, name, scope, lockToken string) error {
client, err := self.getWafClient()
if err != nil {
return errors.Wrapf(err, "getWafClient")
}
input := wafv2.DeleteRuleGroupInput{}
input.SetId(id)
input.SetName(name)
input.SetScope(scope)
input.SetLockToken(lockToken)
_, err = client.DeleteRuleGroup(&input)
return errors.Wrapf(err, "DeleteRuleGroup")
}
+265
View File
@@ -0,0 +1,265 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package aws
import (
"strings"
"github.com/aws/aws-sdk-go/service/wafv2"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/utils"
"yunion.io/x/onecloud/pkg/cloudprovider"
)
type sWebDetails struct {
*wafv2.WebACL
}
type sWafRule struct {
waf *SWebAcl
*wafv2.Rule
}
func (self *sWafRule) GetAction() *cloudprovider.DefaultAction {
ret := &cloudprovider.DefaultAction{}
if self.Action.Allow != nil {
ret.Action = cloudprovider.WafActionAllow
} else if self.Action.Block != nil {
ret.Action = cloudprovider.WafActionBlock
} else if self.Action.Count != nil {
ret.Action = cloudprovider.WafActionCount
}
return ret
}
func (self *sWafRule) GetDesc() string {
return ""
}
func (self *sWafRule) GetName() string {
return *self.Rule.Name
}
func (self *sWafRule) GetGlobalId() string {
return self.GetName()
}
func (self *sWafRule) GetPriority() int {
return int(*self.Rule.Priority)
}
func (self *sWafRule) Delete() error {
input := wafv2.UpdateWebACLInput{}
rules := []*wafv2.Rule{}
for _, rule := range self.waf.sWebDetails.Rules {
if *rule.Name == *self.Name {
continue
}
rules = append(rules, rule)
}
input.SetRules(rules)
input.SetLockToken(self.waf.LockToken)
input.SetId(self.waf.Id)
input.SetName(self.waf.Name)
input.SetScope(self.waf.scope)
input.SetDescription(self.waf.Description)
input.SetDefaultAction(self.waf.DefaultAction)
input.SetVisibilityConfig(self.waf.sWebDetails.VisibilityConfig)
client, err := self.waf.region.getWafClient()
if err != nil {
return errors.Wrapf(err, "getWafClient")
}
_, err = client.UpdateWebACL(&input)
return errors.Wrapf(err, "UpdateWebACL")
}
func (self *sWafRule) Update(opts *cloudprovider.SWafRule) error {
return cloudprovider.ErrNotImplemented
}
func (self *sWafRule) GetStatementCondition() cloudprovider.TWafStatementCondition {
if self.Rule.Statement == nil {
return cloudprovider.WafStatementConditionNone
}
if self.Rule.Statement.AndStatement != nil {
return cloudprovider.WafStatementConditionAnd
} else if self.Rule.Statement.OrStatement != nil {
return cloudprovider.WafStatementConditionOr
} else if self.Rule.Statement.NotStatement != nil {
return cloudprovider.WafStatementConditionNot
}
return cloudprovider.WafStatementConditionNone
}
type sWafStatement struct {
*wafv2.Statement
}
func (self *sWafStatement) convert() cloudprovider.SWafStatement {
statement := cloudprovider.SWafStatement{
Transformations: &cloudprovider.TextTransformations{},
}
if self.ByteMatchStatement != nil {
statement.Type = cloudprovider.WafStatementTypeByteMatch
if self.ByteMatchStatement.PositionalConstraint != nil {
operator := strings.ReplaceAll(utils.CamelSplit(*self.ByteMatchStatement.PositionalConstraint, "_"), "_", "")
if operator == "None" {
operator = ""
}
statement.Operator = cloudprovider.TWafOperator(operator)
}
fillStatement(&statement, self.ByteMatchStatement.FieldToMatch)
statement.SearchString = string(self.ByteMatchStatement.SearchString)
fillTransformations(&statement, self.ByteMatchStatement.TextTransformations)
} else if self.GeoMatchStatement != nil {
statement.Type = cloudprovider.WafStatementTypeGeoMatch
statement.MatchFieldKey = "CountryCodes"
values := cloudprovider.TWafMatchFieldValues{}
for _, code := range self.GeoMatchStatement.CountryCodes {
values = append(values, *code)
}
statement.MatchFieldValues = &values
if self.GeoMatchStatement.ForwardedIPConfig != nil {
statement.ForwardedIPHeader = *self.GeoMatchStatement.ForwardedIPConfig.HeaderName
}
} else if self.IPSetReferenceStatement != nil {
statement.Type = cloudprovider.WafStatementTypeIPSet
statement.IPSetId = *self.IPSetReferenceStatement.ARN
if self.IPSetReferenceStatement.IPSetForwardedIPConfig != nil {
statement.ForwardedIPHeader = *self.IPSetReferenceStatement.IPSetForwardedIPConfig.HeaderName
}
} else if self.ManagedRuleGroupStatement != nil {
statement.Type = cloudprovider.WafStatementTypeManagedRuleGroup
statement.ManagedRuleGroupName = *self.ManagedRuleGroupStatement.Name
fillExcludeRules(&statement, self.ManagedRuleGroupStatement.ExcludedRules)
} else if self.RateBasedStatement != nil {
statement.Type = cloudprovider.WafStatementTypeRate
statement.Limit = self.RateBasedStatement.Limit
if self.RateBasedStatement.ForwardedIPConfig != nil {
statement.ForwardedIPHeader = *self.RateBasedStatement.ForwardedIPConfig.HeaderName
}
} else if self.RegexPatternSetReferenceStatement != nil {
statement.Type = cloudprovider.WafStatementTypeRegexSet
statement.RegexSetId = *self.RegexPatternSetReferenceStatement.ARN
fillStatement(&statement, self.RegexPatternSetReferenceStatement.FieldToMatch)
} else if self.RuleGroupReferenceStatement != nil {
statement.Type = cloudprovider.WafStatementTypeRuleGroup
statement.RuleGroupId = *self.RuleGroupReferenceStatement.ARN
fillExcludeRules(&statement, self.RuleGroupReferenceStatement.ExcludedRules)
} else if self.SizeConstraintStatement != nil {
statement.Type = cloudprovider.WafStatementTypeSize
statement.Operator = cloudprovider.TWafOperator(*self.SizeConstraintStatement.ComparisonOperator)
statement.Size = self.SizeConstraintStatement.Size
fillStatement(&statement, self.SizeConstraintStatement.FieldToMatch)
fillTransformations(&statement, self.SizeConstraintStatement.TextTransformations)
} else if self.SqliMatchStatement != nil {
statement.Type = cloudprovider.WafStatementTypeSqliMatch
fillStatement(&statement, self.SqliMatchStatement.FieldToMatch)
fillTransformations(&statement, self.SqliMatchStatement.TextTransformations)
} else if self.XssMatchStatement != nil {
statement.Type = cloudprovider.WafStatementTypeXssMatch
fillStatement(&statement, self.XssMatchStatement.FieldToMatch)
fillTransformations(&statement, self.XssMatchStatement.TextTransformations)
}
return statement
}
func fillStatement(statement *cloudprovider.SWafStatement, field *wafv2.FieldToMatch) {
if field.AllQueryArguments != nil {
statement.MatchField = cloudprovider.WafMatchFieldQuery
statement.MatchFieldKey = "AllArguments"
} else if field.Body != nil {
statement.MatchField = cloudprovider.WafMatchFieldBody
} else if field.Method != nil {
statement.MatchField = cloudprovider.WafMatchFieldMethod
} else if field.QueryString != nil {
statement.MatchField = cloudprovider.WafMatchFieldQuery
} else if field.SingleHeader != nil {
statement.MatchField = cloudprovider.WafMatchFiledHeader
statement.MatchFieldKey = *field.SingleHeader.Name
} else if field.SingleQueryArgument != nil {
statement.MatchField = cloudprovider.WafMatchFieldQuery
statement.MatchFieldKey = "SingleArgument"
} else if field.UriPath != nil {
statement.MatchField = cloudprovider.WafMatchFiledUriPath
}
}
func fillTransformations(statement *cloudprovider.SWafStatement, trans []*wafv2.TextTransformation) {
values := cloudprovider.TextTransformations{}
for _, tran := range trans {
switch *tran.Type {
case wafv2.TextTransformationTypeNone:
values = append(values, cloudprovider.WafTextTransformationNone)
case wafv2.TextTransformationTypeLowercase:
values = append(values, cloudprovider.WafTextTransformationLowercase)
case wafv2.TextTransformationTypeCmdLine:
values = append(values, cloudprovider.WafTextTransformationCmdLine)
case wafv2.TextTransformationTypeUrlDecode:
values = append(values, cloudprovider.WafTextTransformationUrlDecode)
case wafv2.TextTransformationTypeHtmlEntityDecode:
values = append(values, cloudprovider.WafTextTransformationHtmlEntityDecode)
case wafv2.TextTransformationTypeCompressWhiteSpace:
values = append(values, cloudprovider.WafTextTransformationCompressWithSpace)
}
}
statement.Transformations = &values
}
func fillExcludeRules(statement *cloudprovider.SWafStatement, rules []*wafv2.ExcludedRule) {
values := cloudprovider.SExcludeRules{}
for _, rule := range rules {
values = append(values, cloudprovider.SExcludeRule{Name: *rule.Name})
}
statement.ExcludeRules = &values
}
func (self *sWafRule) GetStatements() ([]cloudprovider.SWafStatement, error) {
if self.Rule.Statement == nil {
return []cloudprovider.SWafStatement{}, nil
}
ret := []cloudprovider.SWafStatement{}
if self.Rule.Statement.AndStatement != nil {
for i := range self.Rule.Statement.AndStatement.Statements {
statement := sWafStatement{self.Rule.Statement.AndStatement.Statements[i]}
ret = append(ret, statement.convert())
}
} else if self.Rule.Statement.OrStatement != nil {
for i := range self.Rule.Statement.OrStatement.Statements {
statement := sWafStatement{self.Rule.Statement.OrStatement.Statements[i]}
ret = append(ret, statement.convert())
}
} else if self.Rule.Statement.NotStatement != nil {
statement := sWafStatement{self.Rule.Statement.NotStatement.Statement}
ret = append(ret, statement.convert())
} else {
statement := sWafStatement{self.Rule.Statement}
ret = append(ret, statement.convert())
}
return ret, nil
}
func (self *SWebAcl) GetRules() ([]cloudprovider.ICloudWafRule, error) {
ret := []cloudprovider.ICloudWafRule{}
for i := range self.sWebDetails.Rules {
ret = append(ret, &sWafRule{
waf: self,
Rule: self.sWebDetails.Rules[i],
})
}
return ret, nil
}
+15
View File
@@ -435,6 +435,18 @@ func (self *SAzureClient) _apiVersion(resource string, params url.Values) string
if utils.IsInStringArray("publicipaddresses", info) {
return "2018-03-01"
}
if utils.IsInStringArray("frontdoorwebapplicationfirewallmanagedrulesets", info) {
return "2020-11-01"
}
if utils.IsInStringArray("frontdoorwebapplicationfirewallpolicies", info) {
return "2020-11-01"
}
if utils.IsInStringArray("applicationgatewaywebapplicationfirewallpolicies", info) {
return "2020-11-01"
}
if utils.IsInStringArray("applicationgatewayavailablewafrulesets", info) {
return "2018-06-01"
}
return "2018-06-01"
} else if utils.IsInStringArray("microsoft.classicnetwork", info) {
return "2016-04-01"
@@ -488,6 +500,9 @@ func (self *SAzureClient) _list(resource string, params url.Values) (jsonutils.J
return nil, fmt.Errorf("no avaiable subscriptions")
}
path = fmt.Sprintf("subscriptions/%s/%s", subId, resource)
case "Microsoft.Network/frontdoorWebApplicationFirewallPolicies":
path = fmt.Sprintf("subscriptions/%s/resourceGroups/%s/providers/%s", subId, params.Get("resourceGroups"), resource)
params.Del("resourceGroups")
default:
if len(subId) == 0 {
return nil, fmt.Errorf("no avaiable subscriptions")
+70
View File
@@ -0,0 +1,70 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package shell
import (
"yunion.io/x/onecloud/pkg/multicloud/azure"
"yunion.io/x/onecloud/pkg/util/shellutils"
)
func init() {
type RuleGroupListOptions struct {
}
shellutils.R(&RuleGroupListOptions{}, "waf-rule-group-list", "List waf rule groups", func(cli *azure.SRegion, args *RuleGroupListOptions) error {
groups, err := cli.ListAppWafManagedRuleGroup()
if err != nil {
return err
}
printList(groups, len(groups), 0, 0, []string{})
return nil
})
type FrontDoorPolicyListOptions struct {
RESOURCE_GROUP string
}
shellutils.R(&FrontDoorPolicyListOptions{}, "front-door-policy-list", "List front door policies", func(cli *azure.SRegion, args *FrontDoorPolicyListOptions) error {
policies, err := cli.ListFrontDoorWafs(args.RESOURCE_GROUP)
if err != nil {
return err
}
printList(policies, 0, 0, 0, []string{})
return nil
})
type AppGatewayWafListOptions struct {
}
shellutils.R(&AppGatewayWafListOptions{}, "app-gateway-waf-list", "List app gateway wafs", func(cli *azure.SRegion, args *AppGatewayWafListOptions) error {
wafs, err := cli.ListAppWafs()
if err != nil {
return err
}
printList(wafs, 0, 0, 0, []string{})
return nil
})
type AppGatewayWafRuleGroupListOptions struct {
}
shellutils.R(&AppGatewayWafRuleGroupListOptions{}, "app-gateway-waf-rule-group-list", "List app gateway wafs", func(cli *azure.SRegion, args *AppGatewayWafRuleGroupListOptions) error {
group, err := cli.ListAppWafManagedRuleGroup()
if err != nil {
return err
}
printList(group, 0, 0, 0, []string{})
return nil
})
}
+617
View File
@@ -0,0 +1,617 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package azure
import (
"fmt"
"net/url"
"strings"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/onecloud/pkg/multicloud"
)
type SMatchvariable struct {
Variablename string `json:"variableName"`
Selector string `json:"selector"`
}
type SMatchcondition struct {
Matchvariables []SMatchvariable `json:"matchVariables"`
Operator string `json:"operator"`
Negationconditon bool `json:"negationConditon"`
Matchvalues []string `json:"matchValues"`
Transforms []string `json:"transforms"`
}
type CustomRule struct {
waf *SAppGatewayWaf
Name string `json:"name"`
Priority int `json:"priority"`
Ruletype string `json:"ruleType"`
//RateLimitThreshold *int `json:"rateLimitThreshold"`
Matchconditions []SMatchcondition `json:"matchConditions"`
Action string `json:"action"`
}
func (self *CustomRule) GetName() string {
return self.Name
}
func (self *CustomRule) GetGlobalId() string {
return fmt.Sprintf("%s-%s", self.waf.GetGlobalId(), self.GetName())
}
func (self *CustomRule) GetDesc() string {
return ""
}
func (self *CustomRule) GetPriority() int {
return self.Priority
}
func (self *CustomRule) Delete() error {
rules := []CustomRule{}
for _, rule := range self.waf.Properties.Customrules {
if rule.Name != self.Name {
rules = append(rules, rule)
}
}
self.waf.Properties.Customrules = rules
return self.waf.region.update(jsonutils.Marshal(self.waf), nil)
}
func wafMatchFieldAndKeyLocal2Cloud(opts cloudprovider.SWafStatement) ([]SMatchvariable, error) {
ret := []SMatchvariable{}
switch opts.MatchField {
case cloudprovider.WafMatchFieldQuery:
ret = append(ret, SMatchvariable{
Variablename: "QueryString",
})
case cloudprovider.WafMatchFieldMethod:
ret = append(ret, SMatchvariable{
Variablename: "RequestMethod",
})
case cloudprovider.WafMatchFiledUriPath:
ret = append(ret, SMatchvariable{
Variablename: "RequestUri",
})
case cloudprovider.WafMatchFiledHeader:
ret = append(ret, SMatchvariable{
Variablename: "RequestHeaders",
Selector: opts.MatchFieldKey,
})
case cloudprovider.WafMatchFiledPostArgs:
ret = append(ret, SMatchvariable{
Variablename: "PostArgs",
Selector: opts.MatchFieldKey,
})
case cloudprovider.WafMatchFieldBody:
ret = append(ret, SMatchvariable{
Variablename: "RequestBody",
})
case cloudprovider.WafMatchFiledCookie:
ret = append(ret, SMatchvariable{
Variablename: "RequestCookies",
Selector: opts.MatchFieldKey,
})
default:
return ret, fmt.Errorf("unsupported match filed %s", opts.MatchField)
}
return ret, nil
}
func wafMatchFieldAndKeyCloud2Local(vars []SMatchvariable) (cloudprovider.TWafMatchField, string, error) {
for _, v := range vars {
switch v.Variablename {
case "QueryString":
return cloudprovider.WafMatchFieldQuery, v.Selector, nil
case "RequestMethod":
return cloudprovider.WafMatchFieldMethod, "", nil
case "RequestUri":
return cloudprovider.WafMatchFiledUriPath, "", nil
case "RequestHeaders":
return cloudprovider.WafMatchFiledHeader, v.Selector, nil
case "PostArgs":
return cloudprovider.WafMatchFiledPostArgs, v.Selector, nil
case "RequestBody":
return cloudprovider.WafMatchFieldBody, "", nil
case "RequestCookies":
return cloudprovider.WafMatchFiledCookie, v.Selector, nil
default:
return "", "", fmt.Errorf("invalid variablename %s", v.Variablename)
}
}
return "", "", nil
}
func wafStatementLocal2Cloud(opts cloudprovider.SWafStatement) (SMatchcondition, error) {
ret := SMatchcondition{}
if opts.Transformations != nil {
for _, tran := range *opts.Transformations {
ret.Transforms = append(ret.Transforms, string(tran))
}
}
if opts.MatchFieldValues != nil {
ret.Matchvalues = *opts.MatchFieldValues
}
ret.Negationconditon = opts.Negation
ret.Operator = string(opts.Operator)
var err error
switch opts.Type {
case cloudprovider.WafStatementTypeIPSet:
ret.Operator = "IPMatch"
ret.Matchvariables = []SMatchvariable{
SMatchvariable{
Variablename: "RemoteAddr",
},
}
case cloudprovider.WafStatementTypeGeoMatch:
ret.Operator = "GeoMatch"
if len(opts.ForwardedIPHeader) == 0 {
ret.Matchvariables = []SMatchvariable{
SMatchvariable{
Variablename: "RemoteAddr",
},
}
} else {
ret.Matchvariables = []SMatchvariable{
SMatchvariable{
Variablename: "RequestHeaders",
Selector: opts.ForwardedIPHeader,
},
}
}
case cloudprovider.WafStatementTypeSize:
switch opts.Operator {
case "LT":
ret.Operator = "LessThan"
case "LE":
ret.Operator = "LessThanOrEqual"
case "GT":
ret.Operator = "GreaterThan"
default:
return ret, fmt.Errorf("invalid operator %s for %s", opts.Operator, opts.Type)
}
ret.Matchvariables, err = wafMatchFieldAndKeyLocal2Cloud(opts)
if err != nil {
return ret, errors.Wrapf(err, "wafMatchFieldAndKeyLocal2Cloud")
}
case cloudprovider.WafStatementTypeByteMatch:
switch opts.Operator {
case "Contains", "EndsWith", "Regex":
case "StartsWith":
ret.Operator = "BeginsWith"
case "Exactly":
ret.Operator = "Equal"
default:
return ret, fmt.Errorf("invalid operator %s for %s", opts.Operator, opts.Type)
}
ret.Matchvariables, err = wafMatchFieldAndKeyLocal2Cloud(opts)
if err != nil {
return ret, errors.Wrapf(err, "wafMatchFieldAndKeyLocal2Cloud")
}
}
return ret, nil
}
func wafRuleLocal2Cloud(opts *cloudprovider.SWafRule) (*CustomRule, error) {
ret := &CustomRule{}
ret.Name = opts.Name
ret.Priority = opts.Priority
ret.Ruletype = "MatchRule"
ret.Matchconditions = []SMatchcondition{}
for _, s := range opts.Statements {
cds, err := wafStatementLocal2Cloud(s)
if err != nil {
return nil, errors.Wrapf(err, "wafStatementLocal2Cloud")
}
ret.Matchconditions = append(ret.Matchconditions, cds)
}
ret.Action = "Block"
if opts.Action != nil {
ret.Action = string(opts.Action.Action)
}
return ret, nil
}
func (self *CustomRule) Update(opts *cloudprovider.SWafRule) error {
rules := []CustomRule{}
for _, rule := range self.waf.Properties.Customrules {
if rule.Name != self.Name {
rules = append(rules, rule)
} else {
rule, err := wafRuleLocal2Cloud(opts)
if err != nil {
return errors.Wrapf(err, "wafRuleLocal2Cloud")
}
rules = append(rules, *rule)
}
}
self.waf.Properties.Customrules = rules
return self.waf.region.update(jsonutils.Marshal(self.waf), nil)
}
func (self *CustomRule) GetAction() *cloudprovider.DefaultAction {
return &cloudprovider.DefaultAction{
Action: cloudprovider.TWafAction(self.Action),
}
}
func (self *CustomRule) GetStatementCondition() cloudprovider.TWafStatementCondition {
return cloudprovider.WafStatementConditionAnd
}
func (self *CustomRule) GetStatements() ([]cloudprovider.SWafStatement, error) {
ret := []cloudprovider.SWafStatement{}
for _, condition := range self.Matchconditions {
trans := cloudprovider.TextTransformations{}
for _, tran := range condition.Transforms {
trans = append(trans, cloudprovider.TWafTextTransformation(tran))
}
values := cloudprovider.TWafMatchFieldValues(condition.Matchvalues)
statement := cloudprovider.SWafStatement{
Negation: condition.Negationconditon,
Transformations: &trans,
MatchFieldValues: &values,
}
statement.MatchField, statement.MatchFieldKey, _ = wafMatchFieldAndKeyCloud2Local(condition.Matchvariables)
switch condition.Operator {
case "IPMatch":
statement.Type = cloudprovider.WafStatementTypeIPSet
case "GeoMatch":
statement.Type = cloudprovider.WafStatementTypeGeoMatch
case "LessThan":
statement.Type = cloudprovider.WafStatementTypeSize
statement.Operator = cloudprovider.WafOperatorLT
case "LessThanOrEqual":
statement.Type = cloudprovider.WafStatementTypeSize
statement.Operator = cloudprovider.WafOperatorLE
case "GreaterThan":
statement.Type = cloudprovider.WafStatementTypeSize
statement.Operator = cloudprovider.WafOperatorGT
case "BeginsWith":
statement.Type = cloudprovider.WafStatementTypeByteMatch
statement.Operator = cloudprovider.WafOperatorStartsWith
case "Contains", "EndsWith", "Regex":
statement.Type = cloudprovider.WafStatementTypeByteMatch
statement.Operator = cloudprovider.TWafOperator(condition.Operator)
case "Equal":
statement.Type = cloudprovider.WafStatementTypeByteMatch
statement.Operator = cloudprovider.WafOperatorExactly
default:
statement.Type = cloudprovider.WafStatementTypeByteMatch
}
ret = append(ret, statement)
}
return ret, nil
}
type ManagedRule struct {
Rulesettype string `json:"ruleSetType"`
Rulesetversion string `json:"ruleSetVersion"`
}
type ManagedRules struct {
waf *SAppGatewayWaf
Managedrulesets []ManagedRule `json:"managedRuleSets"`
}
func (self *ManagedRules) GetName() string {
return fmt.Sprintf("%s Managed rules", self.waf.GetName())
}
func (self *ManagedRules) GetGlobalId() string {
return self.waf.GetGlobalId()
}
func (self *ManagedRules) GetDesc() string {
return ""
}
func (self *ManagedRules) GetPriority() int {
return 0
}
func (self *ManagedRules) GetAction() *cloudprovider.DefaultAction {
return nil
}
func (self *ManagedRules) Delete() error {
return cloudprovider.ErrNotSupported
}
func (self *ManagedRules) Update(opts *cloudprovider.SWafRule) error {
rules := []ManagedRule{}
for _, s := range opts.Statements {
if len(s.ManagedRuleGroupName) == 0 {
return fmt.Errorf("missing managed rule group name")
}
names := strings.Split(s.ManagedRuleGroupName, "_")
if len(names) != 2 {
return fmt.Errorf("invalid managed rule group name %s", s.ManagedRuleGroupName)
}
rules = append(rules, ManagedRule{
Rulesettype: names[0],
Rulesetversion: names[1],
})
}
if len(rules) == 0 {
return fmt.Errorf("missing statements")
}
self.waf.Properties.Managedrules = ManagedRules{
Managedrulesets: rules,
}
return self.waf.region.update(jsonutils.Marshal(self.waf), nil)
}
func (self *ManagedRules) GetStatementCondition() cloudprovider.TWafStatementCondition {
return cloudprovider.WafStatementConditionAnd
}
func (self *ManagedRules) GetStatements() ([]cloudprovider.SWafStatement, error) {
ret := []cloudprovider.SWafStatement{}
for i := range self.Managedrulesets {
ruleGroupName := fmt.Sprintf("%s_%s", self.Managedrulesets[i].Rulesettype, self.Managedrulesets[i].Rulesetversion)
ret = append(ret, cloudprovider.SWafStatement{
ManagedRuleGroupName: ruleGroupName,
Type: cloudprovider.WafStatementTypeManagedRuleGroup,
RuleGroupId: ruleGroupName,
})
}
return ret, nil
}
type SAppGatewayWaf struct {
multicloud.SResourceBase
multicloud.AzureTags
region *SRegion
Name string `json:"name"`
ID string `json:"id"`
Type string `json:"type"`
Location string `json:"location"`
Properties struct {
ApplicationGateways []SApplicationGateway
HttpListeners []struct {
Id string
}
Resourcestate string `json:"resourceState"`
Provisioningstate string `json:"provisioningState"`
Policysettings struct {
State string `json:"state"`
Mode string `json:"mode"`
Maxrequestbodysizeinkb int `json:"maxRequestBodySizeInKb"`
Fileuploadlimitinmb int `json:"fileUploadLimitInMb"`
Requestbodycheck bool `json:"requestBodyCheck"`
} `json:"policySettings"`
Customrules []CustomRule `json:"customRules"`
Managedrules ManagedRules `json:"managedRules"`
} `json:"properties"`
}
func (self *SAppGatewayWaf) GetEnabled() bool {
return self.Properties.Policysettings.State == "Enabled"
}
func (self *SAppGatewayWaf) GetName() string {
return self.Name
}
func (self *SAppGatewayWaf) GetId() string {
return self.ID
}
func (self *SAppGatewayWaf) GetGlobalId() string {
return strings.ToLower(self.ID)
}
func (self *SAppGatewayWaf) Delete() error {
return self.region.del(self.ID)
}
func (self *SAppGatewayWaf) GetWafType() cloudprovider.TWafType {
return cloudprovider.WafTypeAppGateway
}
func (self *SAppGatewayWaf) AddRule(opts *cloudprovider.SWafRule) (cloudprovider.ICloudWafRule, error) {
rule, err := wafRuleLocal2Cloud(opts)
if err != nil {
return nil, errors.Wrapf(err, "wafRuleLocal2Cloud")
}
rule.waf = self
self.Properties.Customrules = append(self.Properties.Customrules, *rule)
err = self.region.update(jsonutils.Marshal(self), nil)
if err != nil {
return nil, errors.Wrapf(err, "update")
}
return rule, nil
}
func (self *SAppGatewayWaf) GetStatus() string {
switch self.Properties.Provisioningstate {
case "Deleting":
return api.WAF_STATUS_DELETING
case "Failed":
return api.WAF_STATUS_CREATE_FAILED
case "Succeeded":
return api.WAF_STATUS_AVAILABLE
case "Updating":
return api.WAF_STATUS_UPDATING
default:
return self.Properties.Provisioningstate
}
}
func (self *SAppGatewayWaf) GetRules() ([]cloudprovider.ICloudWafRule, error) {
ret := []cloudprovider.ICloudWafRule{}
for i := range self.Properties.Customrules {
self.Properties.Customrules[i].waf = self
ret = append(ret, &self.Properties.Customrules[i])
}
self.Properties.Managedrules.waf = self
ret = append(ret, &self.Properties.Managedrules)
return ret, nil
}
func (self *SAppGatewayWaf) Refresh() error {
waf, err := self.region.GetAppGatewayWaf(self.ID)
if err != nil {
return errors.Wrapf(err, "GetAppGatewayWa")
}
return jsonutils.Update(self, waf)
}
func (self *SAppGatewayWaf) GetDefaultAction() *cloudprovider.DefaultAction {
return &cloudprovider.DefaultAction{}
}
func (self *SRegion) ListAppWafs() ([]SAppGatewayWaf, error) {
ret := []SAppGatewayWaf{}
err := self.list("Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies", url.Values{}, &ret)
if err != nil {
return nil, errors.Wrapf(err, "list")
}
return ret, nil
}
type SAppWafRuleGroup struct {
Name string `json:"name"`
ID string `json:"id"`
Type string `json:"type"`
Properties struct {
Provisioningstate string `json:"provisioningState"`
Rulesettype string `json:"ruleSetType"`
Rulesetversion string `json:"ruleSetVersion"`
Rulegroups []struct {
Rulegroupname string `json:"ruleGroupName"`
Description string `json:"description"`
Rules []struct {
Ruleid int `json:"ruleId"`
Description string `json:"description"`
} `json:"rules"`
} `json:"ruleGroups"`
} `json:"properties"`
}
func (self *SRegion) CreateICloudWafInstance(opts *cloudprovider.WafCreateOptions) (cloudprovider.ICloudWafInstance, error) {
switch opts.Type {
case cloudprovider.WafTypeAppGateway:
return self.CreateAppWafInstance(opts.Name, opts.DefaultAction)
default:
return nil, errors.Wrapf(cloudprovider.ErrNoSuchProvder, "invalid waf type %s", opts.Type)
}
}
func (self *SRegion) GetICloudWafInstanceById(id string) (cloudprovider.ICloudWafInstance, error) {
if strings.Contains(id, "microsoft.network/applicationgatewaywebapplicationfirewallpolicies") {
return self.GetAppGatewayWaf(id)
}
return nil, errors.Wrapf(cloudprovider.ErrNotSupported, id)
}
func (self *SRegion) CreateAppWafInstance(name string, action *cloudprovider.DefaultAction) (*SAppGatewayWaf, error) {
mode := cloudprovider.WafActionDetection
if action != nil {
switch action.Action {
case cloudprovider.WafActionDetection, cloudprovider.WafActionPrevention:
mode = action.Action
default:
return nil, errors.Wrapf(cloudprovider.ErrNotSupported, "invalid action %s", action.Action)
}
}
params := map[string]interface{}{
"Type": "Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies",
"Name": name,
"Location": self.Name,
"properties": map[string]interface{}{
"customRules": []string{},
"policySettings": map[string]interface{}{
"fileUploadLimitInMb": 100,
"maxRequestBodySizeInKb": 128,
"mode": mode,
"requestBodyCheck": true,
"state": "Enabled",
},
"managedRules": map[string]interface{}{
"exclusions": []string{},
"managedRuleSets": []map[string]interface{}{
map[string]interface{}{
"ruleSetType": "OWASP",
"ruleSetVersion": "3.1",
"ruleGroupOverrides": []string{},
},
},
},
},
}
ret := &SAppGatewayWaf{region: self}
err := self.create("", jsonutils.Marshal(params), ret)
if err != nil {
return nil, err
}
return ret, nil
}
func (self *SRegion) GetAppGatewayWaf(id string) (*SAppGatewayWaf, error) {
res := &SAppGatewayWaf{region: self}
return res, self.get(id, nil, &res)
}
func (self *SRegion) ListAppWafManagedRuleGroup() ([]SAppWafRuleGroup, error) {
ret := []SAppWafRuleGroup{}
err := self.list("Microsoft.Network/applicationGatewayAvailableWafRuleSets", url.Values{}, &ret)
if err != nil {
return nil, errors.Wrapf(err, "list")
}
return ret, nil
}
func (self *SRegion) GetICloudWafInstances() ([]cloudprovider.ICloudWafInstance, error) {
wafs, err := self.ListAppWafs()
if err != nil {
return nil, errors.Wrapf(err, "ListAppWafs")
}
ret := []cloudprovider.ICloudWafInstance{}
for i := range wafs {
wafs[i].region = self
ret = append(ret, &wafs[i])
}
return ret, nil
}
func (self *SAppGatewayWaf) GetCloudResources() ([]cloudprovider.SCloudResource, error) {
ret := []cloudprovider.SCloudResource{}
for _, ag := range self.Properties.ApplicationGateways {
ret = append(ret, cloudprovider.SCloudResource{
Id: ag.ID,
Type: "app_gateway",
CanDissociate: true,
})
}
for _, lis := range self.Properties.HttpListeners {
ret = append(ret, cloudprovider.SCloudResource{
Id: lis.Id,
Type: "http_listener",
CanDissociate: true,
})
}
return ret, nil
}
+69
View File
@@ -0,0 +1,69 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package azure
import "net/url"
type SFrontDoorProperties struct {
ResourceState string
ProvisioningState string
PolicySettings struct {
EnabledState string
Mode string
RedirectUrl string
CustomBlockResponseStatusCode int
CustomBlockResponseBody string
RequestBodyCheck string
}
CustomRules struct {
Rules []struct{}
}
ManagedRules struct {
ManagedRuleSets []struct {
RuleSetType string
RuleSetVersion string
RuleSetAction string
RuleGroupOverrides []struct {
}
Exclusions []struct{}
}
}
FrontendEndpointLinks []struct{}
RoutingRuleLinks []struct{}
SecurityPolicyLinks []struct{}
}
type SFrontDoorWaf struct {
Id string
Name string
Type string
Tags map[string]string
Location string
Sku struct {
Name string
}
Properties SFrontDoorProperties
}
func (self *SRegion) ListFrontDoorWafs(resGroup string) ([]SFrontDoorWaf, error) {
params := url.Values{}
params.Set("resourceGroups", resGroup)
ret := []SFrontDoorWaf{}
err := self.list("Microsoft.Network/frontdoorWebApplicationFirewallPolicies", params, &ret)
if err != nil {
return nil, err
}
return ret, nil
}
+54
View File
@@ -0,0 +1,54 @@
// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package azure
import "net/url"
type SWafRule struct {
RuleId string
Description string
DefaultAction string
DefaultState string
}
type SRuleGroup struct {
ruleGroupName string
description string
Rules []SWafRule
}
type SManagedRuleGroupProperties struct {
ProvisioningState string
RuleSetId string
RuleSetType string
RuleSetVersion string
RuleGroups []SRuleGroup
}
type SManagedRuleGroup struct {
Name string
Id string
Type string
Properties SManagedRuleGroupProperties
}
func (self *SRegion) ListManagedRuleGroups() ([]SManagedRuleGroup, error) {
groups := []SManagedRuleGroup{}
err := self.list("Microsoft.Network/FrontDoorWebApplicationFirewallManagedRuleSets", url.Values{}, &groups)
if err != nil {
return nil, err
}
return groups, nil
}
+24
View File
@@ -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")
}
File diff suppressed because it is too large Load Diff
+88
View File
@@ -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
View File
@@ -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 couldnt perform the operation because your resource is being used
// by another resource or its associated with another resource.
ErrCodeWAFAssociatedItemException = "WAFAssociatedItemException"
// ErrCodeWAFDuplicateItemException for service response error code
// "WAFDuplicateItemException".
//
// AWS WAF couldnt 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 couldnt 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 cant 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 couldnt perform the operation because the resource that you requested
// isnt valid. Check the resource, and try again.
ErrCodeWAFInvalidResourceException = "WAFInvalidResourceException"
// ErrCodeWAFLimitsExceededException for service response error code
// "WAFLimitsExceededException".
//
// AWS WAF couldnt 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 couldnt perform the operation because your resource doesnt
// exist.
ErrCodeWAFNonexistentItemException = "WAFNonexistentItemException"
// ErrCodeWAFOptimisticLockException for service response error code
// "WAFOptimisticLockException".
//
// AWS WAF couldnt 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 couldnt perform your tagging operation because of an internal
// error. Retry your request.
ErrCodeWAFTagOperationInternalErrorException = "WAFTagOperationInternalErrorException"
// ErrCodeWAFUnavailableEntityException for service response error code
// "WAFUnavailableEntityException".
//
// AWS WAF couldnt 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
View File
@@ -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
}
+1
View File
@@ -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