From 0235690aaa05304d393e3b05b0a0de37b097accc Mon Sep 17 00:00:00 2001 From: Miren Esnaola Date: Tue, 29 Nov 2022 17:24:26 +0100 Subject: [PATCH] Moved apigee bigquery analytics blueprint, added apigee network patterns --- .gitignore | 13 +- blueprints/apigee/README.md | 8 + .../bigquery-analytics}/README.md | 0 .../bigquery-analytics}/diagram1.png | Bin .../bigquery-analytics}/diagram2.png | Bin .../functions/export/index.js | 0 .../functions/export/package-lock.json | 0 .../functions/export/package.json | 0 .../functions/gcs2bq/index.js | 0 .../functions/gcs2bq/package-lock.json | 0 .../functions/gcs2bq/package.json | 0 .../functions/gcs2bq/schema.json | 0 .../bigquery-analytics}/main.tf | 0 .../bigquery-analytics}/outputs.tf | 0 .../bigquery-analytics}/package-lock.json | 0 .../bigquery-analytics}/send-requests.sh | 0 .../templates/create-datastore.sh.tpl | 0 .../templates/deploy-apiproxy.sh.tpl | 0 .../terraform.tfvars.sample | 8 +- .../bigquery-analytics}/variables.tf | 0 .../bigquery-analytics}/versions.tf | 0 .../README.md | 68 ++++++++ .../apigee.tf | 96 +++++++++++ .../apigee_nb.tf | 50 ++++++ .../apigee_sb.tf | 68 ++++++++ .../apiproxy.tf | 41 +++++ .../bundle/apiproxy/proxies/default.xml | 18 +++ .../bundle/apiproxy/test.xml | 10 ++ .../diagram.png | Bin 0 -> 50404 bytes .../onprem.tf | 152 ++++++++++++++++++ .../outputs.tf | 20 +++ .../templates/deploy-apiproxy.sh.tpl | 34 ++++ .../templates/targets/default.xml.tpl | 15 ++ .../terraform.tfvars.sample | 5 + .../variables.tf | 90 +++++++++++ .../versions.tf | 29 ++++ .../vpn.tf | 117 ++++++++++++++ .../bigquery-analytics}/__init__.py | 0 .../bigquery-analytics}/basic.tfvars | 0 .../bigquery-analytics}/basic.yaml | 0 .../bigquery-analytics}/tftest.yaml | 2 +- .../__init__.py | 13 ++ .../basic.tfvars | 5 + .../basic.yaml | 17 ++ .../tftest.yaml | 18 +++ 45 files changed, 887 insertions(+), 10 deletions(-) create mode 100644 blueprints/apigee/README.md rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/README.md (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/diagram1.png (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/diagram2.png (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/functions/export/index.js (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/functions/export/package-lock.json (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/functions/export/package.json (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/functions/gcs2bq/index.js (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/functions/gcs2bq/package-lock.json (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/functions/gcs2bq/package.json (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/functions/gcs2bq/schema.json (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/main.tf (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/outputs.tf (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/package-lock.json (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/send-requests.sh (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/templates/create-datastore.sh.tpl (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/templates/deploy-apiproxy.sh.tpl (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/terraform.tfvars.sample (64%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/variables.tf (100%) rename blueprints/{cloud-operations/apigee => apigee/bigquery-analytics}/versions.tf (100%) create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/README.md create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apigee.tf create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apigee_nb.tf create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apigee_sb.tf create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apiproxy.tf create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/bundle/apiproxy/proxies/default.xml create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/bundle/apiproxy/test.xml create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/diagram.png create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/onprem.tf create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/outputs.tf create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/templates/deploy-apiproxy.sh.tpl create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/templates/targets/default.xml.tpl create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/terraform.tfvars.sample create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/variables.tf create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/versions.tf create mode 100644 blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/vpn.tf rename tests/blueprints/{cloud_operations/apigee => apigee/bigquery-analytics}/__init__.py (100%) rename tests/blueprints/{cloud_operations/apigee => apigee/bigquery-analytics}/basic.tfvars (100%) rename tests/blueprints/{cloud_operations/apigee => apigee/bigquery-analytics}/basic.yaml (100%) rename tests/blueprints/{cloud_operations/apigee => apigee/bigquery-analytics}/tftest.yaml (92%) create mode 100644 tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/__init__.py create mode 100644 tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/basic.tfvars create mode 100644 tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/basic.yaml create mode 100644 tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/tftest.yaml diff --git a/.gitignore b/.gitignore index a2d19a2c5..b266b9dc6 100644 --- a/.gitignore +++ b/.gitignore @@ -37,8 +37,11 @@ examples/cloud-operations/adfs/ansible/gssh.sh examples/cloud-operations/multi-cluster-mesh-gke-fleet-api/ansible/vars.yaml examples/cloud-operations/multi-cluster-mesh-gke-fleet-api/ansible/gssh.sh blueprints/cloud-operations/network-dashboard/cloud-function.zip -blueprints/cloud-operations/apigee/bundle-export.zip -blueprints/cloud-operations/apigee/bundle-gcs2bq.zip -blueprints/cloud-operations/apigee/apiproxy.zip -blueprints/cloud-operations/apigee/create-datastore.sh -blueprints/cloud-operations/apigee/deploy-apiproxy.sh +blueprints/apigee/bigquery-analytics/bundle-export.zip +blueprints/apigee/bigquery-analytics/bundle-gcs2bq.zip +blueprints/apigee/bigquery-analytics/apiproxy.zip +blueprints/apigee/bigquery-analytics/create-datastore.sh +blueprints/apigee/bigquery-analytics/deploy-apiproxy.sh +blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/bundle/apiproxy/targets/default.xml +blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/bundle.zip +blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/deploy-apiproxy.sh diff --git a/blueprints/apigee/README.md b/blueprints/apigee/README.md new file mode 100644 index 000000000..67b933ce7 --- /dev/null +++ b/blueprints/apigee/README.md @@ -0,0 +1,8 @@ +# Apigee Examples + +This repository contains the following Apigee examples: + +* [Apigee BigQuery analytics](./bigquery-analytics/README.md) +* Apigee network patterns + * [Apigee X - Northbound GLB with PSC Neg, Southbouth PSC with ILB (L7) and Hybrid NEG +](./network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/README.md) \ No newline at end of file diff --git a/blueprints/cloud-operations/apigee/README.md b/blueprints/apigee/bigquery-analytics/README.md similarity index 100% rename from blueprints/cloud-operations/apigee/README.md rename to blueprints/apigee/bigquery-analytics/README.md diff --git a/blueprints/cloud-operations/apigee/diagram1.png b/blueprints/apigee/bigquery-analytics/diagram1.png similarity index 100% rename from blueprints/cloud-operations/apigee/diagram1.png rename to blueprints/apigee/bigquery-analytics/diagram1.png diff --git a/blueprints/cloud-operations/apigee/diagram2.png b/blueprints/apigee/bigquery-analytics/diagram2.png similarity index 100% rename from blueprints/cloud-operations/apigee/diagram2.png rename to blueprints/apigee/bigquery-analytics/diagram2.png diff --git a/blueprints/cloud-operations/apigee/functions/export/index.js b/blueprints/apigee/bigquery-analytics/functions/export/index.js similarity index 100% rename from blueprints/cloud-operations/apigee/functions/export/index.js rename to blueprints/apigee/bigquery-analytics/functions/export/index.js diff --git a/blueprints/cloud-operations/apigee/functions/export/package-lock.json b/blueprints/apigee/bigquery-analytics/functions/export/package-lock.json similarity index 100% rename from blueprints/cloud-operations/apigee/functions/export/package-lock.json rename to blueprints/apigee/bigquery-analytics/functions/export/package-lock.json diff --git a/blueprints/cloud-operations/apigee/functions/export/package.json b/blueprints/apigee/bigquery-analytics/functions/export/package.json similarity index 100% rename from blueprints/cloud-operations/apigee/functions/export/package.json rename to blueprints/apigee/bigquery-analytics/functions/export/package.json diff --git a/blueprints/cloud-operations/apigee/functions/gcs2bq/index.js b/blueprints/apigee/bigquery-analytics/functions/gcs2bq/index.js similarity index 100% rename from blueprints/cloud-operations/apigee/functions/gcs2bq/index.js rename to blueprints/apigee/bigquery-analytics/functions/gcs2bq/index.js diff --git a/blueprints/cloud-operations/apigee/functions/gcs2bq/package-lock.json b/blueprints/apigee/bigquery-analytics/functions/gcs2bq/package-lock.json similarity index 100% rename from blueprints/cloud-operations/apigee/functions/gcs2bq/package-lock.json rename to blueprints/apigee/bigquery-analytics/functions/gcs2bq/package-lock.json diff --git a/blueprints/cloud-operations/apigee/functions/gcs2bq/package.json b/blueprints/apigee/bigquery-analytics/functions/gcs2bq/package.json similarity index 100% rename from blueprints/cloud-operations/apigee/functions/gcs2bq/package.json rename to blueprints/apigee/bigquery-analytics/functions/gcs2bq/package.json diff --git a/blueprints/cloud-operations/apigee/functions/gcs2bq/schema.json b/blueprints/apigee/bigquery-analytics/functions/gcs2bq/schema.json similarity index 100% rename from blueprints/cloud-operations/apigee/functions/gcs2bq/schema.json rename to blueprints/apigee/bigquery-analytics/functions/gcs2bq/schema.json diff --git a/blueprints/cloud-operations/apigee/main.tf b/blueprints/apigee/bigquery-analytics/main.tf similarity index 100% rename from blueprints/cloud-operations/apigee/main.tf rename to blueprints/apigee/bigquery-analytics/main.tf diff --git a/blueprints/cloud-operations/apigee/outputs.tf b/blueprints/apigee/bigquery-analytics/outputs.tf similarity index 100% rename from blueprints/cloud-operations/apigee/outputs.tf rename to blueprints/apigee/bigquery-analytics/outputs.tf diff --git a/blueprints/cloud-operations/apigee/package-lock.json b/blueprints/apigee/bigquery-analytics/package-lock.json similarity index 100% rename from blueprints/cloud-operations/apigee/package-lock.json rename to blueprints/apigee/bigquery-analytics/package-lock.json diff --git a/blueprints/cloud-operations/apigee/send-requests.sh b/blueprints/apigee/bigquery-analytics/send-requests.sh similarity index 100% rename from blueprints/cloud-operations/apigee/send-requests.sh rename to blueprints/apigee/bigquery-analytics/send-requests.sh diff --git a/blueprints/cloud-operations/apigee/templates/create-datastore.sh.tpl b/blueprints/apigee/bigquery-analytics/templates/create-datastore.sh.tpl similarity index 100% rename from blueprints/cloud-operations/apigee/templates/create-datastore.sh.tpl rename to blueprints/apigee/bigquery-analytics/templates/create-datastore.sh.tpl diff --git a/blueprints/cloud-operations/apigee/templates/deploy-apiproxy.sh.tpl b/blueprints/apigee/bigquery-analytics/templates/deploy-apiproxy.sh.tpl similarity index 100% rename from blueprints/cloud-operations/apigee/templates/deploy-apiproxy.sh.tpl rename to blueprints/apigee/bigquery-analytics/templates/deploy-apiproxy.sh.tpl diff --git a/blueprints/cloud-operations/apigee/terraform.tfvars.sample b/blueprints/apigee/bigquery-analytics/terraform.tfvars.sample similarity index 64% rename from blueprints/cloud-operations/apigee/terraform.tfvars.sample rename to blueprints/apigee/bigquery-analytics/terraform.tfvars.sample index c8c38cafb..db4213210 100644 --- a/blueprints/cloud-operations/apigee/terraform.tfvars.sample +++ b/blueprints/apigee/bigquery-analytics/terraform.tfvars.sample @@ -1,10 +1,10 @@ project_create = { - billing_account_id = "011D94-9C86C1-ADD197" - parent = "folders/586929298360" + billing_account_id = "12345-12345-123456" + parent = "folders/123456789" } -project_id = "g-prj-cd-sb-apigee-bq-10" +project_id = "my-project" envgroups = { - test = ["test.cool-demos.space"] + test = ["test.myorg.org"] } environments = { apis-test = { diff --git a/blueprints/cloud-operations/apigee/variables.tf b/blueprints/apigee/bigquery-analytics/variables.tf similarity index 100% rename from blueprints/cloud-operations/apigee/variables.tf rename to blueprints/apigee/bigquery-analytics/variables.tf diff --git a/blueprints/cloud-operations/apigee/versions.tf b/blueprints/apigee/bigquery-analytics/versions.tf similarity index 100% rename from blueprints/cloud-operations/apigee/versions.tf rename to blueprints/apigee/bigquery-analytics/versions.tf diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/README.md b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/README.md new file mode 100644 index 000000000..e47ba6f33 --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/README.md @@ -0,0 +1,68 @@ +# Apigee X - Northbound GLB with PSC Neg, Southbouth PSC with ILB (L7) and Hybrid NEG + +The following example shows how to expose an on-prem target backend to clients in the internet. + +The architecture is the one depicted below. + +![Diagram](diagram.png) + +To emulate an service deployed on-premise, we have used a managed instance group of instances running Nginx exposed via a regional internalload balancer (L7). The service is accesible through VPN. + +## Running the blueprint + +1. Clone this repository or [open it in cloud shell](https://ssh.cloud.google.com/cloudshell/editor?cloudshell_git_repo=https%3A%2F%2Fgithub.com%2Fterraform-google-modules%2Fcloud-foundation-fabric&cloudshell_print=cloud-shell-readme.txt&cloudshell_working_dir=blueprints%2F%apigee%2F/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg), then go through the following steps to create resources: + +2. Copy the file [terraform.tfvars.sample](./terraform.tfvars.sample) to a file called ```terraform.tfvars``` and update the values if required. + +3. Initialize the terraform configuration + + ```terraform init``` + +4. Apply the terraform configuration + + ```terraform apply``` + +Once the resources have been created, do the following: + +Create an A record in your DNS registrar to point the environment group hostname to the public IP address returned after the terraform configuration was applied. You might need to wait some time until the certificate is provisioned. + +## Testing the blueprint + +Do the following to verify that everything works as expected. + +1. Deploy the API proxy + + ./deploy-apiproxy.sh + +2. Send a request + + curl -v https://HOSTNAME/test/ + + You should get back an HTTP 200 OK response. + + +## Variables + +| name | description | type | required | default | +|---|---|:---:|:---:|:---:| +| [apigee_project_id](variables.tf#L17) | Project ID. | string | ✓ | | +| [billing_account_id](variables.tf#L47) | Parameters for the creation of the new project. | string | ✓ | | +| [hostname](variables.tf#L52) | Host name. | string | ✓ | | +| [onprem_project_id](variables.tf#L57) | Project ID. | string | ✓ | | +| [parent](variables.tf#L75) | Parent (organizations/organizationID or folders/folderID). | string | ✓ | | +| [apigee_proxy_only_subnet_ip_cidr_range](variables.tf#L23) | Subnet IP CIDR range. | string | | "10.2.1.0/24" | +| [apigee_psa_ip_cidr_range](variables.tf#L29) | Apigee PSA IP CIDR range. | string | | "10.0.4.0/22" | +| [apigee_psc_subnet_ip_cidr_range](variables.tf#L35) | Subnet IP CIDR range. | string | | "10.2.2.0/24" | +| [apigee_subnet_ip_cidr_range](variables.tf#L41) | Subnet IP CIDR range. | string | | "10.2.0.0/24" | +| [onprem_proxy_only_subnet_ip_cidr_range](variables.tf#L63) | Subnet IP CIDR range. | string | | "10.1.1.0/24" | +| [onprem_subnet_ip_cidr_range](variables.tf#L69) | Subnet IP CIDR range. | string | | "10.1.0.0/24" | +| [region](variables.tf#L80) | Region. | string | | "europe-west1" | +| [zone](variables.tf#L86) | Zone. | string | | "europe-west1-c" | + +## Outputs + +| name | description | sensitive | +|---|---|:---:| +| [ip_address](outputs.tf#L17) | GLB IP address. | | + + diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apigee.tf b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apigee.tf new file mode 100644 index 000000000..0e4faabfb --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apigee.tf @@ -0,0 +1,96 @@ +/** + * Copyright 2022 Google LLC + * + * 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. + */ + +locals { + envgroup = "test" + environment = "apis-test" +} + +module "apigee_project" { + source = "../../../../modules/project" + billing_account = var.billing_account_id + parent = var.parent + name = var.apigee_project_id + services = [ + "apigee.googleapis.com", + "compute.googleapis.com", + "servicenetworking.googleapis.com", + ] +} + +module "apigee_vpc" { + source = "../../../../modules/net-vpc" + project_id = module.apigee_project.project_id + name = "vpc" + subnets_proxy_only = [ + { + ip_cidr_range = var.apigee_proxy_only_subnet_ip_cidr_range + name = "regional-proxy" + region = var.region + active = true + } + ] + subnets = [ + { + ip_cidr_range = var.apigee_subnet_ip_cidr_range + name = "subnet" + region = var.region + } + ] + subnets_psc = [{ + ip_cidr_range = var.apigee_psc_subnet_ip_cidr_range + name = "subnet-psc" + region = var.region + }] + psa_config = { + ranges = { + "apigee" = var.apigee_psa_ip_cidr_range + } + } +} + +module "apigee" { + source = "../../../../modules/apigee" + project_id = module.apigee_project.project_id + organization = { + authorized_network = module.apigee_vpc.network.name + analytics_region = var.region + } + envgroups = { + (local.envgroup) = [var.hostname] + } + environments = { + (local.environment) = { + envgroups = [local.envgroup] + } + } + instances = { + instance-1 = { + region = var.region + environments = [local.environment] + psa_ip_cidr_range = var.apigee_psa_ip_cidr_range + } + } + endpoint_attachments = { + backend = { + region = var.region + service_attachment = google_compute_service_attachment.service_attachment.id + } + } + depends_on = [ + module.apigee_vpc + ] +} diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apigee_nb.tf b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apigee_nb.tf new file mode 100644 index 000000000..b568da9a0 --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apigee_nb.tf @@ -0,0 +1,50 @@ +/** + * Copyright 2022 Google LLC + * + * 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. + */ + +module "glb" { + source = "../../../../modules/net-glb" + name = "glb" + project_id = module.apigee_project.project_id + protocol = "HTTPS" + use_classic_version = false + backend_service_configs = { + default = { + backends = [{ backend = "neg-0" }] + protocol = "HTTPS" + health_checks = [] + } + } + neg_configs = { + neg-0 = { + psc = { + region = var.region + target_service = module.apigee.instances["instance-1"].service_attachment + network = module.apigee_vpc.network.self_link + subnetwork = ( + module.apigee_vpc.subnets_psc["${var.region}/subnet-psc"].self_link + ) + } + } + } + ssl_certificates = { + managed_configs = { + default = { + domains = [var.hostname] + } + } + } + +} diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apigee_sb.tf b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apigee_sb.tf new file mode 100644 index 000000000..e6df149b2 --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apigee_sb.tf @@ -0,0 +1,68 @@ +/** + * Copyright 2022 Google LLC + * + * 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. + */ + +module "apigee_ilb_l7" { + source = "../../../../modules/net-ilb-l7" + name = "apigee-ilb" + project_id = module.apigee_project.project_id + region = var.region + backend_service_configs = { + default = { + backends = [{ + balancing_mode = "RATE" + group = "my-neg" + max_rate = { per_endpoint = 1 } + }] + } + } + neg_configs = { + my-neg = { + hybrid = { + zone = var.zone + endpoints = { + e-0 = { + ip_address = module.onprem_ilb_l7.address + port = 80 + } + } + } + } + } + health_check_configs = { + default = { + http = { + port = 80 + } + } + } + vpc_config = { + network = module.apigee_vpc.self_link + subnetwork = module.apigee_vpc.subnet_self_links["${var.region}/subnet"] + } + depends_on = [ + module.apigee_vpc.subnets_proxy_only + ] +} + +resource "google_compute_service_attachment" "service_attachment" { + name = "service-attachment" + project = module.apigee_project.project_id + region = var.region + enable_proxy_protocol = false + connection_preference = "ACCEPT_AUTOMATIC" + nat_subnets = [module.apigee_vpc.subnets_psc["${var.region}/subnet-psc"].self_link] + target_service = module.apigee_ilb_l7.forwarding_rule.id +} diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apiproxy.tf b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apiproxy.tf new file mode 100644 index 000000000..a94b11eec --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/apiproxy.tf @@ -0,0 +1,41 @@ +/** + * Copyright 2022 Google LLC + * + * 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. + */ + +resource "local_file" "target_endpoint_file" { + content = templatefile("${path.module}/templates/targets/default.xml.tpl", { + ip_address = module.apigee.endpoint_attachment_hosts["backend"] + }) + filename = "${path.module}/bundle/apiproxy/targets/default.xml" + file_permission = "0777" +} + +data "archive_file" "bundle" { + type = "zip" + source_dir = "${path.module}/bundle" + output_path = "${path.module}/bundle.zip" + depends_on = [ + local_file.target_endpoint_file + ] +} + +resource "local_file" "deploy_apiproxy_file" { + content = templatefile("${path.module}/templates/deploy-apiproxy.sh.tpl", { + organization = module.apigee.org_name + environment = local.environment + }) + filename = "${path.module}/deploy-apiproxy.sh" + file_permission = "0777" +} diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/bundle/apiproxy/proxies/default.xml b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/bundle/apiproxy/proxies/default.xml new file mode 100644 index 000000000..a277b3cda --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/bundle/apiproxy/proxies/default.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + /test + + + default + + diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/bundle/apiproxy/test.xml b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/bundle/apiproxy/test.xml new file mode 100644 index 000000000..93812d829 --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/bundle/apiproxy/test.xml @@ -0,0 +1,10 @@ + + + /test + + default + + + default + + diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/diagram.png b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..8667cd318defe6cdabb6c766d79a4005a2d2f92a GIT binary patch literal 50404 zcmeFZWmMJO*EXt1halaENVlZq1_T78m2O0kM!MZdry|`UCEeYyQK^kcNJ@8izYFlb z|Ic&Y=X^M0oN>!uAZ+vS>K53NA=lx{QbeCSt2vO|gLx>kKFAhq4OH+w= zXjknB*N!8CJ00bCpt0g+=vL!2+sYu@r;Hj^d`6Wo40hAbcApqF&ziQtU->c_r_cDb zp02;8^(QyY3G#oh>u!A@5!B}>I4ZTTMvv$xqMLu=h)1PE z@UCCOd3Toqe*0^kJLuft1@J1-dj$FG--&-iO8fu7+X5T;g@uP!98geDj)}UdL_9u@ zJoK%h#y107?Ko`kzM`BG5*3{u92^`T9-f>O=Hts5GFN6RmPNJWyE$B7*vadpH|3E;G)ob>ec8yg!>+zBfxD#$4*f2f1i32s-90jql%8)uf3 zC~fwMmQ_?ZxVbUuhvCeMD5aqR3u*5jZj8^&7}oNTadL3jIygN3ufIfqZmz9;)-HcA zIXUUpsMkbF-Qjs_(5m_UeFqN@9qV4H(9lqFDynXE8s8f1zYp~|-Zr$cDXyu}VCzFx zYAP*lWuJZ6QF!Yz-o?p!X9)?3ch0=<>FNINe%~6wzotk^Nx6@WO+-K-vl?nLx;HTJ zz&qk2j&s0`H%I-Px27n_$$NTwLc_yn^$XQPa9wG|1Ifgpbimc?odMWXQ_bGkHjDE8 zzAm_bw*pCsh=_=diSZ8zsIRNj($Y#uOx&?CHKms&BqDMYpzut(-dG}V1z6wyxHtq%aPf-xz$xvynOWvNsjk)I85<_ zKy-Apy}do~#;!jqH5>MgcWPO-rW&>N^w`+h*;!bky2}u9HPzI3MMbX;H?&>teQ`!^ zpRR+x)6EF{`%b#*eL_M)VIiwmDFyW=((NMnHq%YX@$sCOKTNwBSy+I*mlX4HX7z5i z@=-2*aHX!ke!<+5lY)Xmt59u-&WbVw?H#J4M5sy>-;r}d~zL|iyl<@Yx`t~i*MMGJc z^Xb#P!4+Uwd1hR3p}RNf_>Qrvy4rj9bE?P1!HDBA<<$yL)D4 z=0asJDmM1?=;+5-TyY)Zzn`<7YKV`Fd=zuF-hWw;nJIy~zq|Vmcn+P9kMDzzkCBnl zRFh}^khz7qIW8`)QdxQV;Mmxyd-IWdYild;0$tdDS?uyS;>yL#YpUiMs>9p2D?|C} zhA{7K6mKP6T`c3KcMCt}=jUxMhHVH42#}DGFHc9BQ{v)|zbkr0e)eAEi5=4IfjE9Tsbyn?7hH$aueYuodUQ)7Mo_c|aA$oPvpOc*( zs!s1)!+#T#^D5`P)93Q?@?jcYm**$T%ekcxbu~5dPivSJm6b9GjWspLgQ=JMD8LNX zsDJ&>%F61!FYWzndK&xf<>d6mWP7`WF;s+~|2TR2gkqHItK_q1aTxph7eo34L_~W_ zFH!AiZlL3v$;$eAgX`WK2&Coo^b}jvD~zHAfwHf+ce2@gdSt}e(eYL0!0R_}GL-U% z0JInxnwc#FOb|%!tB?^7T)Ry!RO)$z+prf$t-W(|43KhccW!n^?fVe}a+8Dq_r7ht z``53ihCrOzzS~Eisi>*Zu|M*y;kwQ3Ch+nO$1Om50@utM{(T?Vb4UAaC?EPE$Oi_9 z-68}A*e>>MFpm-e>rx`$?7x&9tS5wd6Lm)VU_BS&|NjBhzPBdw4~C?sq)=Yh+Id_^ z+JYoNEUC?o>|E6S@oJlc>vCI*h-2pZfV!jdlVB<1e=KJwIIm!d{vQiZ+^@w;{EOAs zo~V`p%lsFQZG8NH{NtnIY0l2r^iq{3#ZH-&7MprQIwuQ#2kcJw8Y|+zqfoHc4G}ad z(ChnwQ=V9Yh?;f!mOL6Ihp|7r=;e73-e1^zwWe=%`Tgomr0B)>L-xxHC%4_h_1T$p z58-QzaX~@&jZ-@tsj|_+>k8#J5;HdRFGb%uUUD*vUbGKi9p$(EI^3a6_KQtdwsCfL z_VO}(?O^vm$ZoY8#F5TS|eS6t`WqUL};{D*Or^;9D$rwI^ zzL}YspS$mLCFaVBcJxHz%!8NgN*&R2_U08>2qo&sbhp z$1A`)H6j`q8m4GzX&JoRnMFGfCsZG^+bt=pV`8WE#hI-F{=D&f@BxA+KTqw^H}|uv zbN%Y8S?{UK>Z_1N(F>2QlerIlRqeIE+jo?$WM<;@&ER1pq6dSQ%vbHr?oJvLS??Z@ z9zJa@`4|(wH+fXO=_ZUB5f~n(*w(CZxVvMswH#S&`}DA4EOfoW`+Qd0rR2O;5jsgm zLLt}PbN@cp(GIq_k3{PH0#RR2&um^&L+rP{z9Nsxkk3&GJJ}85da{6ZSzY7BwKMT8 zkhH43;c?Z@R}n{Bmq!8ASG_ZHR|-eFS0Y*r@GbcjM-+eby1c9pA2TklXr7@!FE!ya zA3UN%;ACWEwI@jWUT2;igK?M8)(;=bot%yiPf`4X^`cqW*uJaRkP{Is&&()q1wgSc zK475hS5`S!R8*NR%um;DscM{SzFX8fsb_q)pFGD+5SEPFSRpZQY(lCbzlq7cxi?cs}=Gp<9S?A&n!$ZEt*c)`c z0Ry8j2-RC;1!QkKt+UiCSW4EftKsjXtQV~@xwSRvAq>Lx2w~?kEiI`n|omd3x%PuR-^VkjLHa?1}wuhOyCSmBGXWZFTj2>j;th zd#}CHzt$Z}di(@|euC7QX*{Q7wUgH|)dbz|Nm`Dp=~-_$^q|Pxy|*}lZfWix?*q03NOA)+EK;WWovp;gU@kC)cmhdf7oK>0agJI zH@D6!)tmtjODCguUn?5k85`p%_V)A;HZsXPm+k%bqcywH9;R%X)Nf7;KdtwZ;NOp~ zXfKrnVMR9AeT;O*Ya_csIJnsY^Lg$HUv4iAB(WK9Ke#vsv9Yh4G2>8y*&?N z^}R->ezPKyrU;90x~^^B<6a=zUrwo}V*16$O;Z1acW3g5um7a!zD!!Z`>FNx9vY@s zQbJ5nTVksrwg#c8w&Yo=>)`yW}*xS| zJw06x8Ya~zTt(A`HJx)%E0k5(IA{<5c16} z($o>DEX7HlVKC5Qd5H};k64Qhly1vF{WYc!yhbO->DglVDl6I!RDW{GYtaJ$y{0<1 z0Lp`KQMI9u3Kdy7IT=vv>iRkP-B>z zMZ<1lKHs}N48NS&>7mNXPoFry6gKYde9i$F8XFaJak|D_^177pOL=_`_7wTvBWhj| zl2tTOLPaY}OM_^e;z`S`< zcT@&HX1gzRzW5`|UWA4L(ap(ev)iV4=-03@bB2eB36huoE7io$N4uX9!je56#4>D( z50L3Sz)w;KJ!i+~f9fcHK4RU1vk3Y=oIU(-sQDR5oetlZv!hQ`TeI7)d4k+{X8Z>& zaE|$*E_O2yqo2oGTbGw&S1o@oP`vK8rWbBd=zG|+(z2@ZAGgj>r}$urdLBNa-E)H)2KQ4m||+SR+kPqJGLV*EM{&hD8g|%)I${L4A9xgkHJQF>Gy(3?+Mdd16Eq z6~o4A?W3-*lm%%R^4TLqw|C~J`8LfqX67+PdYO65)6+${U!f59lVesk&vUjx;v~J?rE;d-WF8Q&BNQ&0c#TXptm~fr7xt%jr-Y2hS@^LHB_BK~HDJUtprm8_#u};7% zEcB$Vva-?HpHOgOaPa6^o4&D2Zi|QiO;C!pvQw+XL|JZ<--m8{d|R`yQ$MJfRjBN8KR@^ty)P9X)R+DTwT= zwZQ~$WT?p3GxkNdONkM2iL0^Yma({Re}1%Wx3z9J=zVdPN*(xebru()|K?~!5!+r% zWToE}63bO?Zy2LqG=1M4mmoC`m-2z<#^NNvGCu|jC#Q$S#d@(B2tE8&XB2T&mMU!cHK2+wY8dz$jqMS1$})vCe_)w$Q9{$j?+^qDK)k+F&@NsNs0P*+=o{j zOsDZ86PwHH-CbNXwA5A(IPMUX(Ax!l?`F==eZT9IF>=)4sZ5EFn{rf!qphjIej9s&`()kOonY)4Hr6@z2e{&aOQ6H-xM>lFQTGQnM|ZyQ84q2}CAX!1TR$Pc zA!Y1y*xhdZ<)&!Mi&awhxMD6SgYVF~Yi;cQK!2@uh_5y=G1jK~v-bzX(=(3QWnw0F zR`%k;VhN|_-JCN7TF1sx$A^IJ~lP{&B@Ec-Tg$B zd2@@Zpr9b5Xeel)*8zZyxm zxT4cIGQNMsGQZ8cUWONhKF^8wx)aX=Rn&)U}SXy4cbe0ILa<7*)=33iB z`L`-&LGEp&SJ^l|wtm=E&$Fwhnj2L=)QOE=?Wwo=%mc&Wfl1x2$mEYMeR>COK>BDh zjh!1QFHhI|uEZpdfFo^eKc}in(O{J7T0V@K@yc3_bUx@ zj^S)xO(i71Ek$nP!GGK2OH<7ubl;lmZdwOxXin{Kr+i=Bu|nl`>j;Hz=?ecBcaCD~ z;=;hbt0R(6BqxM@%4tU-ASjqm{#;Vhui;zDpP}#i+qAZRwJA7>nF6%mL2o38zW?LL zk2L7cj$N_>z4usPSXkKa-$(zQ#+?upgyx#ZcuWR^ z!8SKHf22N~-@9|qk61-YTKeedXhD&zw7mR-p|qZC;DgVfKkuUTe`v}7-26w*_EM*~ z8uIMTn>S#!#igYMMGYx2vDOpaDMJGTpj*aLDkv(3h{+se0olwjBQ_RyL~5$|MQJ9a z+3kSo(IbQ|Pbn!_rgTK#(^ETCCkKaba=n2eAzWU8_v53YUhB;MFj(p}br`iZH)kUJ zGmM3WRc6{tLP8>=s0h}YWlR#q0!7o`*Vo|r_wV0#_Vzx|c3Yf(TU|BR)lF{rh57rV zxCk=?JjULu>sS7Fh>VQP>({S6Jug1fD}K$-Ur^L;X%E0YIy{`u>bv6|9LugRi#@~3 zL5?Y_tgL);aw0{r@aNpn&`?az9Q|=U(2VtDlL8v_3@r3Rx;E3cT z40&I_3J3{#T%0PJgQLa* zgfVD`%qw$0B+Q!cx3t_@?2C%RC+~#~>*?u*zq72UttG*BcXKPDkB^Vn@Ndf0aj@j} zL0U&1dv-P&yguPqN3aq*3v9j8A&C&I^m z9P|pTr#VYTK27dNMKxDAxGXGq7)EvLYioEz9WPL1aCidz{kJV8C6U~!FQuVUd|eJf z=CCcHc0whTUZXNtKJ43jBs*c^t87vnn=7LbVu>$9pq&Ncd?~@VpsA8nGsHa`6O$~Z zkiI?z8O)CCfhSVf@sJRh@=RZ{pj$iK_oDT(xVYHZrS&~c)SX1at%{I0=~Nj=>9oW( z98!LMeqe;re~ivo%KTL|@~x*9=hIE`pU|?WN`o!d9*qp}8 z_R_#P%r5SIeC!?e9^9_|)m5f&1@ccSXV{cNIL`iQPwv|Z5#ZuJ;pBvxaECbA{>fm> z6X|}~EX^_QYQBlJXG3eR|8$@%c% zoko1!&7HX}Fm9UmJff&W(d$&#_vA6UL!h*Gd2wb$02~&IDxSuvVNk!Ed#w6rrl$uJ zhICGWjDoU5svJ(_Ctgz%5rIA2M)z=H)Rg;?0+SM!@Lt!*vp_++J{D&FW}nCKWyZL- zaQgv1>Mmkh4l=Q*foOOLCjm&$P8cks`t;-^T_T;%jhxP4pB?kr#l^+)SX>du7XyP& zHvS%zN@-T#o(dBQ-*0@S7U+d84C%+Ze;-!Vb~hs<1MZE139*{_v|OvJtE&OOVt{`{ zuVHkvR#N&{1N*`^@!N54Q63;8`5>p(+RBQUH<7j&Pft#q%z=L`vE$<6;=_Hn_5;Qj z6B-nWEtVKuux!Koxf5e!!7?QEk2~%p_z|Qd;@n$4rbi+be1BN_e()W4eSJL!9!|BB zi@Uo8cLEq}VLpp%k}M~#FCnlSdnjyaZ4GPb6ci?hJ?$!lT;onLWUj{d*Q^pu*$0;; zPy(w9FB{T0^N#(#G&NiUW*GJXtqAR`9L-Y-)xGFog^SGc$%hB5L?-@ASKS8W5hBgo*FF z_3E8iTU)B9y)dBuE2~(7j2r%={fg+^geC6FACEEqaN}P*8?C}I`{wN7(V&6hiP?_g zRu=ciPWHY08rBkg`Ax=s>P^2@Ge<8Zhi&a@>-1_P5yDtMj&_I%4Gy>#>(plOB~+4;lK$yf z{>EQ8L}qQ#5rt0D;>*AksKA6sI=E17+7C~*qYHJ_aj|78SmYD&|)G&!r)dzQ&SZBaWk>2xyQ^wcbzD^0VKy|AEeg#-E;R# z;N;|-l`S7Nw6lJ=`r5?Au#N~J%p^}UY0voXUelDV4CUFw7ZCHL(ZoGd@hya3kaDIfAYsq=E*Gdo`^(@W&r=Xw2!?Qb^{`?5q*~>_Gy? zen$tQK)M-XBgULhDFj2bWoovcb`{L&a>Lb@uo+?1wy2MxQd@*J5#eEBhQtpLz^FH% zR(7>;`8@+Zb8!EO>jD`Anfg{kQ+n%JsH&cgD8^e34~<-YugnVn1!O zgtrwHvHjB5)O;$PW|*4mujlLa2#q^ir64d_thi;zvk9_>Wga2`*H4O0p@D-!X<}k> zjNx&z5E}`}6ninlza+H~6GOOf&tib`tXhnQ_+g3qvcaq{yFC<^znIw9A^&tb;uTnY zfNH=5U{AD>c%=1A%a=ff07Jw<>N@IEB2uv~{MZc1E zy^)w1?Hj8XuFF+%`<$7E@19LRGwo;yI(fjA2`WVmzm*3D3Y~P%+(+f*N*8@C?;?mX zo0NA~1N$4(c!;q!Epij!*1f&*FX}-=j?%vT0GY#P2)gT!Un8xggmZp(E|eCbkdOZk zY1e&&;u1N4w%qBO{MeTWF4SNI%Od2uizq>o()qM`)f6kJP$@Zb{^AGVTiiVwhn;Nv zvR}%j$YnTm?b1-8!(>gpSi)awYc(hSK*ON|Katdbk94Ia;OI2Y;6ZcI+=t1gIB-WY z;59qdbLn$4%K-zy;^)j1*`VBM=z1iGF{SbtOx-`kN`!f3)MxNz$SbpLBpypWXdtxA zAHVZ8-R2KI9)=5{F#5%_3N%Mp-&}OCs$mlEuaS{VPrIh@2htw<#1zDeh9R@VY~msk z9Lhm_nUCQXUtIC$?zxrbK19^ASuR|*=0_p4aSZ~cJiF%9PsHq;6Kz*h3|f`6x8&A{ z^ymrTSDQiRM(;+h_$}l{KEO$Kl^XseXqIxPEsqYdu<7aO zLaW)Vont6h!>W8PTAi|5rBN%U3N$O;oClW#TU~8^Gx-SOd7S}HSk}};Nkzr(`Do}J zT&6?*VwWEOqxFofKD@M3SIyVu@z=o;S_8eFZ{I#PAqRX^6o*!k4~4(QBl*}ef4RRh zSXTDrTw7C<(R)nf4-ehr$5ByH$7g5b=lMk)WRndQ>rUU!qHn3b2^#;?_PjX$+6IO= zMpkE|q(8DtO`E7N{2?lBFi}>f;Iw>#wY9O~=v;N_~d;{Eh=vGcPdBu!l1gI&muW)P)&DX9%Kt`@-Z2YK01G1n! zs1lb+n@+hbsXFsAJTr!=PdoNDStJS&XpXvF9VUAa5Oq}jw@zY9{kl*3ZHh`AlPREO z_ni8^1W>#WM7b4{V)h#eWO7AoQ@tH{blFvYI@c9nJ=E_yC@F;GAL@XvXXu_bD2}yJ zkbLVz9P!7?T^)`}xXZ$m0d)g|K1J1!242ytbA?}Win06PvVs9%1jJD`68Ph$dlC`6 z#yx?N{9sh-&A`8>xM`r;m2k~2z6X>>I}6*J=8-+c@^Cya*Ak*=#0=?Ngg??c;RXjEYrtye@b=hlk zm77$Jl0&PYC0~tD+utH`pd$9)X<%8I+FFZPnAC&XztM!6BZ*u3MMB89N)IpBqB4)` z@Oq)zW_vca51=A&D)s~{Qp~yc1uN6vv8B19!nM)BraLzg8q?h^F5AFraRsZtx)`CW zW?5P@;_J%_!wxybQY0`Tn$Lr~Xj=hPycJa0d{gp;%|v+=o=30BL>kt=m~QghC_)97*0>QJmLZmVU|pi}BTH_8pGCkX1>uArk3ZPca{m7^^vK_2?6{ zb5MSkoJ4W0R);uNl)Zjl`cd~H=%naLXjJ-lk`v#fc5J^%8_$sNttG0Ui5`(tlZ?yp zicG;;D!Gr+HVXc+)7>NIpK5DsmzS4w6jNhjV!SveHXl$?U2RUqg@j`;DzGjz zqOmUWZuX;y?w~UFy|E!P>99IlBImgi5c;1=8=BB}3RB6YsHM0pP&xN{op!whG`z8~ z(b>r3Z)!mJO$1MBv=T9wdZSV3j`BH_n>iyJ|9oG0YQ8c6k zJENCKTK@zmX1fj(*aD5_h;mx|UdCg%SaC#`+7tz)Hw30OjnW{{x52MFDeNBD^5r5p zynacQ5a=Upc-Lz2g5eUt@f#d$eBPwpr~ZDP3(Ju`8%Jax_mx zYiVOcq@G3%r=_I@1@~-56@j$~0-OODy6i$#CxD$`mHsRUmqO@QNWOy1u9pcAcE)fS z;Fxp2OLfws-)N!@p~px--}FViNQ-rzQpZeLbZ%;lwm+=@fU{8dX>c}0bw|#39~~dxJ3JH-5xH#Le%rQ(L|T;`9ZefO4rH75T=a^c zcFfcO>y*++{A*t_z(WOLln7YJ$jIX04_0VcSUMs`P*Bi!WG83m_O`Zd4mvtI0Rd9% zg|%_iarBB+KY=XtYv0+ug{rM`!N4-Ga$^Z-704T$YuBwmhO_xtU5iJzaeZxJt2IV& zwiR$TtL3h*N+6bK@UGEuAo@tyehb}QVNiSOki8*Qw5K&@mPr`>^-_G({A<)~e#B zexgZ6=Ee#SkQ62AE~FWBaa0wQ9bbv(2i7Tc;f98 zoqc>w1ti~zsWAaE_dM8zl0N1_g7T=R2$DAQBLk5%?8CZ=tNd`jigM)PZuH{`%=Q{_ z79z8u2NEEYefE&*vMmhEBx!`#lXT3;5-Bt$JanfY`8-v0bMjcb^I7N3PGWeF>s~f7 z9~RP>knBxf2ZZ&*xH=^yU!0EQFr38k|d& zfe&)ps)DCEr9q$AaVe3JG48=q{`^ksQY_)hpb$b@3k#Mb9iK=Y6?x`qi6Qvjl+)Va z2#$X!i)*&NwBfF2M$&D!@_T_*7iSsF2Rh0*-c$?=aR-G3M>d^Q`uq@h+fS1C>{Z&U zoX597ZiTjl!F|6>@Tf7zIYN5a$@Bc4GH3--+DiRYe=Z-tUa@-MZ>YlxF!m=4bGlaR zyFQ}j`6Qo?0*@8yHzGa5CcVjVGac>)adyV4Ts!zeXNQevan_u7=YIdpzP~q2?2HNQ zcAwD9POr|ORW-Hgp3R1GIeBfynV8a`9@yfQ+AgDr*P59Kr@3j&D(L z0MOatfo4>cEKEddLm`5~Q`}YQTM|BW$i&DYwl$yBe6EoD){{Vu;dxB3|wL4 z*KB#m%k?`c^6n?HU;9Uez9JMlOvqj{LJdd z9*5DZZ9Kt=Z??yPc8gNL^q5a*t8p;+**i~|$g54A7C@ZOYDPg`49s?W+%)uxGo#;9nFXV@eDqmxZc?jd~iQ3YZm4pD=$bm(Ky^|B=CzSNUGGpZ)S zOx{O6FAW7`XLek3XC(dMoH`-e)bAar#RjDy>K+-}NxT8ST`Q-ju z%nak66tTaZnkC?fn2dz)njkdT=Lj7Jk!RUY*o56%ZRO=~mxDII-Iv7%pr$$Xvm_Sx z)wnaj7nOnBo|4~jf`HZej1T`XNDmoGISJ2rCWLXeo}lMLhRJ5dO3bD%A-pG>4>#N? zaWzxHHLI{)+Z5jML;N{{%RY z=D1yqE~XdB%}nwGrOMDiz@KNf4xarDNY~ibjWp)(RS^6Y(p-?+>052Uv2wUmi}V39 zUE?XO(^co$&z!ljtz}#j!B(bX%q4D9S#Lj@hJqCS5|9bHxK*$Rh z&%z6d6nl>AU0X(K<{3M2(X7}er;f+jBtgwPi7N&tWL|7h|D6yUk>@|WT=)8P;~_+^ z_$Hd1^;r@zxFaLg@kvR-CZ#Yu_e@p#Mma#ZgJ}YYb~b7_1>T-;IrBBDX`k*AF*5Xc z>H1SXDXX$*5@_d82wgzfcn+A?#BrdET*A;pcwBVnh?$WdzF(Y@AU#pX?nG<-V!8}~ z%A1r|!>EW1%thb#NvG$znZ=_`#-GX%sudb!IwaujUM@OIcT%tYH5C6th?yGk?PgK3;sY zthb}+FOl3@x6`SJ?G*(K7cj0-b}yzFp+{0-3XyvO%qQ1|_wRHb9N zoj;y+J#TL@u(Jrb2jY8H`PoYYvzmQBgHY`bkSUd_EC0}lSJIf*PhokmyxMoEf3d3m z^GquhALKzhxF7+L-AI+oW}?aX{J<$xI{?9ok`}5anYT2ilO{>--RQLWhr+w7cO!!d z{%=cJg$T%zixa3_S(<9%l|Bm^kKl0+!fc4i#^I#Rc9uGYjt<#&1|H^1-_A8*@)A(q zh(iqOl?$;Jwo^@M@T-QW>_6ImRvJM7z{ zH)bCVNR2}1ZI0lZ`S0v&u)%rvjbAaqdrm-%2O#visQeGKJRR`V>qq4yX~{eTOb!nK z$=7Re1#1|x{a2!(l-3J$i?0-_GRW8OoBMg)B<}z7sIN5s|1gSQj)&1NhXhz`n3#Go zHeyfvMD}6}NN>%jl14%=byM8HkPi%S{x_QeE*LB8>RP*xH^@eY&OIjsVk2u#P5fqr zcgr?0GZS`$gI!~<@49LU&n{@(e@)ZCpUMh4qZMN5)<|GeR`u@yxUa1fM6vds^*8#Tl12M zDSz=$can|~9!f9y&pBpaL#NA;k2Mttmp5n%PkehhLf2mJEw?l*k#_kb6mnx}xB73sUV3hP z`HmRIm{(LZCZfT~?reJ)&NmY6UJ(gs)eBmZe>`uV^HUX2>0Usk|8^mxPsg~tSuy7d ze*JoBv%wCYPuqQ}s2{9`YxXM2jqN|J+U;mn?wS~D-#ocnHdn1AX)=>yZ={W*PgdTl zH{0oZ!vv$|5LKe{JQDDX=70ChQ*aI3zt+Qi&Ah6j=pE8&#*HwNhj9H29j&zJ(@;=X z{q5HHRnk~VR9Jkkt+~2t!RJKO+npR40{G{D^Tj_0sY<8H2XU^$bb#e}{rT6oF?@5^ z+261)1dzT@H!&k&JbBvZ14yco{Wa4D8|(m$3KN(+1IKanxY~VzFw3{AfsRdw31^un ztp1kqf^S*Ob^PV0-5C2tUcC))o;j)dA1*2&X8w(8Sk}+ciIOT|8@%78&9?xIC>;M-1~mMj0+6%?--hO<_SV$mhLLqCIlH=I0(pJBzUbkl@K3C_Jm#i z$7$brIgw&-w=R>*%w9g8265tMKXcEM;ua34uR(1gj|*zYjbwdLU-b!!$rt@ z@3J00?lL0SdzZ5$Il)!>F^bfC>vFOu>E#Y!HOU;s{TzqjKDi-V>S7EmTHYC)0mD(2 zAPUh<`Dn_cm>5>avMTENVC@0WYx03sd#BbnJ2$o6-C<11MS?d&eCmdURh#9N&xX18sME!aNY*mE zti=`&TYv1&K9@IsioT=W{P4O+Z8#8izDQRPP-ua>LAOkDm_c9 zLUsHlG{CVp`ls49ZU-Ar^@x#XLFLzY?TI+q?iaE$iaI)};xjE8>K?NgK&HJAvvBjdIhaSuwN28Tzf3*WC-o`co|iI#0AF1{k_vZ4=1lW z*V=r^hTO$)ft2`hL7e4uL3CeBDJevg<5>CO;(OSzxlnx-7dz7tW)%|RsiC8gFC_ERxU;obtK=Nqjyn6J zrRY@v$5`1{bl9_R@kH>e}$HZyL#D1 zPW&FR)GNZrq##b~=}smK)#4W&A#JEV?(II)a|S-!!J)zRXT%g+%;%_*m9rT93Hyyi zp$@))v-3rR^}0xc3o~|(&?eV4WV)y4~*S!R@_6xuJc`ucHm?OUH>EFvjJ zq#ZKyiG-ow)-3fi%{uHa*`?&Ffx{d;ZL$N4AZcbQ7ZJk3%(2w-vdFSa-v{8BJ+B?M zRj#clb}a0nW%>M!5xSUzMj{RKzhO`UTzv8@bBG!qJ!ysY4~%{IojU`S^)5)gfNG0AUUScD92Q z5CSPo!7?}>qoM{Otdz1S$nPWkVGrSK;|RE6=KY?Xj=C@pV!SCMqlnMiQUahi6cE); z)i{LCPT~UEFNB(7Nt;v~FP?`FC7|seuN!m>a+F%TbQr(zjf4<2{b=vmf3!(5hQCoj zrrX`hCL9q0(_3ihdH&oDN2w^yalbK z~ST>603k9|QQL9ZL2Wu%lc|ldk7}Rs_-W#sv^R z5R&?_1hW&DeUszF%eGZismBPop`O}<9^~2rX9=CUk4CTR7JqDfAh5)^4D;qBHX8lj z*Wc3O^D6Clpr3|Q!0>K#7PgmxJs76F+0HD7hL@^pjVBU~WdBpFfLL-}I^Nf0-AEf@ zh*}mkF`;%;c#5N+m0moLQ{Y&OiXswr-@z|OS|pQ6}|oB{3QEw~5=yi1g(T(CH9LS+l_zI@$>{`Fi0;oX?&YcG8Ow z-NW!8-7whyU<=%*#$&Ifmo#dO*{bAkPJD4HCBX44jjn28!4ta*i>GU)@t7M`3pUEI zky8q>z#3*_<>FP;mhNs_?IPPtN&$R;Nme)(aI=SiEZtrc1B28UTM{U2d0OxnTg*&7 zs4*JELe|(}CEBnnWvv_qz~ds0i@hem^qg3dNfH zjS$AA!M^3rPaCf2u~S!oV}yRu*`70?_-Bwmy3ziq>M>lSMd^c{zOw2gYo@a=V78wz z;;PmD+soji=&FQXdKLfofR(<&(B?q*H!Sd3ds4H8tn$l&IfKHPBFrR5<25rUW9PeW zVU3+lt<9bC7LOK&iaSv<(+_4NpEAuY7`!G+UTs$}LZJ*0Z6nktTrkj0N}XE>%pcHF zg{J6IhJ>QWYQ3>c2`?J1HTj3hfM(_1Yz#u-FVoP{d=P5t*(k8Of?-)Z+VQ&3{`-2% ziG^$=FH+CrgyxR_lGAw)sDEKF_TgKsEv1>6-$bfW^AeezXOhbnB)=J5{WQg>?{fTU z`gGq;Uv1h}8pPbW#{LDU+!+tv-i3CGYj-}W@;TiGpo@!G{iT6{lU70Jqn<`$RFj6i zWt}J^4`l|6h{#==B8#GqVB(1i|L%6P>0>f3$r#?8PLst~y-EA{{vA>K9s33IuIH-8@$qL{QQmovShDf;*y3jNTU5f0j!aeW}q zms)^GyzT@0fTY^;#3GR?EeHF;qu_WdF(dLE<0AJn3v8sE0%vC-QLW(xY}etiqMt3r z^HT`3FG5(R?m^CP9r~Zr0r843bEq1a-Q9dA(J*e$NCN8gI2L~yKq#sMz^S$DqQ*?e z6=O`bXXmGp?LP%4nkrV9^l@hLR#vT2HMcdcNqIg}T~?;T#1B#K0prU8mRUABz)sUH zLuyRJ8}1DTTfU9$;D6ufc{rQ5LuB%#?3y=Rf5+^4w6oOt>9!xD1zgoKadRqs#V=xd zbz}dUjSFT+VuCkUZ%wR{SX!)EV|w8;)Z2d-QtH8IoKYRoSxKPk>SymE)E8HJ8F{sA zw_P~SC;3!I|C9tBCUkAAWLZV%8)Ci)z`Y$iloI?4-(R;UZl?k{i@FPuOOi-h1X(HW zBv8U5d`IkxVC?l_?igtytoE{Fwz2i|{Sx|g5Ew|EwK&V8$Hav*^uZ4k7>cbK+S|vn z(O``*(^YS`}N9 zq_l@7E2W4hA+^Xa49_kJZrTf94kwxOw2t|6TRp>=;q6R0RtiTzTRWm^zUA8P?L zP{8V3sxqrrnnrY8_Rd#*YZ{+=p1;2l zL5*X~Ot+KDPdsf*{oW#;+``x+;ZkyZa*lc-WbFelTPln1O)sU-OFj&5kGId3cfyxr z`rL9GKF$RvM9x?Eb{^!lJoN6JVLCi?UH^?u9n{htTm5DiqrB9{jC@s;lMivv+OiNP zB6Qyy(LFpkh&*8#`YMEAr(hos2c*72zbvm;FlYGCtu*{k$Xqvmv5H%ek@*79?cGeB zVjnCww6T0EJ^tDix%+7JwbJwVsaNg5e;md;2OFS`iiFJRudI!Cf7LT2c$p6>bNehG zd;Y4Zmobgy(8$&LIJ_ELt?7JKt|AC1dez$o_E18ixU4tY^`uYAR7+N7BRvXdFc{MN zQ&EM-YXQbOR_W#U6Eg{nABQ#%oKd{#ddK1-tPc!iCbzVj)?{)h1M} z0I4}Z+oGSqti8Hh`>GVZKO8g|Dyf|Q;2_o%f7_LtZg<+?sH3MVb>f{H8_;Wn)q}cG zLGLPWUxQBTm!rlP)%vhg7009|uO`vxb=k--<;3V|ZH}E!6)Y7#q*HzQho<;yB}|bmbBtds@S+PsOkBZ|AGeo|`F|OZ{Bm z9sT^ROD1o})XE>Rr!dJg=H)NT&D?f`brN?UKYK({MVaOm*tcuMy`4Z$2mw8h?6j2W zx}E(g`io1%(aVn#@8QYh*TglJ`1Wsc^TLJJ03_({#4}XUn za|q$XdG%4OC?i~}J(+S=IuHPV%X`4@g3lx}Ql;r~Xj}Y?bxss49>YN+6hVnX6gzKB zrGx)fWX>2E`qdL%Hl;0X3P`j1S@1XFYl+1A1M@E$p zxoJI=Vggb6FHdzgs5X+4u3QMby&N-azGP;Vi_i)yTO8{eDvLDo`6dY=$%jB%ZFjvXOe;$c~dh^J2KDgkVv(onozNeMER$} zPJhyUfpxyUb0~XS%Xe%yZ5yzE5vL(HX7~~o64{idbxOlhAit~4-xmauA^5uIx(Ddw z=+uxIs0E%*M?LOIEaA8MDkzL{CbnNjJb^4~%=G>J5Q3-Iu+!oPDkK=K&=K}_bkx}H zI!P0X*7?gEf=`=JrxzvF{c{;J@I^(=N4KbHg8>~bSmU;E^EX`o)aXetP>~MF4=0u# zEFriK(;t7#rk6W@7q`}nUxz8ffsPfUmytlm!;sPqO!Kmk6%F zXt$XlX*C;)EO22O=dYVPFC_PIU#r5my6Vl+aAHI^I1r?EFaeT*%JPpI0z{&d0x;p&yi)Ye#_p7QzlPp#sWUbP7oPqU*%JrR{gYZ}K2%DE^|CZ2p7x;8Z}7 z29hdD$3MmS-%9{LuJx|oGTg5OEI|6Lc?ru2I1ONc|4aiHMJx&bM{^mysj(>;2PUn} zh2-nys(uAEf*hwBm|es;)E>$0t&_XC1JD3>3s~3HVus^m1^I0BUd0nV2_>)tO789O zeoiGmiDHFf`3aD$ZlMY7pEk)_+r}Geo%dI#Dt-8Vza<+L_mHD+faIZLc<^q|egovnz`MC6y@@ez7q;uA`%2F2`RM4M z0y`QF44zNtNss1s+s<+EPet~(tf?Z=jWdj@)g9UG^=BLn@kWdGU)qViHPS&RoWfUE zi{&Hc>*N>)jN)Himu^YQ?Mx6fcVM_bCj;m)7{6Y#<0%BJfdnH3n=SYQrfio zQ#+0C5QGMJ%Mj0tZy!K^a%T}qfZtH* zSA`D&3>_k8XUM^A&`rDCr-#ofuoIh|N92TfIEA+MTKINlDq!2<9d$5mLt^IH=YWr0 zBkU6%(Xqj$QiQ^r>oIq)k8-UrZ?eL_-P;PNjP8xx6}M-e`ek(Yk+zBs8W3dW)YRO( z3?R=<-clqTtVZX{puOc(E@ccNA#L}YKPHlq*~xPm9sY%(Eg!0=t366kDE4EZrh@es zK0;W+Y#T4W8m()+yk zx5gA7k(rSD|03+GHk4oqK{)qcV?R_4y2 z7V;&Z?Gt?MMmM7`Ztp!M#FP-B<|dcAbHl znmf}!hLWB_;=Al8;oM@K2v`Zsne$UpXacRFT`!L2urEcfCT9e zn~tSm{!IbbWFd&zqLD;1Y-K=O@~;##3^ zoTU*az!{nR27*D^`2Bi38?gnKv7yH?Vl#wd^ouL>l&y;1cVS&jb@Usv1neW0Z35aS z2Lj?HLgB83VP$lb&Xd09@%+Ri^nOSNBPI*l1=tdr@eere@oIz9mE)&2fiSnNTj=+f z{1EN^d=Ry;A|8lH!+PkM3w`5hD)~d&9XC2@w$60b*Zr(_X2VQ`pJz?geiGh-OTS0N zl0;{83GbIqXljY0!h*uOX_r%?KVL_LZcWT;Kc?6! z$abP)*xd5Sk*UrXstl6TF&eJx$mU(4slaDhRd?oJe>rs zUi1Yg%`MTslxPv^#o{-TuZ!QVD7z&zr^khrI%XmM$i_bI^2uUa<4en`) zU7pQ7A*+18zcOgT{rmOjH>vrN7#y6-@2=4_d{Bz1pF8TulrW_*5{nIibN9u zdf0#<Q03My@Z{?Jv+Zu7HS(nLHSXLqF;yg%vcmuKJU|~)D2owZ z;;&HU_t$u6miGQNf}fZkf|vQfc?n3Zv7Iv5)QgOkv`EmS|4Y36OFMSbQRN@)*z3tV z2;1feQ?P_qRY|5CWE=cwQRH-YPP^NERJvmy4qd$7%D zc#PkVw{*_~O4kxsMyN3Vv`4|u1Ptoh8`&mb4h+Z(9kaMO^tuge|L!MYf9jva^RL!u z$s_pTzeG}L4$`_{+Ly6WG%tV73pLtrkYSJhj~(#uHtBRe37+mV#8QnTIVvkX8>=qE z=3<)pS3H27PS^AQmW*IQl2#a2i3?2-_;>CsR%nDw4VKaWR~WQKV_9jw5a{R6LNZOK z#N8yjFs)2-9)ir@7Tvp&r$~FN7%MC8|3Dd_0)^ybCx}@oP?@f+7i!$isW$fcDRd4n zC>BNk{-GtozVG+2fmDLVl7k#N(j?FSg4bUsP=*pT7XpL{@N}ht|N9Fpu}?a5nzyG% z?wG0?x!DE5cq{a*7F|39KNw#%+SWjTdqs{c_>VxMn?F-ucZBOaa)mM98< z94}Kb#h<>S*Qqy1-arKZWz^O<_Wzvk<>BFl_6WA0`CoP_blNi+;R>rt02R?2q~6O= zj-|E4#){z}oy5^$U1>4F>RbAk(VGir&rbd8#eORwf1|M93dj(kWiqix2pb262%X)p z+uCWKykjt$Q|e`GSQF5EqjP0}QCv`~ecj?0fR*Vf>Ql)O6Gi2UGK4Ly4K#we#teHj zDn8v*Z(g=y63S9gC{2zrh>g+_60JICZH4x%sJ2$s)Q0e=q)T7+KGOeF=+?9$-*-(3 zi?o^RdQ>%IjIyFKLJZsIZufq_I!TDAbSp44R6|9dA|@0w%l`+&!z!j+`m+SG6hnjs zD~iXBgImi*mv&55?`62-F)NgH^RtCqUUB<`>1O3Yj@)-sRVGYcLb(6&sVHq!u=?P}0aKo+VUffZZLwUU0=#8iTv{uwJx+k?%_oTlrhEw;?nfSbP>pBM|*7W5~G-JbBGHzU_(SCrI>Z|%%AqRdqukM z^xS>df}F4b8|3~*NcfC3$w81%X*q{UeB3wZ3#X)ssh7vrb>l|@oaI-2@Vjjv&IUBR zC3#0#MdaQvk2=Zb6lD?iTs54(&N25KkC_22yC&muLL)+zYU(oDB<_87y4JKS^WM(& z@{=)4v&_m#A>SDx|fS@iL3S7%0dQa%! zL0ciE@kJWPMpjthY8gei!YlYzK(oO-^PyyKf0HGt=Y4Dq)&BpVOrhY=g-;tTjDiMBa)IMlM*ym z%W@d+5LIt%c|3W<<+3x0fBW=cU$3*P^2((0MC9GQi>pcW22VfNUNWj@XB9tt^Rh4b ztIm*YB>GMGXh9_~@dZ-hh6@w(cPDwGSoF&Ls4K0KS2r@y8tj+_JK_Jc&A5ke&jguL}Oiv_c7*^6scUdrtOl59?(VL1fprz429xfd? z58qm0r>3_W%=@;U`$X>La(_UTS$4fqcCiy~>ti+ty9zJIrqTjYKz;l~c!P7$il+Tr zrXCl^{b)uU+SwNsZWUfbkNFMed9BMt|6J;Der$;*`pl_DaD(t$!{zT$%40_5h%U+O z3wXY#(~t3&nP6{mVa|O<@Q*0J5#D)EX1ODr}OZK=J^S>Ida#79@SWYVO-p^`e#r$BN zYAYCq;vf#GSg-Pe=ZY+uW*jn=>DP-ZA$T%JS0hXI&xy*B?(z1}vBdkm^j*`Fg?od# z#U*H}b72Z3d^#Qy%U9p_Yv7jibcij(Nz`IzPe9n>0nzbWf&m>Q>__-pfK%e>wrt#T zvdl>-LA^=;#3#Hpw-EF2L%FDs8DB+9Pzetws-m zrqbrmWsK_IwXyu{>{x+ARGE3!>3n7sPH2z)+MOS%x4(@U23cJ#r)SFy8FHnYbTD{{j_U$;ctk8RC+4UIf|Cx3ZVE^M~-_l+)ZRTkT; zj95Lm@rq0M`75p$guk7Xm4xrUi>*&|qHyXU2>I%$Fn+DaAMrxtL@@H?L1pLmHI36B zK0kS3&%{jSbMUK^J_ecJJM~p|yGSb>7g2e!*hx@?@LaG=QYOw0KF03IPtf!&ORhYI z-VMb(mr~}ta%pt`oN5?hop)4(nb!+zt?bFnyuc{cFo7>2rGbH~c=YzPRq}FG&)odC z!+n3L-9qU(Yq%TKFUi`-AIK7C5uH{&+|Ae0FJ)mvQP*psqAxybU`0{;;p)~r1K2O1 zmks=8rqW2Tv7L-`|G~k-i{JB)%uIY-=}!q5?LG7^vUe?5nwzA(_dGmQH+gY1b|KvR zad?8FU9a_pG@*xQ62$U92~tiJHn`g>d(1NlOfA_TC_y z>0VNZzM_LNj31!57#i!n5{ega+V6W#w1J_K#X-49^};5RLxfG%Lpo6l;${cuGdavX z^jh1dM==N5=8Z8;0p>d12f-#4lx?V+BsEO4bQUsIRV83#Y&N%WqJTE6b%en9^FWY> zT}RH+e9I}jSH~ycRK)UoYQ+**yEN|4Jmtt^p2(1o{z^Zd)a|3k$g|-Vp6iAPpW#VO zOd#E7CFL}-TiuA$Uy z(vT!;T2~gePHWA<;nyJ{l^wBHG&LuzFDe;UUwd}P?8FbEtBvX5rf<>t$p{0zxbUu) zAB)S=;WoOoqDKvR{aj*9Jjd%(DmL7bS%-tVMub-bdd=npQ#cBI1p?PDCt35XDS0x) zTfJaW8oAo8)f}EX>sOdtGP{4(oi1ZeR~7xsN2oKp?2Z@Lh1s$sZi$G!HEuiFlIsFD zuAv(!uc1iTTL=q$QO@$uUobBo{@9JY|CwjL)Q1&C;CxY>L-ELO6+t=t@V>>gd-OgP zh2)VNeWPKXX^9!QT>ynZzFM!=#E{+Bv$wrmnDQo^*3L}ZhE#p&Atl8UJVUfNA( zqU)cGPKk{3Y zb}y}O?qvi&vj#yy|AT(g@2r@F*3%2YKJ=?=!(lTq>m9P?3%Xe}fj52>h8Jf4>o5s5 z+<$_rdj?jKG7`b>erwK;2cy*9maXLz@I7yZyjDtb<}|a?2-ECG_rr6!nQv5CF(g_z zwmK%g#um1&jl6d9#2Wsv|7m0C9{QbBY#FQe#&h>qRdgy(P#6s@X{NEXT=v^{yA}B| zUjI0kj6>mQPFFk%%8XW_Z}4`C}4cbiy6Kv6^l%Duz!GCm!lrIAk36nNlelw8adFn zXroL-`y?lCOE=oDPzkJdFkT9A_Z8Tj>W<0`-X^Z4q?ql#jA)0SYy7*uHXkX|kqG`%1O-nC zuA``B&3B#!BF|fkcFYX##x&RyH(m-cu{XDOug^dD{S2QeETunC#r=JNAL&RH=2FuL zWbh?Krt#%FXpWdn((|aaXAXZ(k0vIZgAJAD0DtV~WrBhlV~k2%#0jwY;k!fspK$?# zL<=51LBV4LHwN_#H@?;%mZt$vSM>@kghawpdx9i4H@Bc+#n1(w$j{3I>pE>PV=LB7Z&>Z` z@1LKaA08eaA7@RM5EeEOqX)~E{#o$W@$m4__A3~%Q$DP!l7CF@xycuS3ewsU%Af-p+sh-PqlRkk3GwkFqM{S^U0q$8>EiP8 z%&BCv7M)nH_W_%tj~}_7uO-R4-70r+T|h=-I+z||*1fw{_QusFcXwzS*`F-5h*=HncFkIn&SMa@NB)lqZ zHJ+|b^%R+%gxfVVHw`O0<_8 zu)~YQPADR768OMZP31vFJKcCmKp^JddKA{{6wH!z2|Z!xDKM^~&!$iO!n{zoG;(uu zv!UT??~CR)U6v&isj25Hti(A!l+O5^zpdPnVzF?MrrcDz~4~S&VJh*C)^pnDDFd4z+SuklY~HQ z3W1Gg5J_@db66mfusgY;Mu&#{7EM{<>qttv!IS_EE-o%wI=YFQzZm+m4EzkMz4v=- zC}(FnQ}R0sGgz*{d<6%Qu?eDr>HFR@4zF9k9Ze)E1*+P!sM#$##*OulI^^c%<$Xzg z|K6Xt4a}Dw<3ua`3|+1|itb?U6f1TSlknbB^;SImU=KDtL<)Cky9P!&yzgX#8HM|D zE&!K&0FSMugD;VHpR!O`{=$XW)=B$lx%t6m#Lbs&I=C_d0s?GoY~0)r?d&=xJg%*- zt~%VfL71qW-ZTC4Ck&1tE$(?j#RueR^jd^gXzVksnz+KT3)^`$zc6) z#&doqEiE9;{N1Nazm>wJq!9xFSo~)Ki>5XFrxEjWKUA0K&3*yIn`ja9W*{-h*y zort)y_?0+FfDu9qOsc5;<`jUd8+ii1px>vJ%}ae5)=&Tm=NA50Y0m8%Xko9F(Ms@o zgxCXTA57h@2_4YRUlbR|QwcC}dL4(9)hBMlT1HXMZftBkq#+_AdOQbCR}i+qvJ32( za&vQs3*_GbXZt(G#3IdHa?L#h7qV~`qKPHN#T{MhzbxJK@u|xB?v_&u+tdI3xd@~R z#WaH7wQUtL4z2=3tJ|-UtFYUR+wLL4mK@ z?$)A%oQWTC|I$`jnM`U|NmW$`bIr;A^WRqQxVcFxf!oc%%C&veQ@}qzUy#$H8s}ex zh4~!p2ix*V=H}~xDrm4sfoSMR z^h}5D%&B{R#Q7;g^*?EIwE0M4;z`SLbTdB&#eg53V{a{c|MLx- zY<{o+psUWH@TNFRt$3Y*crr`e4>@>20_a@NHbw57$0UaTR9N20;&XJB+R877xVL!dIo zZVqrNdX@SvCx=X2cn0pn3{Q-waq;pJksQt_9Mi??X=uETjJ%A0(yLTEgP+IkLX<-$1>x#i=f`T5Uk zA7De(eQYqDka?M(a>cPkMh5)tYW-SUT40jOfa0m!l*z=Xj@H&X>{i*|USY$m+Ju1V zU!J`K7^~!Gd)9s!aFc_+9wDmAZ6&#`=cqlo{%PE*Y<5F;`L`M%}f-txBPJj z1L0^WYrrO<+rmk~^H7;7eZ)2K($7z^li%kGVu@TBsz)qbIDvqN)55_ycMsOZ4JKq3;HRdUBJ)Sp97#}b6Z5r~cB#_JIh z6y!ZC1%!0ZgJRan@6Vryq`~jrNLGGk|0JY0B7y?eD#8MGQ)RmoxMi^Ii;AL&Nl8iT zOl>9fAO;oQXq(4k#%p3GnmJ zIhTREojU4hb)pXJ`HqW+)lq*A>VHOvy+l^j7Tcfg6KwE6nw|G+;2-c3;Xq;8FWMGM ztY`?U!jxrirKzDIt*<`8B`8=tv_$K@zh&#`>8Yp3&;p}IzIAs8zj$F>x3I7AV3@Dx!9}7KU)>_N^dmBv zlXO^N7{G- znW1nosXtR2>MO5^z_I#~rZqC+` z(>b7}9u54@)x<&o$O#irTHzBoW2CiEMFWiD=c7|b=Z;@JDA_O!M=4bGG`s5 zbJ{28R1bu0z#%YwXH#Gf{0SjWPWp_ITlj>43CEFyH645%4#Dfc6Rh*c%YVMc@A~yG zGUO6~v<%PKSW39j7QM9QSvR%4*Eu;|Nx9#Mk}DrMxLYKjHY`;B&|BB+V2HDfMRb#? zyLajQ{`lLa8(|aK%nwC%hkY2nPV7CsKt*>9QNq;O*qBv7zz%|`q+~I`Ngvv?XZ_az z*NRI@c6M}tZ&fzz764daO$nO>U>D?%o}QkzWEf2~+ntTTgJ&kM;ski9c$UJFh)sIr`j1|Zw)^v9=BQ_8Z}z^HVX?Z4=#=A zCVr5#IW~$v3Uq!W2=<^>g}Pg`HV}bZTU(j3#yAe0|1O1`7Ac)31|p_lEy{VpNia>jmn3kbhSEc{YMSsQ;zP z@9*kt8v2VgZm;lgjEc^Zc+1-TRR21x?e244Gt~R-h&ly%Cu?Ry9i392LmAI6 zTZPtr5)u+psDL{P9vjaI#G=W`$!ji{Ac&Wk85t8@vB`LQ+2FA#gTMPajibyz0ryW8 z@Xxk~g{CfVd2~%PLj5bj#(ZtEg^5FIZShYd_=W)3WoCFVpF-0VD#TUo54I|iegnTY zqUP*>xEyo9Km-=6|+&8fH=vx0Pn-GqDWwq(1*r^qH&wim3K_VE5st;sf{Vn|nXxwffge ziPrVw#;&?Q>}r}SWmYgej=$x9#1qH`j#-EiQHw)im6UtdG7?fL zr6ze&6xNAb2mAL9{q9V5t`Pe&W$#bwrMA9VidZ}lSXa2%&2g`E6JpqdenYvZrHxk<%DflU%nW3Ct7+(Zy5(`3ybpPj(!(WJ&q?DEHI!S~&Hii& zCgL5nm?GWs2`cfnAh!5qKP5~$i5_(6x%qfK19uxIe3FuFczZ=|)`scJnbc*4pYsaW zAMXkAoWhB1PAzHDcb^5shb2tbzMchYE5zxnWpMki`TTqaXWghdq=kBh#NqPGt*ey} zjTRQWPny}q{O%jvj=>&@{?TE#1@kMlshmXJ3^vo1Om!K% zbcW^mu8}Es+i*S1y`+CNi-xwovmY%1;)P4l{5dKhKKkubku1iyZ88S;AN)j<@IJ#8 zWl+k|Z@V#hXLY_MAoRWW7B`vQ(duGt1%(|&#nP`g(stx*z-L^#hW6_yB^1NZF$vCx z__lpNZqlnWYMk>q)~$A2)eE3b7%Xw>Ok?fGt>MbM>kU2~Zs&=jC(W=00S zih;rjX%P{Tix=ApwRta}z|~!gWCwt)e+xBwv0y|{-1zjj1jYwA(qABDI72M? zXLb$DO>Es_k@mK>XQ`;bFqoZ#!`9C3ZAE3JoVfT|j;5w20OAUV8v@v^0*_MVE0%3~K-*DV-UrX6KdofsQ??fUggV5aK5-9Y$vcLLTt4U0hE zNawh(w!BZ8;e=O_UxH42UFQ}DJf-l7;H$fxF}{Y01J61}D=CAz`e&7MCfcX`WXaub z-^74Nq~p0@2ZY==h1cfql9|E!vj$c+`AdNB_=5m$I8ERVE-&7+ zH|o!o+p|>75?y8-YCXkQtU!CA*VbXy$Y~RAB-*U5k7e-}A>}Nv4O_G{!;c?WSTLLk z0Ee%ECD)MJcej_o%6Dgbd>oyYb_xdogNB9%7`;Lu{|LhtN$ned#@_hQ&BV+MA+xr^ z%+yr%0;Qq95>Yholm7`w;o}Y%%2|D0d0ydJU0K?B7hNjAC}}tRZPkkgM`%Rh=$E>1 zS9pYqg2B@@Lfk!XP5D0Kj0plU^MtiEVo8=PMC*dqoYzus39g5mK``p+FhzxiCfIFK z=1)L3W|iA`>wtt!n{Wa7bYiB{@MZ|#mwjmvz1Z>a?|n78!S$~L{)H;)B!#8$Py7O? zFFzC@6Eef<)zhjy-tA`-bO@3hMZ5`ITIH=cvI&qmHh8-=c4ss9tkO;=_aG%ztv;HA zl&5kJcksRo-_pQPTBf~T+rUy{^i81u}FZwn5FZP<1CPSg=N zD=D2)>g(-wSpI^vv$K2j=#io#j%NI10@R88n2);viGUfy-vF1_Tli+!x+`recnz34 z*slY3%}P%5zW59OAP@ef#J}Oa02YJt zU?j@Vm-Y^qR<_xlWyt6L`5&N{i^-WhFrPQJ{$nwQ2gg=W!_@}gTjizZHbhRa_o2*u>* zrl&7xYTdlq4kIfW$6(aRBN3?MaKP{}8BtkX9qv0|qpYL^cIbfROYxGRV8UkU|DY8K z3B}f?H;1%3@3OU%zJ2RC7&!i^*nXsD_Ry0w7J2M3HNT&6P~UW2NDV%xwZ74ciq~33 z!R&b+G{1ihnvdwQ8UWZGkk~Rnf;wMSWqnj~+bsv9XMJfhC@096G`6%>F zL0m$rZu(0h7q;0~E5}VbWm6ma{_vTyy0*zRWmUAGjn`Sr<^Y*oLJRU)qU3yh=V9e; zqejbe^J*VK%(8=}nvGjLXHQAQU-q!2trSr1iXMH{;tb!-rrE4%Q zVB#W_xRE5pL@k}2O(!lYclc4W6a2wWA8(+?#1cewRZEl7_Jmtsj@k(gX^BZhPs#1q zm#u%AbQ&s(ly`zu>nEb<5j8|iX9iBslG>;IP~L7BOEEheo1Bxw>6zKt`BqR#N7$T! zi2^WfV7Tp4VXpiyK|+4&R$wOTHlNq~`{OOU5|f0M%c*h=`u$}13rYSqL7=3Xq1U#D z_I2ml_=U;#av@8f-Uy`UKTYT@S@;UPrHx~9-?A15q{6=(mp5%GJeWT&rd{&&{k)J^ zNbf#I|2<*RAvxXMt_mLo(=s2_K~je54kjP~V?@&DR>mrUgM$OD0-#^Pnpr3sco1H# zEHnw<$MSLprF-CLtgjzJm_vUChHHu(OUuacaB;yTy3xVGAA+}$u|N;zZGvhVC&_yq z(<^G>k7Su=l5KJ=5m|fFbdWc?VVzZDTBwMIOevZmv1of*mmrw<-2VVykr)cg(1jVb zi$s15XRA1lf0w!idrs7-uuQR|s~JV^YsF&=0WC6E#ScwFB#Cw^M}oBPLDNMA0K^ME|-j;J3RiSy`9aycjTU4v)C`2`$1fmY0s*P z?d?|w@y^vIRqq4k$=af!yOhw21mYEHL|VX>CQO>0=P>=et1F|DYIB+Nz}rG+S>pmG zxV&iYruD)re}awPmxs3Lb4sX*{WBKp>nnGCtx?NHIcm1rF|L&t{S`T$7a}J=uJbu( zh0@Jre+%SY?@mo-*)4ufw9&u%3a)KC^r!Z4=a8=MIEm9_1TtnB%K${F$ zNoeGIdmI>|DFur%dpR3yUxT>=9u;n#xGJ@D3KUPn)%c~Hp%1)MdN^3-aC`mf`5YwPMt61qA%Adik--r7bt9v|>o6#Vl!OH4oz!8+ zR*TUS8~UrREH9fH0~~nth=LOO8_XrP#FT_NsUBZjKSC3V`Hf4Ol{=~CO)+)cgP*}DoN&c6Fswp%?{DxDm{3o9!_ zE1&I?eCo2i@9l?coKoj=fo}@sDYAI|gEJ0=-+#VkGNVFMx-lj$*;!s*u!Nj)_SZv; zeVr1-{;z|te88ICS4`6Ohb26WcmYrq(A6bQ;OC%^2rQrgOU^4|?Hl|2EP-uxt-Z}I zCKq}$lSF$X<=4w4oRoq;nXV3*QMk`K%ecz=4`su|5mzEGv9Gtw#D$^Plk%$C^CV{y z4w>pXuc4vc?g`{EFFUq3Eu+oFg^5gN!;*^Zm`E(Y3lbv{)TvYX-Znj&(v}?yB4?cw zOujW#P7kX&?LMLNmu8xNYv{C@n@S(}7 z5LSbQnK>&vyRHU2@?U9ABH{#)IaxoulV@HYZC_$!rQg**Rv72|6|*gnyEoaQa zNugbg%bfOooR*?pEU+@*OOx$=TkzMcOo^aoFu?t~NU&JO&QHU{=&zHWIB_NA`jt!f zlu~oc%M&yf78idKiS1|B6c&oB{%|-{GXeUbZ~jcBx%cXnBBDL;_X-&T-Nnw1skwX! zMZIoD@|!vY!s2%u#qUP8CTdhVPcB=$(pG}5ZL8BPI`+}ze3kc1KeLX_M|ui-FIQnH zsgK=r0G0K+s_t2J`AI^PnR{MJjuwV2o4@x3V)pJbhkfz1>VeL86MORtR<>)-Fa~LXW&{fs>o8*1^s?>x92&?(y#QVB-TU6v#diGg9WXgyz+HRiYH1D@crY?B=*_*&&Aq)N z5)QZoKlmcXst_3X+Be!W?ei*sqM6`#`Xn5PgEADSGc*Mf!K(=bP2WkfLx5eeR?`A=iY59 z5XxW+ff@?SqX5jDGw2(j6#%yE0PeU3Mn?E~dFyORDJ?5@ySi@M)PMSv9pm@%B{>{` zGgA8DX;<;i6ciMkAt3>a_pGvOs;XYQYg2GeidkU~YYMS}%An~C3-r~V;$oM}wn#=( z+$i(Cb?@Hi(Z~CK6F2jNbW|2zP4%-TUh#*0%25EUM6SAhe~D*lBFTE?o%3#jG`H`A zyXI!4em{{|R!s)~fN3srL1k0sl=}89`YRNFpfXbO&R88B90YP{N6hY-aWm+gVue8Bp=ays%X0SC(tJ<40|W~? zRXZ_yXv!_j&yQcLZD{?syj30HZTImCR<}{Y!fr910i8=n{u-C3ugCTMqDUk?n4wG| z=}YOb&B|CBV%EBZ4s{xmNN*oFXIbdq=p^-&3*)3$RLnoEaDVogUxUTKd@=EjJmxJM zN`56V9a&fKHZ}E41(`@-x{D|qTa9`CgzEEJ;1f$qq|$p{1V2<&J;Q^nFzyt}kB_HM zJewltdFs8Mp&?8afA+kt==SMsC};7he?sz1L{6HYnu5G`%fyB?!$~u$5SdCA9fAV= z6->v0KC=x;h-vM+ckF8D(j#V@6A7g2797xM`7QEl)-;|lcM8OnxpzAVNlHw7xLQZL zxH#!xaIxz6$a4#4I-FVVax*Bq{7#cXt1K@+-_i6@g0^&rB3fF4WHCJbW-%dgutBV3Wu%n$B%Oz_7RhRT19n!q9P)!R%FnacGl$N<+b+qmIG;*M>}r(VQc%($)@nf zXS>thz56*eGCJ?J8I&FjorPQMr$VnN0(prKIAZe_?pi<$tLZ*G1guwaZ zTV@oDBopY(p0GIu1_Xu@nNPG`@?VZfebto5q6(&g;Y3b%cwG-Ce zYYD7`VmaDOXZ@m!Gt-Fe4;w5jEOuW!c^w6c0Mxs8?{H~KoNKP$%7Y0imy^_*tinP< zKqTWtxpxU7Q;+#r-+)E2&DZ|V{Ka)%yOk5(fu%mfPo3Me!>-z?_4gR0_vHEDG4^wo zGMy2r@g?A;Qx>bnE$7vuGqyX>nj+gmgdX3S={Y&8P;D0D?IZq*x-Nd)xC9f_QCVr7 zg%j};$>yL~asZSSpFr=gr$yk9#m&Rxv9tQ7-Mo(O80t5v536`GJUll93u%&>u&lV( zg5Si4#q8a6**a)ZD%_{_Y5V5n-$!&NM{(lSSc&80sUurU%kgw(wGyfGb(dj(f)KIf z5v_@xoq%KufisMxtBz+$j6zC==t1?mYtV6qZ?Hhg;!XRqc31!4ha}Qwc?qf4%g(3( z;qm!~s&1T?)>cPfe-w-FL6@a-ha-%C=*`qC!M$8qy}vB0c0*TJcND44%Ip&KY60p~+}mhDb9uZ9Jo-_b9zVPv zjKF}rOiAganFSJU^1$WstUxG@lf%2#y9E|tl#GJT*QlY}7mo(2oZhZ*JCvx`GB9b>Z>$Zpv%aX7dl-c(P z&{hh(pd5H1Vos2VPbHs$kD+y+FL~x%wG#x5qWb%ewABx0`jbb@_loZwuI7dEis>$z zr{|FGIinh1JgB4n@_F2Fjmk0%IEQS{PwXaw7?KzjegT2CgqhqyorNlp+eqGdj&O`6<$`J7s}lChS_V_(VcT$A6kl#b;r!n47zCZp6@h;IuxK6+^#gbRWsWpQ#`Cn1o zh0V^@-?d=^@?c?4NG#>&kWQ;m?v$G^IT|I~NA=JrT|;(u9s}+z0U9hLf^rsmUcF5C z2qp#wqVz8YrwwJwk@?iKNp%|0J(=$JAKLkKKQQmaSgL&*8Yb0ijT`_b`{Qn*I@S=Tmg&faIf%L)eQyLa#AuI1V}s(X46i77if zZ)|N9<=i_(a|zu;U`t%;wF%rU#6OT;w&w$zWu(PlVOw44=P z{ryt^sY7&d%Q^Ti`Q1rbQ(e7y^?VX(iRg^oAdb?9d#UQ)-bpjeD!<~flH*=`IRfV| z>)f=6(3AZDTyfx1%QjZih0FN~$o=H*e5qFymS2BW^%_cA1sz(ptVjqh4~lVa#qkf7 zyRJv6r}c8Ter|OASnSrWOYu20o8ji;AQvq%)(aTWT$07WPI;bsI23ge+6D^*=eags zpTOUkvhh|6+?|ZTvp!$kEmmTAh%xgSFy6yhbF<`pd8bZpnSp}&ekNKF9Ba!={mCpd zDu;^gVLTQz#AWm=-?PD00H=qBhRJsj{LjY>q@>PH|LoTyUzsO6>mTGY6pFyn+LL_n$Pog3*Ne1JrQ$&(Yi)%7Qm{O36 zuKFhvT}hE;$LU2dQL*cxx!15)97=8eeCZrSW|w8Z*&^sOwC#lw#ok=G5EZmu4T%(h zPKEH69Qeo2*$9Qevi6x7r675U}tJt>m}F#0qk!=bDD1Hl9v z-5=CTtIzKe7Gf*8a)+;_y`CKGWe(#3C|QQn*vlVS)o>Al=+6~{I&Y?%p~R3UkJKPf z;+G)Palxm@$#f;Q=u70p^Rf2}MiR8p{d?_a6lZ?)(fp#*DY9gHB~8 z1g44Q(p5Jz*eOgG*;?N4~!EHO@#f!!-LHK?5L%6!x+Fy%Gp z9^>CHb#B;Z`B^@)Q$1x9Ur;Oyq5Nj{T(6^pyGvn>WNwU4)5U)RT5MbSx;eQO^5ouKB%)QRg z-vmS~%tv;k)$qmejuAYI`Rq0+X^P90ZpT~w>K28To#?( z&Lw*yCREv`kIl_bJ%!1_9rUt*=(7wfd5*8K{VDzaQDsf1N}x0epd3G6dDt4id9{)| zt+rpxWI*O#mo6azs+XS0Po?*V;d-kFrE9~-JBoc7g;xEwK0&LX)A}IZv8>pCHh)l6 zp`ypAS$w0d)cbXWi(Qd6pXbFh0wuS7yaN}=$tub^T1fi5Su1Ydx+@Rg21LpwKjnN5 z`X?TBL*$kB*uZC|2Dn2>nV*w$LfS8jgOf9#Pe~ySa!daC01a#cg+8kB zvtLK8U9QV`i*{Yf`!1`({`=Zm7orGyi3%V18rRSVEY^mz^*TB_(ubbXdy|((k*##) z3i=U|#9Q8a>vXhuE8V5Qwk&+VTI@^JCy z_q{a=Uf9A|wi=1>24Z6!RNXEY_Sce$r%&4puoP?v^ha+mVyHf<)|C``^zTMYhT>TG zFH2kaPhT%KS12UEf=brT=kO6Z4A&|+c>dIgSuY=#o zyZ3FklKC;9n^?TW@$%)%wmR**9A_T8yVIR&JNkxrSSLrY7+0uy`KaIM9#jaD^75kt z0|ZM>UJFfl#R2ouRdb#>xM44^e2NrmiZ69wnW^(nsfU4vcGgosEmUyOw=k3hmOV{E;8@;<}77sRq{0Tg!#oOGdo3i)400 z)ia-3@ZTccI(32FF;<`70eR)H8lJ~HEeS*1(Ne!r1$M9hS#p7?Qt3nc|hqw}v3(hjv!eWs#)6;osOpAde zx5Cr1*G3GxMtbymO0)uF1;-^ zfWeU6r}S}H9sPeQ6^V8GAK4VRCazkV%wG}Y44(NVDA_7r-8tAYalB6#$l565e8 zES(=cT7!wVNFYs**oJB7)MtL+i`m`d;pJs3fl2aYI!S7$%i%tm1brx!YT84KdI3;L z-7-8g*@0V^F_!PQO)E=fs%t~CRq+bM!#2u+3o(@gm6*jvzO>8YZ71~tZ;}i(%2Awx z8)5_P;lMopzBxER$OlIqwAMWA7+|z3DXySKrE+|ki@zki%=20QS@wcnS@ANuE&yIo z|Madx6EVM^xwL*~pm1EGf=NEyl}N6{*OG;+We>L4>0-BQYoGSaFY5X|+A>f*gT@tf zbm>1a-8>y|TZ(Sq#Njzpg6RGhXZru??Yjf9eBZaNY$|1BgbEF_jLaUT5JF~BR%NEl z?3EGOWRFKGii~WDB9tB3D}{&b8IScl?}z$S-_P&;zW==MUy0|r@9Vy<^E%J-I?v-c zZoUOBc0wFeh{2Qk{LWDPf#0?b0Y|zV7x(PaX@r_;IRBopJ?HPCb_%lF1uu*j z`J(^3fs>}=aRoY=!OyA88`B;2Ce{r~UKrG`yjaY3v?AzlZH1TKY67Mhiu89S{n85y z>Bxa~1ON)Ft<8R!Nn_xG$-a<$HHKQo@iuzT#rnVs>EOrTA zTHFXh56)!_O2DaOU|?WjQIeDE>hD)lRP-jl%1sw(6h1UGG(3Dm{l0cp8ZZhVh2_^7 zH8eFn#>q+Sy8-WzZ%#gw>ITKvz8=?)71IBu$@9}FmdNrOM=jiv2J)q{gv%}XvrH{+ zZj3r}_&J@4;Nw)}P->Ukyt#KFPA zU*1EtqalX9CC7{s6-GsT4zQIO70|&HS_W2#dMU_TEFat5z~wo*ua!VjT>J$0Wzv7T zVMreUfcQ}PB(J&S85OAw$7qZq0S`$5S^lTVb)LQ&zNmXsqY0PP>YqH#Z%+7R_=4$F zD*wxm>YvT0V{#9UT{2y#r8V)JD0(jCwjKiji7#Y=G6yiP;Eb!O#MXlF?g(DCjptMX z`$cSnYMDtL`YV66YaY(rQ%r0 zGq2c^2>QD_FL%!R*QfbnLzaTl(ykvoeU}>FE z6)sKSw*2I!1M3Um)3S6-2O|%(#wix0jwTwtZW=x7kN}x2i-$dG;k}FA;_sj{g*RwhF((@J^ zn8-sBgjMAjV^NMHEf^wb*dm?;2&qknTJGQ92ntHB5|SijK?q%X+w^IzSXA_G?a)>? zn~j(extZ1xJEr=TxRv&HK3!Cz0*IV0!VCDw5y}n?K*uWy%@{NGmka+1Xq62Q(l$ z1<^-R97=3*iJWc^N>vz{Cl{j7yO)9!jl^{i92*m^)jHr_C#;>>bg-3wa_Hv7dLh-) zE*q8IfD)4FCkRp+y~2)YTt3f+1NCLDtss2unR=gVKEtgl3yAhF}d z#XG_y_F`AjqMp2y!dz}AHvw3atoI$>?)D>2g+{~7q3y{4-Ppi%lk$K`diH`YEj>bZ zgY|ug<5}x)zw00Lq5;GXf;A&lQzS-iAqV-&u=G=yKCbq->!0HX3St2g&DwotF-CR1 zwg_7hjG@REE$zF@(;TX6PSYSQ2>=qcvK@r^jx+!;h-i?}0|*iUaRKX*1Gt22+Z4;A z*MGt{uD9p#GHXVodPR0mJy&`*vFf|!V7{VvtaPRgAiGg;6(|EJx*=ea@=cqN(lPWw(VewlOb- z(@@ciu_s6x0naei*5uddSZyK*E~>|(5SsB>p=TNlPR0g@g!nw2ZfIzb>)49|3eabs zmUmQSf)r%73_D;RBrEiaK^-Qkk!%*Zkg^g-_$>=FQ2p2pM@j%--5ol{Ll3C{A^2TsnL4LDt$DLynA|lF8cRXt_jLgh82t!Agm+dp! zS0hd+qHhcL!n3cetjy2P1K8!$r@cgs=GJa*Zua(cBVvh7`uq)zjiS0i9p>id3^54_ zeZ9RlR~w!qgflye#p?0O6daWcH%dlWAki7bra0tb;dQxj01vY&9dR?qUNfi8Tb3X< zWFOxOx!B<*y`wJuP;omcq@=xE5Ui$izq7N`po%&g1rFt0WQB{>ri$>svGH+JQo;Qt z+1Yo%uR@c>%&g8t5UNW+V+80v6_u#_aYqLS20nwe6wV9m-BKG*pg+7@wFpI`Wr9$& zkD%Z^S>oOOoztdgk9G}8P_!p*Y$(0F+qj18g&pCMXG8)}!@}*gy9BrM#BDiG=L3I> z{Z&_S`JH+*p$+FaOZ`s(9$v#lmqs=}BTVf7x*<|l@v6A^gPV}b42=mT;0uAnddl;H z|Hok$m)gEQW<50UxLC3@0&Ie++C@sAKPQ`S90deVj8FXzl5U4odH*fx;#^b8U1K#@ zDW5N?UkhF{Hb3G6E-nsnMe;0$5~#vn49H5uR!v5o(iAELq8YU2bW#rk2ThsJ7JM~r z&{T!wr}9nijj_^4k7zl|v3HO-*VEhEz1!(rTPcc_g$3TUZPglR77-DlN6$vM zjfPEvLe21jbCV}0N$_dLuF;I4WL_7|l+2IpYyh0#M;y)jUn`44WL@&?Na%Xi+W?@! z``rVgMoOmqx0!o{bk_28j24EU2Q~9jQ&Y#Re6JuA)YjHcfBDj`c+m-{DsXPO$ioT8 zK$fkuuR%9LyVF<^nuD9YC!ZjUvF~(a58Fuok!UakW-`K+J_~XO2y!?eS{%};W(H$E|ur(Nc5 z{0Wi^!~?VR;pmbXqDNZlYQS-At9mGr8LC5CTT7XIm)1l(yX)R2TO)MSpn4At>63{J zg>PQHI>asc8}%+hEkF@`Ah;%kbO~V!Jgaoz3xxEDorP2+18N*&Ok#1(I=FB-{je;b}t*ZbELZ=WrYak^TS%P>HWj@&_27vLN>^o-|q$$e-% zGRG_``#;_D{yKuRKX>?xfa9XW5oPnWVIY9`8uoMypq%{PSgfLU6u&8@>1ZFltL(O4 z2I7Gv*<#5bM1TbA1IzGqxiIGtD&+S|Sd$&nmjflDuOm&dL^{;Ckc``6dI?f3;aXQd zlFx(drvPFuQ5@Ui$>pmM6n}D3?I>*T0?g>Kwdb_urb$=)9QTjI?`X!FYA!BpCK#6_ zz;S~K2vXo-UlB;B@A-Hl7`!^d$rptL48eH(Eh?UQ& zBP=2|tfMkPBxz(5jynfu%x_#OdvjV_GsX@ZubVX4^igq+J9;0D$<1##*%hL_0dmt_ zXXmVuq!OuGZ$CXaefl&CKQA|Ke{f<7H?4##eLIcU=qhYa#!7X^@tfTmt?3C7;p)o3 z_K%MbX-XT}7@iHZG!CHRQ?k9?uw?YsKL2k1kOY~&ro|Wi+lqN71Kb4y#VGW|R7t9O zrsNy$+UEyp+(%ud9yPvD9{dVT)XuNp+VJYBk$(a+-z8hC<>oi|WvgT9uNkWEno8fY zx&1L?xVDe-N~RyhitSoPQ<3)*3HMidf=AL11IMe*7dO?s^6(%?dmoNwxP7z0QHg>s zxG!(*`9WjeHFgon!$JqP%3Y%HI2sk5H@O9}9v>C|+F?gJ(NXy&H75Q0t3E%~d!ny> zI;GqeL#a}wp85C+tJ6+r2cOMk;SH-+XDFVp9|3(W_DoiVfwXc(?vL*Ai%00{c^tNg zg>oZ%MY4_db`7djybvUrF|#X;zFHTtVnP||?hqZn)H4)*E!{@p+A-n)>r?#a_LnOu z@HRO=e5$|qeqw=0)>c4t%vB>zXvw(O)=IriB$WDwlBK%Xb0%6u-Stan7~r;UrWT_V z0!XF35B>I>+gZ&ChXb1asB?!{`zi?c*%kNLrcR&Fng1NEOkZw$_JQ#Q9f7#SIWzlw zo|$WAvPRVdb)--7o1+|^iRyMcEn0)c8 zl)CR4G{uJ{IgtvkGo*^f9t%|<9a}5P)^-nx4HMS1vCL#SIC*!;+t)o$3-r7spz|B( zZjj&Ly7z&#vH~slfsTitatE4s&9voINDp?qd?}uF;AZT&su4$Mz7-lz{n6L#8%s|x z9mu`;x69<9L3)Yu$a_f>^P@HoNChW+ynYPo=;>%(d3*h)w5SwYg$!)iM?na)*GraH znuroK4qE*Ck*&=BfIun5C8%^4_Uoc&R9W3c&Cn1=BE}vpw?HtHPsoLVl3f}?X15N) zN*;i>{n%ZZt_}aea4q)x5SEHHGblIKq=-wP#L~FVsThy8Mv*_jk@u4A+%CovR!3*h zShD74U7J0a$pT{N_Qe+E8P91562syw&Rmya0hzn2W6jZg(rp5>6OWR)Na9r)7TBzB z*IXef4H+p1wKrVL?9#NiljSZNL=PO zqS4q*?175|Ao@k-i_&^DD&Ze;ft?w&5fpzcJ(TIt5?{J`Xn>Nqkd8Q|+M&w9j{(&6 zyoc!J=USln{?V47IO{@)>@2nCW1+RFrsXrK| zl^uJJOVODD5*zsiB0eHAgUD5-OQRpv=^MXvAADmpRC+h(=n8{)ve%j)xC6=h5jX>M zBZzQVZ0|$i;)UCb4X|FE%F{poRQ@!eBHOzxKCi5vJ1)tiF_GumXOcryx@pAjd^ri^ z2Q`H;>@BBD_1y1^w>}Rg*SP+H`28NSTp&P4Qs7d|RT={}vQyB*fWVQ5+%~}vwNGY+ z-PRB|@Y@ngaLiFCBmqSR9d2OmLqK^)7{PXyG-cmwWLMd!{F@-nPF}6FhkoDA=c*hj z@<&Yi7c3M~W{tFpP`LQ!#*Gt-+Rj4uc{6)on!NOZVsU6W_j;Z}N<#Rz#B5FE|q&qQUiK{4(T;LR$x$CP#oS(Hc$ z*d=s0oFVQ$99#A>dkp+%ZAXz5qDlHZc!YG(U(=C6L}NmWq+m#{!M*qI;gsGz3W6;F z*>DjNVdW~E@0Ka2sO%4UBFP$t zN(OfiNuCA+Smustz>*+IG_yK6si4nUvg_dEtuGxr3EKg=SRn4aM5Jp^bZ~BUT~3)5|ZO@_X35|5zM&MdD#3=!pIp{%uUiUV-V|f#Bjy1&dO^=7PAMcLdUc8FNgV zhx&bdV~unF$C{c8Mn?fOnw<^RYwhe50RUZ)SwYXp$W2T2)K8NLa{`)raU@r> zs^KLKOcPU6lBZ99;oJ*IO`kt(HxeZHTrUzFZUHnE$j9`Jfu5GF7|V|4W}k_Am6(K-lzlPd zBVZk{6|dZb)6Lh3yNRu9SS-38K;Q(PnZdQ!nlLP2v0@d&pn#~sKx5(+ zdLNd3+lv4`(bf80tRS(rKO=c8>W6Z}T_1*9wR{zK4Gq0m<{4DvQ@Xh3bv_U|*^U)` zEJ@am=1$mXt(DkK=(c~^{vK&_+4Nf{_l>1ara=TK7t0D&(68-)OdS&hV0$B|^vHENz6S@Ig;@COO_8 zh#P+n_pB%nc_ARi_4nCz6`^`93e7vSrlzL{O6}?`ix$>URpw{h)=52Uj>SFV_dLkR zcu_&Yh$G1r9qSJCoeQ$ES{fSig(#zNz`iECVg0vWKvIqDx_{dX-nIxT`;>2jvvsWZ z84^U=Gyis5_%cS9w~%f`J(f{pfxBsxFolqVfzB?Y`Ae2_Ong_tALA_+!PUr~eyzEdzPuV-`>N5L6 z4F<~A$2nV|Q4Ur=N`!^x>!U$_21*B^lP77Wsb!Vn`xh^Mz4aB2aDVzrl}i+4i^s?U zQ6WJ=xyB~^(CzKcJBiLiD&jtX&;T$fK(*kII~mptcw-*)KrjiWYr48OLVSFq@6GeaDpGgapy68r0b1-MeMm|D|6()Aqu;zLD5&lU z_u)&26Y>8R0YZblaFT&E%LM(sy%f&N>+)v{phW*i#MxhG3X@4F-$h}Y{&zHjzagSu zT{55vNwedIw-baNXO?gu3B6?F2ubO``8;GaKULzkulD;k0=qoYk_M3ks!O=%S?}E| z?fvJrrfG%IY-_Cj3^@72VG4i8N1WLqA|C$|Uw57s8g>@}*KZ()COb=wxDH5u$Vc*_ zs7(9c9Q^M_y%Sj>0CPTg_%leuIe-5}x&JlFK`1%IqU&~aDDK=;5{3=~E$>JWll$q+ z+{F()$dQ3)h#a#q=tG{=_Z_Z>9yQpfoev*I@`%T(I2_kbp$6d7HXr+8v&WrP?NG!`|1#*ix^$5GDSit4*we8_6|M^X-_zqJ#tcDCxMI-!g5$JW|u#WFirqe(`G00UM)K8MXCU4 z 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 literal 0 HcmV?d00001 diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/onprem.tf b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/onprem.tf new file mode 100644 index 000000000..07bedf8a8 --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/onprem.tf @@ -0,0 +1,152 @@ +/** + * Copyright 2022 Google LLC + * + * 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. + */ + +module "onprem_project" { + source = "../../../../modules/project" + billing_account = var.billing_account_id + parent = var.parent + name = var.onprem_project_id + services = [ + "compute.googleapis.com" + ] +} + +module "onprem_vpc" { + source = "../../../../modules/net-vpc" + project_id = module.onprem_project.project_id + name = "vpc" + subnets_proxy_only = [ + { + ip_cidr_range = var.onprem_proxy_only_subnet_ip_cidr_range + name = "regional-proxy" + region = var.region + active = true + } + ] + subnets = [ + { + ip_cidr_range = var.onprem_subnet_ip_cidr_range + name = "subnet" + region = var.region + } + ] +} + +module "firewall" { + source = "../../../../modules/net-vpc-firewall" + project_id = module.onprem_project.project_id + network = module.onprem_vpc.network.name + default_rules_config = { + disabled = true + } + ingress_rules = { + fw-allow-health-check = { + source_ranges = ["35.191.0.0/16", "130.211.0.0/22"] + targets = ["http-server"] + rules = [{ protocol = "tcp", ports = ["80"] }] + } + fw-allow-proxies = { + source_ranges = [var.onprem_proxy_only_subnet_ip_cidr_range] + targets = ["http-server"] + rules = [{ protocol = "tcp", ports = ["80"] }] + } + } +} + +module "cos-nginx" { + source = "../../../../modules/cloud-config-container/nginx" +} + +module "instance_template" { + source = "../../../../modules/compute-vm" + project_id = module.onprem_project.project_id + name = "nginx-template" + zone = var.zone + tags = ["http-server", "ssh"] + network_interfaces = [{ + network = module.onprem_vpc.self_link + subnetwork = module.onprem_vpc.subnet_self_links["${var.region}/subnet"] + nat = false + addresses = null + }] + boot_disk = { + image = "projects/cos-cloud/global/images/family/cos-stable" + type = "pd-ssd" + size = 10 + } + create_template = true + metadata = { + user-data = module.cos-nginx.cloud_config + } +} + +module "mig" { + source = "../../../../modules/compute-mig" + project_id = module.onprem_project.project_id + location = var.region + name = "mig" + target_size = 2 + instance_template = module.instance_template.template.self_link + named_ports = { + http = 80 + } + health_check_config = { + check_interval_sec = 1 + enable_logging = true + healthy_threshold = 1 + http = { + port_name = "http" + } + timeout_sec = 1 + unhealthy_threshold = 1 + } +} + +module "onprem_ilb_l7" { + source = "../../../../modules/net-ilb-l7" + name = "ilb" + project_id = module.onprem_project.project_id + region = var.region + backend_service_configs = { + default = { + port_name = "http" + backends = [{ + group = module.mig.group_manager.instance_group + }] + } + } + health_check_configs = { + default = { + check_interval_sec = 1 + enable_logging = true + healthy_threshold = 1 + http = { + port_name = "http" + port_specification = "USE_NAMED_PORT" + request_path = "/" + } + timeout_sec = 1 + unhealthy_threshold = 1 + } + } + vpc_config = { + network = module.onprem_vpc.self_link + subnetwork = module.onprem_vpc.subnet_self_links["${var.region}/subnet"] + } + depends_on = [ + module.onprem_vpc.subnets_proxy_only + ] +} diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/outputs.tf b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/outputs.tf new file mode 100644 index 000000000..3dffa2808 --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/outputs.tf @@ -0,0 +1,20 @@ +/** + * Copyright 2022 Google LLC + * + * 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. + */ + +output "ip_address" { + description = "GLB IP address." + value = module.glb.address +} \ No newline at end of file diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/templates/deploy-apiproxy.sh.tpl b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/templates/deploy-apiproxy.sh.tpl new file mode 100644 index 000000000..21a0be14f --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/templates/deploy-apiproxy.sh.tpl @@ -0,0 +1,34 @@ +# Copyright 2022 Google LLC +# +# 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. + +#!/bin/bash + +ORGANIZATION=${organization} +ENVIRONMENT=${environment} + +export TOKEN=$(gcloud auth print-access-token) + +curl -v -X POST \ +-H "Authorization: Bearer $TOKEN" \ +-H "Content-Type:application/octet-stream" \ +-T 'bundle.zip' \ +"https://apigee.googleapis.com/v1/organizations/$ORGANIZATION/apis?name=test&action=import" + +curl -v -X POST \ +-H "Authorization: Bearer $TOKEN" \ +"https://apigee.googleapis.com/v1/organizations/$ORGANIZATION/environments/$ENVIRONMENT/apis/test/revisions/1/deployments" + +curl -v \ +-H "Authorization: Bearer $TOKEN" \ +"https://apigee.googleapis.com/v1/organizations/$ORGANIZATION/environments/$ENVIRONMENT/apis/test/revisions/1/deployments" diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/templates/targets/default.xml.tpl b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/templates/targets/default.xml.tpl new file mode 100644 index 000000000..a2290cc4c --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/templates/targets/default.xml.tpl @@ -0,0 +1,15 @@ + + + + + + + + + + + + + http://${ip_address} + + \ No newline at end of file diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/terraform.tfvars.sample b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/terraform.tfvars.sample new file mode 100644 index 000000000..8c3ff2970 --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/terraform.tfvars.sample @@ -0,0 +1,5 @@ +billing_account_id = "12345-12345-123456" +parent = "folders/123456789" +apigee_project_id = "my-apigee-project" +onprem_project_id = "my-onprem-project" +hostname = "test.myorg.org" \ No newline at end of file diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/variables.tf b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/variables.tf new file mode 100644 index 000000000..5d28ab9f7 --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/variables.tf @@ -0,0 +1,90 @@ +/** + * Copyright 2022 Google LLC + * + * 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. + */ + +variable "apigee_project_id" { + description = "Project ID." + type = string + nullable = false +} + +variable "apigee_proxy_only_subnet_ip_cidr_range" { + description = "Subnet IP CIDR range." + type = string + default = "10.2.1.0/24" +} + +variable "apigee_psa_ip_cidr_range" { + description = "Apigee PSA IP CIDR range." + type = string + default = "10.0.4.0/22" +} + +variable "apigee_psc_subnet_ip_cidr_range" { + description = "Subnet IP CIDR range." + type = string + default = "10.2.2.0/24" +} + +variable "apigee_subnet_ip_cidr_range" { + description = "Subnet IP CIDR range." + type = string + default = "10.2.0.0/24" +} + +variable "billing_account_id" { + description = "Parameters for the creation of the new project." + type = string +} + +variable "hostname" { + description = "Host name." + type = string +} + +variable "onprem_project_id" { + description = "Project ID." + type = string + nullable = false +} + +variable "onprem_proxy_only_subnet_ip_cidr_range" { + description = "Subnet IP CIDR range." + type = string + default = "10.1.1.0/24" +} + +variable "onprem_subnet_ip_cidr_range" { + description = "Subnet IP CIDR range." + type = string + default = "10.1.0.0/24" +} + +variable "parent" { + description = "Parent (organizations/organizationID or folders/folderID)." + type = string +} + +variable "region" { + description = "Region." + type = string + default = "europe-west1" +} + +variable "zone" { + description = "Zone." + type = string + default = "europe-west1-c" +} diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/versions.tf b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/versions.tf new file mode 100644 index 000000000..90b632f6d --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/versions.tf @@ -0,0 +1,29 @@ +# Copyright 2022 Google LLC +# +# 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 +# +# https://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. + +terraform { + required_version = ">= 1.3.1" + required_providers { + google = { + source = "hashicorp/google" + version = ">= 4.47.0" # tftest + } + google-beta = { + source = "hashicorp/google-beta" + version = ">= 4.47.0" # tftest + } + } +} + + diff --git a/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/vpn.tf b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/vpn.tf new file mode 100644 index 000000000..c39878d19 --- /dev/null +++ b/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/vpn.tf @@ -0,0 +1,117 @@ +/** + * Copyright 2022 Google LLC + * + * 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. + */ + +module "apigee_vpn" { + source = "../../../../modules/net-vpn-ha" + project_id = module.apigee_project.project_id + network = module.apigee_vpc.self_link + region = var.region + name = "vpn" + router_config = { + name = "router" + asn = 64513 + custom_advertise = { + all_subnets = true + ip_ranges = { + "35.191.0.0/16" = "health checks" + "130.211.0.0/22" = "load balancers" + } + mode = "CUSTOM" + } + } + peer_gateway = { + gcp = module.onprem_vpn.self_link + } + tunnels = { + 0 = { + bgp_peer = { + address = "169.254.2.2" + asn = 64514 + } + bgp_peer_options = null + bgp_session_range = "169.254.2.1/30" + ike_version = 2 + peer_external_gateway_interface = null + router = null + shared_secret = null + vpn_gateway_interface = 0 + } + 1 = { + bgp_peer = { + address = "169.254.2.6" + asn = 64514 + } + bgp_peer_options = null + bgp_session_range = "169.254.2.5/30" + ike_version = 2 + peer_external_gateway_interface = null + router = null + shared_secret = null + vpn_gateway_interface = 1 + } + } +} + +module "onprem_vpn" { + source = "../../../../modules/net-vpn-ha" + project_id = module.onprem_project.project_id + network = module.onprem_vpc.self_link + region = var.region + name = "vpn" + router_config = { + name = "router-${var.region}" + asn = 64514 + custom_advertise = { + all_subnets = false + ip_ranges = { + (var.onprem_subnet_ip_cidr_range) = "subnet range" + } + mode = "CUSTOM" + } + } + peer_gateway = { + gcp = module.apigee_vpn.self_link + } + tunnels = { + 0 = { + bgp_peer = { + address = "169.254.2.1" + asn = 64513 + } + bgp_peer_options = null + bgp_session_range = "169.254.2.2/30" + ike_version = 2 + peer_external_gateway_interface = null + router = null + shared_secret = module.apigee_vpn.random_secret + vpn_gateway_interface = 0 + } + 1 = { + bgp_peer = { + address = "169.254.2.5" + asn = 64513 + } + bgp_peer_options = null + bgp_session_range = "169.254.2.6/30" + ike_version = 2 + peer_external_gateway_interface = null + router = null + shared_secret = module.apigee_vpn.random_secret + vpn_gateway_interface = 1 + } + } +} + diff --git a/tests/blueprints/cloud_operations/apigee/__init__.py b/tests/blueprints/apigee/bigquery-analytics/__init__.py similarity index 100% rename from tests/blueprints/cloud_operations/apigee/__init__.py rename to tests/blueprints/apigee/bigquery-analytics/__init__.py diff --git a/tests/blueprints/cloud_operations/apigee/basic.tfvars b/tests/blueprints/apigee/bigquery-analytics/basic.tfvars similarity index 100% rename from tests/blueprints/cloud_operations/apigee/basic.tfvars rename to tests/blueprints/apigee/bigquery-analytics/basic.tfvars diff --git a/tests/blueprints/cloud_operations/apigee/basic.yaml b/tests/blueprints/apigee/bigquery-analytics/basic.yaml similarity index 100% rename from tests/blueprints/cloud_operations/apigee/basic.yaml rename to tests/blueprints/apigee/bigquery-analytics/basic.yaml diff --git a/tests/blueprints/cloud_operations/apigee/tftest.yaml b/tests/blueprints/apigee/bigquery-analytics/tftest.yaml similarity index 92% rename from tests/blueprints/cloud_operations/apigee/tftest.yaml rename to tests/blueprints/apigee/bigquery-analytics/tftest.yaml index 49190499d..a3441f559 100644 --- a/tests/blueprints/cloud_operations/apigee/tftest.yaml +++ b/tests/blueprints/apigee/bigquery-analytics/tftest.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -module: blueprints/cloud-operations/apigee +module: blueprints/apigee/bigquery-analytics tests: basic: diff --git a/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/__init__.py b/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/__init__.py new file mode 100644 index 000000000..6d6d1266c --- /dev/null +++ b/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022 Google LLC +# +# 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. diff --git a/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/basic.tfvars b/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/basic.tfvars new file mode 100644 index 000000000..ae07c514f --- /dev/null +++ b/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/basic.tfvars @@ -0,0 +1,5 @@ +billing_account_id = "12345-12345-12345" +parent = "folders/123456789" +apigee_project_id = "my-apigee-project" +onprem_project_id = "my-onprem-project" +hostname = "test.myorg.org" diff --git a/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/basic.yaml b/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/basic.yaml new file mode 100644 index 000000000..ef1fa1e00 --- /dev/null +++ b/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/basic.yaml @@ -0,0 +1,17 @@ +# Copyright 2022 Google LLC +# +# 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. + +counts: + modules: 13 + resources: 72 diff --git a/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/tftest.yaml b/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/tftest.yaml new file mode 100644 index 000000000..5c92fb82a --- /dev/null +++ b/tests/blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg/tftest.yaml @@ -0,0 +1,18 @@ +# Copyright 2022 Google LLC +# +# 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. + +module: blueprints/apigee/network-patterns/nb-glb-psc-neg-sb-psc-ilbl7-hybrid-neg + +tests: + basic: