Skip to content

Commit 5493a44

Browse files
committed
Add support for WAAS
1 parent 6d57acd commit 5493a44

23 files changed

+7555
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- Support for importing Buckets and Pre-authenticated requests in Object Storage
55
- Support glob inclusion and exclusion patterns for object names allowed in Object Storage Lifecycle
66
- Support for sorting for resources returned in `oci_core_images` data source
7+
- Support for Web Application Acceleration and Security service
78

89
### Fixed
910
- Import functionality for Objects in Object Storage

docs/examples/waas/waas_full.tf

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
// Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
2+
3+
variable "tenancy_ocid" {}
4+
variable "user_ocid" {}
5+
variable "fingerprint" {}
6+
variable "private_key_path" {}
7+
variable "region" {}
8+
variable "compartment_ocid" {}
9+
10+
variable "certificate_display_name" {
11+
default = "tf_example_waas_certificate"
12+
}
13+
14+
variable "waas_policy_display_name" {
15+
default = "tf_example_waas_policy"
16+
}
17+
18+
provider "oci" {
19+
tenancy_ocid = "${var.tenancy_ocid}"
20+
user_ocid = "${var.user_ocid}"
21+
fingerprint = "${var.fingerprint}"
22+
private_key_path = "${var.private_key_path}"
23+
region = "${var.region}"
24+
}
25+
26+
resource "oci_waas_certificate" "test_certificate" {
27+
#Required
28+
certificate_data = "-----BEGIN CERTIFICATE-----\nMIIC9jCCAd4CCQD2rPUVJETHGzANBgkqhkiG9w0BAQsFADA9MQswCQYDVQQGEwJV\nUzELMAkGA1UECAwCV0ExEDAOBgNVBAcMB1NlYXR0bGUxDzANBgNVBAoMBk9yYWNs\nZTAeFw0xOTAxMTcyMjU4MDVaFw0yMTAxMTYyMjU4MDVaMD0xCzAJBgNVBAYTAlVT\nMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTEPMA0GA1UECgwGT3JhY2xl\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA30+wt7OlUB/YpmWbTRkx\nnLG0lKWiV+oupNKj8luXmC5jvOFTUejt1pQhpA47nCqywlOAfk2N8hJWTyJZUmKU\n+DWVV2So2B/obYxpiiyWF2tcF/cYi1kBYeAIu5JkVFwDe4ITK/oQUFEhIn3Qg/oC\nMQ2985/MTdCXONgnbmePU64GrJwfvOeJcQB3VIL1BBfISj4pPw5708qTRv5MJBOO\njLKRM68KXC5us4879IrSA77NQr1KwjGnQlykyCgGvvgwgrUTd5c/dH8EKrZVcFi6\nytM66P/1CTpk1YpbI4gqiG0HBbuXG4JRIjyzW4GT4JXeSjgvrkIYL8k/M4Az1WEc\n2wIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAuI53m8Va6EafDi6GQdQrzNNQFCAVQ\nxIABAB0uaSYCs3H+pqTktHzOrOluSUEogXRl0UU5/OuvxAz4idA4cfBdId4i7AcY\nqZsBjA/xqH/rxR3pcgfaGyxQzrUsJFf0ZwnzqYJs7fUvuatHJYi/cRBxrKR2+4Oj\nlUbb9TSmezlzHK5CaD5XzN+lZqbsSvN3OQbOryJCbtjZVQFGZ1SmL6OLrwpbBKuP\nn2ob+gaP57YSzO3zk1NDXMlQPHRsdSOqocyKx8y+7J0g6MqPvBzIe+wI3QW85MQY\nj1/IHmj84LNGp7pHCyiYx/oI+00gRch04H2pJv0TP3sAQ37gplBwDrUo\n-----END CERTIFICATE-----"
29+
compartment_id = "${var.compartment_ocid}"
30+
private_key_data = "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEA30+wt7OlUB/YpmWbTRkxnLG0lKWiV+oupNKj8luXmC5jvOFT\nUejt1pQhpA47nCqywlOAfk2N8hJWTyJZUmKU+DWVV2So2B/obYxpiiyWF2tcF/cY\ni1kBYeAIu5JkVFwDe4ITK/oQUFEhIn3Qg/oCMQ2985/MTdCXONgnbmePU64GrJwf\nvOeJcQB3VIL1BBfISj4pPw5708qTRv5MJBOOjLKRM68KXC5us4879IrSA77NQr1K\nwjGnQlykyCgGvvgwgrUTd5c/dH8EKrZVcFi6ytM66P/1CTpk1YpbI4gqiG0HBbuX\nG4JRIjyzW4GT4JXeSjgvrkIYL8k/M4Az1WEc2wIDAQABAoIBAGQznukfG/uS/qTT\njNcQifl0p8HXfLwUIa/lsJkMTj6D+k8DkF59tVMGjv3NQSQ26JVX4J1L8XiAj+fc\nUtYr1Ap4CLX5PeYUkzesvKK6lPKXQvCh+Ip2eq9PVrvL2WcdDpb5695cy7suXD7c\n05aUtS0LrINH3eXAxkpEe5UHtQFni5YLrCLEXd+SSA3OKdCB+23HRELc1iCTvqjK\n5AtR916uHTBhtREHRMvWIdu4InRUsedlJhaJOLJ8G8r64JUtfm3wLUK1U8HFOsd0\nLAx9ZURU6cXl4osTWiy1vigGaM8Xuish2HkOLNYZADDUiDBB3SshmW5IDAJ5XTn5\nqVrszRECgYEA79j1y+WLTyV7yz7XkWk3OqoQXG4b2JfKItJI1M95UwllzQ8U/krM\n+QZjP3NTtB9i1YoHyaEfic103hV9Fkgz8jvKS5ocLGJulpN4CgqbHN6v9EJ3dqTk\no6X8mpx2eP2E0ngRekFyC/OCp0Zhe2KR9PXhijMa5eB2LTeCMIS/tzkCgYEA7lmk\nIdVjcpfqY7UFJ2R8zqPJHOne2+llrl9vzo6N5kx4DzAg7MP6XO9MekOvfmD1X1Lm\nFckXWFEF+0TlN5YvCTR/+OmVufYM3xp4GBT8RZdLFbyI4+xpAAeSC4SeM0ZkC9Jt\nrKqCS24+Kqy/+qSqtkxiPLQrXSdCSfCUlmn0ALMCgYBB7SLy3q+CG82BOk7Km18g\n8un4XhOtX1uiYqa+SCETH/wpd0HP/AOHV6gkIrEZS59BDuXBGFaw7BZ5jPKLE2Gj\n7adXTI797Dh1jydpqyyjrNo0i6iGpiBqkw9x+Bvged7ucy5qql6MxmxdSk01Owzf\nhk5uTEnScfZJy34vk+2WkQKBgBXx5uy+iuN4HTqE5i6UT/FunwusdLpmqNf/LXol\nIed8TumHEuD5wklgNvhi1vuZzb2zEkAbPa0B+L0DwN73UulUDhxK1WBDyTeZZklB\nVWDK5zzfGPNzRs+b4tRwp2gtKPT1sOde45QyWELxmNNo6dbS/ZB9Pijbfnz0S5n1\ns2OFAoGBAJUohI1+d2hKlkSUzpCorQarDe8lFVEbGMu0kX0JNDI7QU+H8vDp9NOl\nGqLm3sCVBYypT8sWfchgZpcVaLRLQCQtWy4+CbMN6DT3j/uBWeDpayU5Gvqt0/no\nvwqbG6b0NEYLRPLEdsS/c8TV9mMlvb0EW+GXfmkpTrTNt3hyXniu\n-----END RSA PRIVATE KEY-----"
31+
32+
#Optional
33+
display_name = "${var.certificate_display_name}"
34+
is_trust_verification_disabled = true
35+
}
36+
37+
data "oci_waas_certificates" "test_certificates" {
38+
#Required
39+
compartment_id = "${var.compartment_ocid}"
40+
41+
#Optional
42+
display_names = ["${var.certificate_display_name}"]
43+
ids = ["${oci_waas_certificate.test_certificate.id}"]
44+
}
45+
46+
resource "oci_waas_waas_policy" "test_waas_policy" {
47+
#Required
48+
compartment_id = "${var.compartment_ocid}"
49+
domain = "somethingnew42.oracle.com"
50+
51+
#Optional
52+
additional_domains = ["somethingnew1.oracle.com", "somethingnew2.oracle.com"]
53+
display_name = "${var.waas_policy_display_name}"
54+
55+
origins {
56+
#Required
57+
label = "primary"
58+
uri = "192.168.0.1"
59+
60+
#Optional
61+
custom_headers {
62+
#Required
63+
name = "name1"
64+
value = "value1"
65+
}
66+
67+
custom_headers {
68+
#Required
69+
name = "name2"
70+
value = "value2"
71+
}
72+
73+
http_port = "80"
74+
https_port = "443"
75+
}
76+
77+
origins {
78+
#Required
79+
label = "secondary"
80+
uri = "192.168.0.2"
81+
82+
#Optional
83+
custom_headers {
84+
#Required
85+
name = "name3"
86+
value = "value3"
87+
}
88+
89+
custom_headers {
90+
#Required
91+
name = "name4"
92+
value = "value4"
93+
}
94+
95+
http_port = "8080"
96+
https_port = "8443"
97+
}
98+
99+
policy_config {
100+
#Optional
101+
certificate_id = "${oci_waas_certificate.test_certificate.id}"
102+
is_https_enabled = true
103+
is_https_forced = true
104+
}
105+
106+
timeouts {
107+
create = "60m"
108+
delete = "60m"
109+
update = "60m"
110+
}
111+
112+
waf_config {
113+
#Optional
114+
access_rules {
115+
#Required
116+
action = "ALLOW"
117+
118+
criteria {
119+
#Required
120+
condition = "URL_IS"
121+
value = "/public"
122+
}
123+
124+
name = "tf_example_access_rule"
125+
126+
#Optional
127+
block_action = "SET_RESPONSE_CODE"
128+
block_error_page_code = 403
129+
block_error_page_description = "blockErrorPageDescription"
130+
block_error_page_message = "blockErrorPageMessage"
131+
block_response_code = 403
132+
}
133+
134+
address_rate_limiting {
135+
#Required
136+
is_enabled = true
137+
138+
#Optional
139+
allowed_rate_per_address = 10
140+
block_response_code = 403
141+
max_delayed_count_per_address = 10
142+
}
143+
144+
captchas {
145+
#Required
146+
failure_message = "message"
147+
session_expiration_in_seconds = 10
148+
submit_label = "label"
149+
title = "title"
150+
url = "url"
151+
152+
#Optional
153+
footer_text = "footer_text"
154+
header_text = "header_text"
155+
}
156+
157+
device_fingerprint_challenge {
158+
#Required
159+
is_enabled = true
160+
161+
#Optional
162+
action = "DETECT"
163+
action_expiration_in_seconds = 10
164+
165+
challenge_settings {
166+
#Optional
167+
block_action = "SET_RESPONSE_CODE"
168+
block_error_page_code = 403
169+
block_error_page_description = "blockErrorPageDescription"
170+
block_error_page_message = "blockErrorPageMessage"
171+
block_response_code = 403
172+
captcha_footer = "captchaFooter"
173+
captcha_header = "captchaHeader"
174+
captcha_submit_label = "captchaSubmitLabel"
175+
captcha_title = "captchaTitle"
176+
}
177+
178+
failure_threshold = 10
179+
failure_threshold_expiration_in_seconds = 10
180+
max_address_count = 10
181+
max_address_count_expiration_in_seconds = 10
182+
}
183+
184+
human_interaction_challenge {
185+
#Required
186+
is_enabled = true
187+
188+
#Optional
189+
action = "DETECT"
190+
action_expiration_in_seconds = 10
191+
192+
challenge_settings {
193+
#Optional
194+
block_action = "SET_RESPONSE_CODE"
195+
block_error_page_code = 403
196+
block_error_page_description = "blockErrorPageDescription"
197+
block_error_page_message = "blockErrorPageMessage"
198+
block_response_code = 403
199+
captcha_footer = "captchaFooter"
200+
captcha_header = "captchaHeader"
201+
captcha_submit_label = "captchaSubmitLabel"
202+
captcha_title = "captchaTitle"
203+
}
204+
205+
failure_threshold = 10
206+
failure_threshold_expiration_in_seconds = 10
207+
interaction_threshold = 10
208+
recording_period_in_seconds = 10
209+
210+
set_http_header {
211+
#Required
212+
name = "hc_name1"
213+
value = "hc_value1"
214+
}
215+
}
216+
217+
js_challenge {
218+
#Required
219+
is_enabled = true
220+
221+
#Optional
222+
action = "DETECT"
223+
action_expiration_in_seconds = 10
224+
225+
challenge_settings {
226+
#Optional
227+
block_action = "SET_RESPONSE_CODE"
228+
block_error_page_code = 403
229+
block_error_page_description = "blockErrorPageDescription"
230+
block_error_page_message = "blockErrorPageMessage"
231+
block_response_code = 403
232+
captcha_footer = "captchaFooter"
233+
captcha_header = "captchaHeader"
234+
captcha_submit_label = "captchaSubmitLabel"
235+
captcha_title = "captchaTitle"
236+
}
237+
238+
failure_threshold = 10
239+
}
240+
241+
origin = "primary"
242+
243+
protection_settings {
244+
#Optional
245+
allowed_http_methods = ["OPTIONS", "HEAD"]
246+
block_action = "SET_RESPONSE_CODE"
247+
block_error_page_code = 403
248+
block_error_page_description = "blockErrorPageDescription"
249+
block_error_page_message = "blockErrorPageMessage"
250+
block_response_code = 403
251+
is_response_inspected = false
252+
max_argument_count = 10
253+
max_name_length_per_argument = 10
254+
max_response_size_in_ki_b = 10
255+
max_total_name_length_of_arguments = 10
256+
media_types = ["application/plain", "application/json"]
257+
recommendations_period_in_days = 10
258+
}
259+
260+
whitelists {
261+
#Required
262+
addresses = ["192.168.127.127", "192.168.127.128"]
263+
name = "whitelist_name"
264+
}
265+
}
266+
}
267+
268+
data "oci_waas_waas_policies" "test_waas_policies" {
269+
#Required
270+
compartment_id = "${var.compartment_ocid}"
271+
272+
#Optional
273+
display_names = ["${var.waas_policy_display_name}"]
274+
ids = ["${oci_waas_waas_policy.test_waas_policy.id}"]
275+
states = ["ACTIVE"]
276+
time_created_greater_than_or_equal_to = "2018-01-01T00:00:00.000Z"
277+
time_created_less_than = "2038-01-01T00:00:00.000Z"
278+
}

oci/helpers_waas.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
2+
3+
package provider
4+
5+
import (
6+
"fmt"
7+
"strings"
8+
"time"
9+
10+
"context"
11+
12+
"github.com/hashicorp/terraform/helper/resource"
13+
oci_common "github.com/oracle/oci-go-sdk/common"
14+
oci_waas "github.com/oracle/oci-go-sdk/waas"
15+
)
16+
17+
func waasWorkRequestShouldRetryFunc(timeout time.Duration) func(response oci_common.OCIOperationResponse) bool {
18+
startTime := time.Now()
19+
stopTime := startTime.Add(timeout)
20+
return func(response oci_common.OCIOperationResponse) bool {
21+
22+
//Stop after timeout has elapsed
23+
if time.Now().After(stopTime) {
24+
return false
25+
}
26+
27+
//Make sure we stop on default rules
28+
if shouldRetry(response, false, "waas", startTime) {
29+
return true
30+
}
31+
32+
// Only stop if the time Finished is set
33+
if okeRes, ok := response.Response.(oci_waas.GetWorkRequestResponse); ok {
34+
return okeRes.TimeFinished == nil
35+
}
36+
return false
37+
}
38+
}
39+
40+
//waasWaitForWorkRequest custom logic to extract an identifier from a workRequest
41+
func waasWaitForWorkRequest(wId *string, entityType string, action oci_waas.WorkRequestResourceActionTypeEnum,
42+
timeout time.Duration, disableFoundRetries bool, client *oci_waas.WaasClient) (*string, error) {
43+
retryPolicy := getRetryPolicy(disableFoundRetries, "waas")
44+
retryPolicy.ShouldRetryOperation = waasWorkRequestShouldRetryFunc(timeout)
45+
46+
response := oci_waas.GetWorkRequestResponse{}
47+
stateConf := &resource.StateChangeConf{
48+
Pending: []string{
49+
string(oci_waas.WorkRequestStatusInProgress),
50+
string(oci_waas.WorkRequestStatusAccepted),
51+
string(oci_waas.WorkRequestStatusCanceling),
52+
},
53+
Target: []string{
54+
string(oci_waas.WorkRequestStatusSucceeded),
55+
string(oci_waas.WorkRequestStatusFailed),
56+
string(oci_waas.WorkRequestStatusCanceled),
57+
},
58+
Refresh: func() (interface{}, string, error) {
59+
var err error
60+
response, err = client.GetWorkRequest(context.Background(),
61+
oci_waas.GetWorkRequestRequest{
62+
WorkRequestId: wId,
63+
RequestMetadata: oci_common.RequestMetadata{
64+
RetryPolicy: retryPolicy,
65+
},
66+
})
67+
wr := &response.WorkRequest
68+
return wr, string(wr.Status), err
69+
},
70+
Timeout: timeout,
71+
}
72+
if _, e := stateConf.WaitForState(); e != nil {
73+
return nil, e
74+
}
75+
76+
var identifier *string
77+
//The work request response contains an array of objects that finished the operation
78+
for _, res := range response.Resources {
79+
if strings.Contains(strings.ToLower(*res.EntityType), entityType) {
80+
if res.ActionType == action {
81+
identifier = res.Identifier
82+
break
83+
}
84+
}
85+
}
86+
87+
// The workrequest didn't do all its intended tasks, if the errors is set; so we should check for it
88+
var workRequestErr error
89+
if len(response.Errors) > 0 {
90+
errorMessage := getErrorFromWaasWorkRequest(response)
91+
workRequestErr = fmt.Errorf("work request did not succeed, workId: %s, entity: %s, action: %s. Message: %s", *wId, entityType, action, errorMessage)
92+
}
93+
94+
return identifier, workRequestErr
95+
}
96+
97+
func getErrorFromWaasWorkRequest(response oci_waas.GetWorkRequestResponse) string {
98+
allErrs := make([]string, 0)
99+
for _, wrkErr := range response.Errors {
100+
allErrs = append(allErrs, *wrkErr.Message)
101+
}
102+
errorMessage := strings.Join(allErrs, "\n")
103+
return errorMessage
104+
}

0 commit comments

Comments
 (0)