Repository: pivotal-cf/pcfdev Branch: master Commit: c5fe36ce3be6 Files: 70 Total size: 430.7 KB Directory structure: gitextract_imyhzfky/ ├── .envrc ├── .gitignore ├── .gitmodules ├── CONTRIBUTING.md ├── DEVELOP.md ├── FAQ.md ├── Gemfile ├── LICENSE ├── README.md ├── assets/ │ ├── keys/ │ │ └── key.pem │ └── scripts/ │ ├── common │ ├── health-check │ ├── reset │ ├── run │ ├── start │ └── stop ├── manifest.yml ├── pcfdev-base.json ├── pcfdev.json ├── preseed/ │ └── preseed.cfg ├── src/ │ ├── api/ │ │ ├── main.go │ │ ├── main_suite_test.go │ │ ├── main_test.go │ │ └── usecases/ │ │ ├── uaa_credential_replacement.go │ │ ├── uaa_credential_replacement_test.go │ │ └── usecase_suite_test.go │ └── provisioner/ │ ├── .envrc │ ├── Dockerfile │ ├── assets/ │ │ ├── stub_server.go │ │ ├── tomcat-web-hsts-disabled.xml │ │ ├── tomcat-web-invalid.xml │ │ └── tomcat-web.xml │ ├── bin/ │ │ ├── generate-mocks │ │ └── tests │ ├── cert/ │ │ ├── cert.go │ │ ├── cert_suite_test.go │ │ └── cert_test.go │ ├── fs/ │ │ ├── fs.go │ │ ├── fs_suite_test.go │ │ └── fs_test.go │ ├── main.go │ ├── main_suite_test.go │ ├── main_test.go │ └── provisioner/ │ ├── commands/ │ │ ├── close_all_ports.go │ │ ├── commands_suite_test.go │ │ ├── configure_dnsmasq.go │ │ ├── configure_dnsmasq_test.go │ │ ├── configure_garden_dns.go │ │ ├── configure_garden_dns_test.go │ │ ├── disable_uaa_hsts.go │ │ ├── disable_uaa_hsts_test.go │ │ ├── open_port.go │ │ ├── replace_domain.go │ │ ├── replace_domain_test.go │ │ ├── setup_api.go │ │ ├── setup_api_test.go │ │ ├── setup_cfdot.go │ │ └── setup_cfdot_test.go │ ├── concrete_cmd_runner.go │ ├── concrete_cmd_runner_test.go │ ├── errors.go │ ├── mocks/ │ │ ├── cert.go │ │ ├── cmd_runner.go │ │ ├── command.go │ │ ├── fs.go │ │ └── ui.go │ ├── provisioner.go │ ├── provisioner_suite_test.go │ └── provisioner_test.go └── versions.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .envrc ================================================ export GOPATH=$PWD export PATH=$GOPATH/bin:$PATH ================================================ FILE: .gitignore ================================================ .DS_Store *.box /bosh/bin /bosh/pkg /output /pkg /releases /src/provisioner/provision /src/api/api /pcfdev-base /bin !/bin/build !/bin/compile-release !/bin/fetch-assets !/bin/setup-packer NERD_tree_* /*.iml ================================================ FILE: .gitmodules ================================================ [submodule "src/github.com/onsi/ginkgo"] path = src/github.com/onsi/ginkgo url = https://github.com/onsi/ginkgo [submodule "src/github.com/onsi/gomega"] path = src/github.com/onsi/gomega url = https://github.com/onsi/gomega [submodule "src/gopkg.in/yaml.v2"] path = src/gopkg.in/yaml.v2 url = https://gopkg.in/yaml.v2 [submodule "src/github.com/cppforlife/bosh-provisioner"] path = src/github.com/cppforlife/bosh-provisioner url = https://github.com/pcfdev-forks/bosh-provisioner [submodule "src/github.com/cppforlife/packer-bosh"] path = src/github.com/cppforlife/packer-bosh url = https://github.com/cppforlife/packer-bosh [submodule "src/provisioner/vendor/github.com/golang/mock"] path = src/provisioner/vendor/github.com/golang/mock url = https://github.com/pcfdev-forks/mock [submodule "src/provisioner/vendor/golang.org/x/net"] path = src/provisioner/vendor/golang.org/x/net url = https://github.com/golang/net [submodule "src/provisioner/vendor/golang.org/x/text"] path = src/provisioner/vendor/golang.org/x/text url = https://github.com/golang/text [submodule "src/api/vendor/gopkg.in/yaml.v2"] path = src/api/vendor/gopkg.in/yaml.v2 url = https://github.com/go-yaml/yaml ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing Everyone is encouraged to help improve this project. Please submit pull requests against the **master branch**. Limited access to our [Concourse](http://concourse.ci) CI system is available at [ci.pcfdev.io](https://ci.pcfdev.io). Here are some ways *you* can contribute: * by using nightly builds and prerelease versions * by reporting bugs * by suggesting new features * by writing or editing documentation * by writing specifications * by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace) * by refactoring code * by closing [issues](https://github.com/pivotal-cf/pcfdev/issues) * by reviewing patches ## Submitting an Issue We use the [GitHub issue tracker](https://github.com/pivotal-cf/pcfdev/issues) to track bugs and features. Before submitting a bug report or feature request, check to make sure it hasn't already been submitted. You can indicate support for an existing issue by voting it up. When submitting a bug report, please include a [Gist](http://gist.github.com/) that includes a stack trace and any details that may be necessary to reproduce the bug including the PCF Dev version. ## Submitting a Pull Request 1. Propose a change by opening an issue. 2. Fork the project. 3. Create a topic branch. 4. Implement your feature or bug fix. 5. Commit and push your changes. 6. Submit a pull request. ## Copyright See [LICENSE](LICENSE) for details. Copyright (c) 2015 [Pivotal Software, Inc](http://www.pivotal.io/). ================================================ FILE: DEVELOP.md ================================================ # PCF Dev Development To develop PCF Dev you will need to have the following tools installed: - [Packer](https://www.packer.io) v0.9.0+ - [Virtualbox](https://www.virtualbox.org/) 5.0+ - [Go](https://golang.org) 1.6.1+ - [jq](https://stedolan.github.io/jq/) 1.5+ - [spiff](https://github.com/cloudfoundry-incubator/spiff) 1.0.6+ ## Clone the PCF Dev source ```bash git clone --recursive https://github.com/pivotal-cf/pcfdev.git ``` ### Building a PCF Dev Box To build an OSS-only PCF Dev OVA, run: ```bash ./bin/build -only=virtualbox-iso # pass -debug for more output ``` > Note: Support for VMware Fusion/Workstation has been discontinued. Support for AWS is temporarily suspended until a commercial version of PCF Dev becomes available from the AWS Marketplace. ### Deploying a locally-built PCF Dev box After the PCF Dev box has been built, you need to use the PCF Dev CLI to launch the OVA. This will disable various checks for system requirements such as system memory. More information on installation of the CLI can be found [here](http://docs.pivotal.io/pcf-dev/index.html#installing). ```bash cf dev start -o output/output-virtualbox-iso/oss-v0.ova ``` ### Customizing PCF Dev Our build tool has the ability to build compiled releases or releases from source. By default, it will try to build releases that have been compiled by the PCF Dev team. If you have a *non-compiled* release that present on your workstation, you can configure the build to use it using the **path:** key. Simply edit the versions.json file at the root of this repo like `"cf" :` is done below: ```json { "releases": { "cf" : { "path": "/Users/pivotal/[path-to-release-folder]" }, "diego" : { "version": "v0.1480.0", "sha1": "bfd87d6ef08458e19e2abc6fc6888ba9ac29fde6", "source_location": "https://github.com/cloudfoundry/diego-release", "compiled_release_url" : "https://s3.amazonaws.com/pcfdev/compiled-releases/diego-8d1450da393eae98d565b9e0e7154c742e75e513.tgz" }, ``` If you would like to a different *compiled* release than is offered in the versions.json, simply make sure that the appropriate keys are modified. > Note: any necessary manifest changes can be done to the manifest.yml file at the root of this repo for a successful build. ## Contributing If you are interested in contributing to PCF Dev, please refer to [CONTRIBUTING](CONTRIBUTING.md). ## Copyright See [LICENSE](LICENSE) for details. Copyright (c) 2015 [Pivotal Software, Inc](http://www.pivotal.io/). ================================================ FILE: FAQ.md ================================================ # Frequently Asked Questions ## General Questions ### What is PCF Dev? PCF Dev is a new distribution of Cloud Foundry designed to run on a developer’s laptop or workstation. PCF Dev gives application developers the full Cloud Foundry experience in a lightweight, easy to install package. ### Who should use PCF Dev? PCF Dev is intended for application developers who wish to develop and debug their application locally on a full-featured Cloud Foundry. PCF Dev is also an excellent getting started environment for developers interested in learning and exploring Cloud Foundry. ### If my application runs on PCF Dev, will it run on PCF? Yes. PCF Dev is designed to mirror PCF exactly. If your application runs on PCF Dev, it will run on PCF with no modification in almost all cases. ## Troubleshooting ### Why does `cf api` and/or `cf login` fail with an "Invalid SSL Cert" error? PCF Dev comes with a self-signed SSL certificate for its API and requires the `--skip-ssl-validation` option. This also applies to the Spring Boot Dashboard, which requires the checkbox "Self-signed" in order to connect. ``` ○ → cf api api.local.cfdev.sh Setting api endpoint to api.local.cfdev.sh... FAILED Invalid SSL Cert for api.local.cfdev.sh TIP: Use 'cf api --skip-ssl-validation' to continue with an insecure API endpoint ``` ## Networking ### Container-to-router This is traffic from the app container to the gorouter. It is enabled by default. This allows apps to communicate with each other by using the routes published by gorouter. ### Container-to-guest This is traffic from the app container to the virtual machine in which PCF Dev is running. It is enabled by default. This may be useful if you want to run other services inside of the guest virtual machine for your applications to use, but doing so is not encouraged. Instead, extra services should be run on the host (see below). The IP address of the guest is `192.168.11.11` or `local.cfdev.sh` (unless this address is already in use). ### Container-to-host This is traffic from the app container to the host on which the virtual machine is running. It is enabled by default. This can be used to run services on your host that are available to your apps in PCF Dev. The IP address of the host accessible to the app is `192.168.11.1` or `host.cfdev.sh` (unless this address is already in use). For example, in order to connect your app to a MongoDB instance running on the host on port `27017`, run the following commands: ```bash cf create-user-provided-service my-mongo-db -p '{ "uri": "mongodb://:@host.cfdev.sh:27017/" }' cf bind-service my-mongo-db cf restage ``` ### Container-to-external This is traffic from the app container to a destination external to the host. It allows your application to reach the internet. Traffic to public and private IP addresses is enabled by default in PCF Dev. You may remove the `all_pcfdev` security group to restrict access to only public IP addresses, as a default PCF installation would be configured. ### Container-to-container This is traffic directly between two containers in the same PCF Dev deployment. It is useful for running applications that must communicate with each other but do not need or want a publicly-accessible route. It is not enabled and will not be available until it is supported in Pivotal Cloud Foundry. # Copyright See [LICENSE](LICENSE) for details. Copyright (c) 2015 [Pivotal Software, Inc](http://www.pivotal.io/). ================================================ FILE: Gemfile ================================================ source 'https://rubygems.org' gem 'bosh_cli', '>=1.3094.0' ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2016 Pivotal Software Inc. 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. ================================================ FILE: README.md ================================================ # Update on PCF Dev This is the deprecated version of PCF Dev - please visit the current Github repository https://github.com/cloudfoundry-incubator/cfdev for the latest updates ************************************************************* # PCF Dev PCF Dev is a new distribution of Cloud Foundry designed to run on a developer’s laptop or workstation. PCF Dev gives application developers the full Cloud Foundry experience in a lightweight, easy to install package. PCF Dev is intended for application developers who wish to develop and debug their application locally on a full-featured Cloud Foundry. PCF Dev is also an excellent getting started environment for developers interested in learning and exploring Cloud Foundry. > More information about the project can be found on the [FAQ](FAQ.md#general-questions). ## Open Source This repository contains source code that allows developers to build an open source version of PCF Dev that only contains the Elastic Runtime and the CF MySQL Broker. The binary distribution of PCF Dev that is available on the [Pivotal Network](https://network.pivotal.io/) contains other PCF components (such as the Redis, RabbitMQ and Spring Cloud Services marketplace services as well as Apps Manager) that are not available in this repository. However, we encourage you to leave any feedback or issues you may encounter regarding the full, binary distribution of PCF Dev in [this repository's Github issues](https://github.com/pivotal-cf/pcfdev/issues). ## Install 1. Download the latest `pcfdev-VERSION-PLATFORM.zip` from the [Pivotal Network](https://network.pivotal.io/). 1. Unzip the zip file and navigate to its containing folder using PowerShell or a Unix terminal. 1. Run the extracted binary. 1. Run `cf dev start`. > Check out the [documentation](https://docs.pivotal.io/pcf-dev/) for more information. Running `cf dev help` will display an overview of PCF Dev VM management commands. ### Prerequisites * [CF CLI](https://github.com/cloudfoundry/cli) * [VirtualBox](https://www.virtualbox.org/): 5.0+ * Internet connection (or [Dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html) or [Acrylic](http://mayakron.altervista.org/wikibase/show.php?id=AcrylicHome)) required for wildcard DNS resolution ### Using the Cloud Foundry CLI Plugin Follow the instructions provided at the end of `cf dev start` to connect to PCF Dev: ``` Downloading VM... Progress: |====================>| 100% VM downloaded Importing VM... Starting VM... Provisioning VM... Waiting for services to start... 40 out of 40 running _______ _______ _______ ______ _______ __ __ | || || | | | | || | | | | _ || || ___| | _ || ___|| |_| | | |_| || || |___ | | | || |___ | | | ___|| _|| ___| | |_| || ___|| | | | | |_ | | | || |___ | | |___| |_______||___| |______| |_______| |___| is now running. To begin using PCF Dev, please run: cf login -a https://api.local.pcfdev.io --skip-ssl-validation Admin user => Email: admin / Password: admin Regular user => Email: user / Password: pass ``` > The `local.pcfdev.io` domain may differ slightly for your PCF Dev instance. To stage a simple app on PCF Dev, `cd` into the app directory and run `cf push `. See cf documentation for information on [deploying apps](http://docs.cloudfoundry.org/devguide/deploy-apps/) and [attaching services](http://docs.cloudfoundry.org/devguide/services/). ### Using a customized PCF Dev OVA Specify the path to the custom built OVA with the `-o flag` to the `cf dev start` command. ``` $ cf dev start -o /path/to/custom/ova Importing VM... Starting VM... Provisioning VM.. ... ``` To build a custom PCF Dev OVA, please see our [DEVELOP](./DEVELOP.md) Documentation. ## Uninstall To temporarily stop PCF Dev run `cf dev stop`. To destroy your PCF Dev VM run `cf dev destroy`. To uninstall the PCF Dev cf CLI plugin run `cf uninstall-plugin pcfdev` ## Contributing If you are interested in contributing to PCF Dev, please refer to the [contributing guidelines](CONTRIBUTING.md) and [development instructions](DEVELOP.md). # Copyright See [LICENSE](LICENSE) for details. Copyright (c) 2016 [Pivotal Software, Inc](http://www.pivotal.io/). PCF Dev uses a version of Monit that can be found [here](https://github.com/pivotal-cf/pcfdev-monit), under the GPLv3 license. ================================================ FILE: assets/keys/key.pem ================================================ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+eYPNeh/gldZCxXCXBmlAUWgJdRTTNClCAx8yV26/hdLjbZGg1StjwOVkUupxpG+5ghm7mxnz6xQUJH+AdzZVXrHaixMl4jwf8RrsTu7OJj/zDjoKNUX9vH6SZzTifUfCigixHJQwOoA+hCJCIbrzh0z2Vvvtn+G/adEFhNwdSl+RaGfuNSh04bTOS7CrPrmPGE2sE192+PMoh+sE5E6RKivWcR0tLR58OA/MN1SEH3LNrKrmxYi4qebp1HxXJTac4nuegqoDdSEUnjdCjZPRdeZiKy/L3B3BAT0+P646IJzwQHv3kUHwVnfBwI3COcEZPwctUOBl/JjyagjJyx5P pcfdev insecure key ================================================ FILE: assets/scripts/common ================================================ monit="/var/vcap/bosh/bin/monit" monit_summary() { while output=$($monit summary 2>&1) && [[ $output = *"error connecting to the monit daemon"* ]]; do sleep 1; done; echo "$output"; } total_services() { monit_summary | grep -E '^(Process|File|System)' | wc -l; } started_service_count() { started_services | wc -l; } started_services() { monit_summary | grep -E '(running|accessible|Timestamp changed|PID changed)' | awk '{print $2}' | tr -d "'"; } stopped_service_count() { stopped_services | wc -l; } stopped_services() { monit_summary | grep 'not monitored' | grep -v 'pending' | awk '{print $2}' | tr -d "'"; } cc_status_code() { curl -s -I -o /dev/null -w %{http_code} -H "Host: api.$1" http://localhost/v2/info; } available_buildpacks() { cf curl /v2/buildpacks | jq '.resources | map(select(.entity.filename | length > 0)) | length'; } wait_for_monit_to_start() { while [[ $(total_services) = 0 ]]; do sleep 1; done; } wait_for_monit_to_stop() { while [[ $(total_services) != 0 ]]; do sleep 1; done; } wait_for_services_to_stop() { while [[ $(stopped_service_count) -lt $(total_services) ]]; do sleep 1; done; } start_services() { for service in $@; do $monit start $service done for service in $@; do while ! monit_summary | grep $service | grep -q running; do sleep 1; done; done } start_remaining() { for service in $(stopped_services); do $monit start $service done } move_monit_control_files() { find /var/vcap/monit/job -name '*.monitrc' | grep -v pcfdev | xargs rm -f for file in $(ls /var/vcap/jobs/*/monit) do local dirname=$(dirname $file) local jobname=$(basename $dirname) local destination_path="/var/vcap/monit/job/$(next_monit_index)-${jobname}.monitrc" cp $file $destination_path sed -i '/group vcap/a\ \ mode manual' $destination_path done } exists_in_monit() { grep $1 /var/vcap/monit/job/* -q } find_monit_file() { grep $1 /var/vcap/jobs/*/monit -l } next_monit_index(){ printf %04d $(ls /var/vcap/monit/job/ | wc -l) } restart_service() { local service=$1 $monit restart $service while ! monit_summary | grep $service | grep -v pending | grep -q running; do sleep 1; done; } update_service_broker() { local broker_name=$1 local broker_url=$2 echo "Service broker already exists - updating broker" cf update-service-broker ${broker_name} admin admin ${broker_url} } create_service_broker() { local broker_name=$1 local broker_url=$2 echo "Service broker does not exist - creating broker" cf create-service-broker ${broker_name} admin admin ${broker_url} } setup_service_broker() { local broker_name=$1 local broker_url=$2 while [[ $(curl -s -o /dev/null -u admin:admin -w %{http_code} ${broker_url}/v2/catalog) != 200 ]]; do sleep 1 done create_service_broker $broker_name $broker_url || update_service_broker $broker_name $broker_url cf enable-service-access ${broker_name} } ================================================ FILE: assets/scripts/health-check ================================================ #!/bin/bash set -e source /var/pcfdev/common domain=$(cat /var/pcfdev/domain) status_code=$(cc_status_code ${domain}) service_count=$(total_services) if [[ ${status_code} == "200" && -f "/run/pcfdev-healthcheck" ]] then echo -n 'ok' exit 0 fi exit 1 ================================================ FILE: assets/scripts/reset ================================================ #!/bin/bash set -e exec 3>&1 4>&2 >>/var/pcfdev/reset.log 2>&1 set -x source /var/pcfdev/common if status runsvdir | grep -q 'start/running'; then wait_for_monit_to_start $monit stop all >&3 echo "Waiting for services to stop..." wait_for_services_to_stop stop runsvdir wait_for_monit_to_stop fi >&3 echo "Services stopped. Resetting data..." rm -rf /var/vcap/nfs /var/vcap/data/{compile,tmp} >&3 echo "Deleting stale state files not needed for mysql migrations" find /var/vcap/store/* -maxdepth 0 ! -name "*.sql" | xargs rm -rf set +x exec 1>&3 2>&4 ================================================ FILE: assets/scripts/run ================================================ #!/bin/bash set -e if [[ -z $1 ]] || [[ -z $2 ]]; then >&2 echo "Usage:" >&2 echo -e "\t$0 " exit 1 fi exec 3>&1 4>&2 >>/var/pcfdev/provision.log 2>&1 set -x rm -f /run/pcfdev-healthcheck source /var/pcfdev/common domain=$1 public_ip=$2 services=$3 registries=$4 if [[ -x /var/pcfdev/pre-run ]]; then /var/pcfdev/pre-run "$domain" "$services" fi >&3 /var/pcfdev/stop rm -f /var/vcap/bosh/agent_state.json # Add self-signed cert to existing trusted certs if [[ ! -f /var/pcfdev/trusted_ca.crt ]]; then cp /var/vcap/jobs/cflinuxfs2-rootfs-setup/config/certs/trusted_ca.crt /var/pcfdev/trusted_ca.crt fi cat /var/pcfdev/trusted_ca.crt /var/vcap/jobs/gorouter/config/cert.pem > /var/vcap/jobs/cflinuxfs2-rootfs-setup/config/certs/trusted_ca.crt /var/vcap/jobs/cflinuxfs2-rootfs-setup/bin/pre-start # Replace the old system domain / IP with the new system domain / IP config_files=$(find /var/vcap/jobs/*/ /var/vcap/monit/job -type f) old_domain=$(cat /var/pcfdev/domain) perl -p -i -e "s/\\Q$old_domain\\E/$domain/g" $config_files echo "$domain" > /var/pcfdev/domain sed -i '/\/proc\/sys\/net\/ipv4\/ip_local_port_range/d' /var/vcap/jobs/gorouter/bin/gorouter_ctl # Point garden at HTTP_PROXY and HTTPS_PROXY pcfdev_http_proxy=$(. /etc/environment && echo "$HTTP_PROXY") pcfdev_https_proxy=$(. /etc/environment && echo "$HTTPS_PROXY") if [[ ! -z $pcfdev_http_proxy || ! -z $pcfdev_https_proxy ]]; then perl -p -i -e "s/^export.*(http|https|no)_proxy=.*\n//i" /var/vcap/jobs/garden/bin/garden_ctl result=$(grep -i '\(http\|https\|no\)_proxy=' /etc/environment | xargs -I {} echo 'export {}\n' | tr -d '\n') if [[ -n "$result" ]]; then sed -i "/set -x/a$result" /var/vcap/jobs/garden/bin/garden_ctl fi fi # Fix CC temporary directory mkdir -p /tmp/cc_tmp chgrp vcap /tmp/cc_tmp chmod 1777 /tmp/cc_tmp cc_worker_ctl=/var/vcap/jobs/cloud_controller_ng/bin/cloud_controller_worker_ctl grep -q 'export TMPDIR=\/tmp\/cc_tmp' "$cc_worker_ctl" || sed -i '2iexport TMPDIR=/tmp/cc_tmp' "$cc_worker_ctl" # Add registries to insecure_docker_registries if [[ -n "$registries" ]]; then perl -p -i -e "s/.*-insecureDockerRegistry=.*\n//i" /var/vcap/jobs/garden/bin/garden_ctl insecureDockerRegistryOptions="" for registry in $(echo "$registries" | tr ',' '\n'); do insecureDockerRegistryOptions="${insecureDockerRegistryOptions}--insecure-docker-registry=$registry " done if [[ -n "$insecureDockerRegistryOptions" ]]; then sed -i "\|/var/vcap/packages/guardian/bin/guardian|a$insecureDockerRegistryOptions \\\\" /var/vcap/jobs/garden/bin/garden_ctl fi stager_config=$(jq \ --arg registries "$registries" \ '.insecure_docker_registries=($registries | split(","))' \ /var/vcap/jobs/stager/config/stager_config.json ) echo "$stager_config" > /var/vcap/jobs/stager/config/stager_config.json fi >&3 2>&4 /var/pcfdev/start "$domain" cf api "https://api.$domain" --skip-ssl-validation cf auth admin admin cf create-org pcfdev-org cf create-space pcfdev-space -o pcfdev-org cf target -o pcfdev-org -s pcfdev-space cf create-user user pass cf set-org-role user pcfdev-org OrgManager cf set-space-role user pcfdev-org pcfdev-space SpaceManager cf set-space-role user pcfdev-org pcfdev-space SpaceDeveloper cf set-space-role user pcfdev-org pcfdev-space SpaceAuditor [[ $domain != $old_domain ]] && cf delete-shared-domain "$old_domain" -f if [[ $(cf curl /v2/shared_domains | jq -r ".resources[] | select(.entity.name == \"tcp.$domain\").entity.name") == "" ]] then cf create-shared-domain tcp.$domain --router-group default-tcp quota_definition_url=$(cf curl /v2/quota_definitions?q=name:default | jq -r .resources[0].metadata.url) cf curl $quota_definition_url -X PUT -d '{"total_routes": 100}' cf curl $quota_definition_url -X PUT -d '{"total_reserved_route_ports": -1}' fi cf enable-feature-flag diego_docker if [[ ! -z $pcfdev_http_proxy ]] || [[ ! -z $pcfdev_https_proxy ]]; then proxy_environment_variables=$( echo -n "{" grep -i '\(http\|https\|no\)_proxy=' /etc/environment | sed -e 's/\(.*\)=\(.*\)/"\1": "\2"/' | paste -sd "," - echo -n "}" ) cf set-staging-environment-variable-group "$proxy_environment_variables" cf set-running-environment-variable-group "$proxy_environment_variables" fi while [[ $(available_buildpacks) -lt 8 ]]; do sleep 1 done setup_service_broker p-mysql http://mysql-broker.$domain setup_service_broker local-volume http://localbroker.$domain if [[ -x /var/pcfdev/post-run ]]; then /var/pcfdev/post-run "$domain" "$services" fi set +x exec 1>&3 2>&4 ================================================ FILE: assets/scripts/start ================================================ #!/bin/bash set -e if [[ -z $1 ]]; then >&2 echo "Usage:" >&2 echo -e "\t$0 " exit 1 fi exec 3>&1 4>&2 >>/var/pcfdev/provision.log 2>&1 set -x source /var/pcfdev/common domain=$1 >&3 echo "Waiting for services to start..." move_monit_control_files start runsvdir wait_for_monit_to_start /var/vcap/jobs/mysql/bin/pre-start start_services mariadb_ctrl galera-healthcheck while ! nc -z 127.0.0.1 3306; do sleep 1 done /var/vcap/jobs/consul_agent/bin/pre-start start_services consul_agent for script in $(ls /var/vcap/jobs/*/bin/pre-start | grep -v '/mysql/' | grep -v '/consul_agent/'); do $script done start_services garden etcd uaa while [[ ! /var/vcap/jobs/uaa/bin/dns_health_check ]]; do sleep 1 done start_services bbs start_remaining total=$(total_services) while started=$(started_service_count) && [[ $started -lt $total ]]; do counter=$(($counter + 1)) [[ $(($counter % 60)) = 0 ]] && >&3 echo "$started out of $total running" sleep 1 done >&3 echo "$total out of $total running" while [[ $(cc_status_code "$domain") != 200 ]]; do sleep 1 done for script in /var/vcap/jobs/*/bin/post-start do $script done exec 1>&3 2>&4 ================================================ FILE: assets/scripts/stop ================================================ #!/bin/bash set -e exec 3>&1 4>&2 >>/var/pcfdev/provision.log 2>&1 set -x source /var/pcfdev/common if status runsvdir | grep -q 'start/running'; then >&3 echo "Waiting for services to stop..." wait_for_monit_to_start $monit stop all wait_for_services_to_stop stop runsvdir wait_for_monit_to_stop fi ================================================ FILE: manifest.yml ================================================ --- name: pcfdev releases: - name: capi version: 0 url: file:///opt/bosh-provisioner/assets/releases/capi-0.tgz - name: loggregator version: 0 url: file:///opt/bosh-provisioner/assets/releases/loggregator-0.tgz - name: nats version: 0 url: file:///opt/bosh-provisioner/assets/releases/nats-0.tgz - name: uaa version: 0 url: file:///opt/bosh-provisioner/assets/releases/uaa-0.tgz - name: consul version: 0 url: file:///opt/bosh-provisioner/assets/releases/consul-0.tgz - name: nodejs-buildpack version: 0 url: file:///opt/bosh-provisioner/assets/releases/nodejs-buildpack-0.tgz - name: java-offline-buildpack version: 0 url: file:///opt/bosh-provisioner/assets/releases/java-offline-buildpack-0.tgz - name: php-buildpack version: 0 url: file:///opt/bosh-provisioner/assets/releases/php-buildpack-0.tgz - name: ruby-buildpack version: 0 url: file:///opt/bosh-provisioner/assets/releases/ruby-buildpack-0.tgz - name: binary-buildpack version: 0 url: file:///opt/bosh-provisioner/assets/releases/binary-buildpack-0.tgz - name: go-buildpack version: 0 url: file:///opt/bosh-provisioner/assets/releases/go-buildpack-0.tgz - name: python-buildpack version: 0 url: file:///opt/bosh-provisioner/assets/releases/python-buildpack-0.tgz - name: staticfile-buildpack version: 0 url: file:///opt/bosh-provisioner/assets/releases/staticfile-buildpack-0.tgz - name: cf version: 0 url: file:///opt/bosh-provisioner/assets/releases/cf-0.tgz - name: etcd version: 0 url: file:///opt/bosh-provisioner/assets/releases/etcd-0.tgz - name: cf-networking version: 0 url: file:///opt/bosh-provisioner/assets/releases/cf-networking-0.tgz - name: garden-runc version: 0 url: file:///opt/bosh-provisioner/assets/releases/garden-runc-0.tgz - name: diego version: 0 url: file:///opt/bosh-provisioner/assets/releases/diego-0.tgz - name: cf-mysql version: 0 url: file:///opt/bosh-provisioner/assets/releases/cf-mysql-0.tgz - name: cflinuxfs2 version: 0 url: file:///opt/bosh-provisioner/assets/releases/cflinuxfs2-rootfs-0.tgz - name: routing version: 0 url: file:///opt/bosh-provisioner/assets/releases/routing-0.tgz - name: local-volume version: 0 url: file:///opt/bosh-provisioner/assets/releases/local-volume-0.tgz networks: - name: default type: local update: update_watch_time: 60000 - 1200000 compilation: network: default jobs: - name: pcfdev instances: 1 persistent_disk: 1024 networks: - name: default templates: - name: mysql release: cf-mysql - name: cf-mysql-broker release: cf-mysql - name: garden release: garden-runc - name: etcd release: etcd - name: gorouter release: routing - name: route_registrar release: routing - name: routing-api release: routing - name: tcp_emitter release: routing - name: tcp_router release: routing - name: auctioneer release: diego - name: file_server release: diego - name: rep release: diego - name: route_emitter release: diego - name: ssh_proxy release: diego - name: bbs release: diego - name: cfdot release: diego - name: cflinuxfs2-rootfs-setup release: cflinuxfs2 - name: stager release: capi - name: nsync release: capi - name: tps release: capi - name: cc_uploader release: capi - name: cloud_controller_clock release: capi - name: cloud_controller_ng release: capi - name: cloud_controller_worker release: capi - name: blobstore release: capi - name: nats release: nats - name: uaa release: uaa - name: consul_agent release: consul - name: nodejs-buildpack release: nodejs-buildpack - name: java-offline-buildpack release: java-offline-buildpack - name: php-buildpack release: php-buildpack - name: binary-buildpack release: binary-buildpack - name: go-buildpack release: go-buildpack - name: python-buildpack release: python-buildpack - name: ruby-buildpack release: ruby-buildpack - name: staticfile-buildpack release: staticfile-buildpack - name: syslog_drain_binder release: loggregator - name: metron_agent release: loggregator - name: doppler release: loggregator - name: loggregator_trafficcontroller release: loggregator - name: localdriver release: local-volume - name: localbroker release: local-volume - name: netmon release: cf-networking - name: vxlan-policy-agent release: cf-networking - name: policy-server release: cf-networking - name: garden-cni release: cf-networking - name: silk-cni release: cf-networking - name: silk-daemon release: cf-networking - name: silk-controller release: cf-networking properties: <<: (( merge )) support_address: pcfdev@pivotal.io domain: local.pcfdev.io system_domain: local.pcfdev.io app_domains: [local.pcfdev.io] system_domain_organization: pcfdev-org name: pcfdev ssl: skip_cert_verify: true skip_ssl_validation: true capi: cc_uploader: listen_addr: 127.0.0.1:9090 debug_addr: 127.0.0.1:17018 cc: job_polling_interval_in_seconds: 5 ca_cert: | -----BEGIN CERTIFICATE----- MIIE/DCCAuSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDExN0ZXN0 LWNjLXVwbG9hZGVyLWNhMB4XDTE3MDMzMDIzNTAxOFoXDTI3MDMzMDIzNTAyNlow HjEcMBoGA1UEAxMTdGVzdC1jYy11cGxvYWRlci1jYTCCAiIwDQYJKoZIhvcNAQEB BQADggIPADCCAgoCggIBAN3Pa74Y46cXWmhQtXpp0sIpHtd80QI/zuTkU0TB8Jzg O+ehnRMpeetCr+0YsKeIM0l1WQHt0zBmUi1emc4OcABnXE/Qp3SQuO3u3emi+g+k svG3Kb5gSOswHPlR3EjvCeB38SS3A0bxnvJMbKPlXvhhtkzWRoZDSlxjHWzeSJ8u XPjuMSPP+Tr+97rtelbufyEta61sr1ahwoBJHFnre2s7KdiG34AOBzbBb8GoAtQ7 IpHHyQQzVTT/YNjdgmHz57uIptbWwBXch0hxBiMleb87Zxpx6EEt4GzSyOt8Qkcp Ja0z68SEaL0P92G92Os1jvfiBFVos+q0IPnvIhCvAgh2LojjBHRVSSGlBHSLEd/D dzaXuYBJrpxoHl0eRZGGa39BJY/gsvOgJ27xFB8kN3PCYSRekF4tuxkWFOmPGLKc TC6jYHG1SIReZgouX16i4lwlejNf+f1La0ZCEr13neaaSZmpd87DNMaQkw+vovUO oUeLCFPknOOFFQiKrI1SmLPjo+0hJPZa0CKz7Jp7ynLBSA5JZDYzf6asxTYvaD2E fjQV+Ucz/blDCbsZrH4HxN42jACYg0sWUQOdyLaTrOpo67k8iPxeizg1pRrIP4U1 emnMjAbW2hZOZdIR2Rel1XfwW99rBD7ejun53l+gNUIkyi7XMz4OE3/fHO1+X4gx AgMBAAGjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0G A1UdDgQWBBRXlmY9gLcIn9KN+RojBbl5j5KVVzANBgkqhkiG9w0BAQsFAAOCAgEA JwOX8/GXfnNt/9YjSlORbwKWYKrigNatGzvOqrbROnueyQkWCOsKXrqX+ol4DOpO 2I+JYdparoqvyAhNKaNsKfW8E4VOta4bIvh0oFQPJXrQAhdHocyTCIX18qbp6zIN AEJLdDvjeBCEo2t/Ip1Ly5bhFCfGeP7LU36tD3T15/8eEARwQ7v3tczBKM3NQ5ON lnHOheXKdAQcJou8kJ1x+n/Cy2MR/86qJV6R2OixXvWiHK3c8P9goREPPELPc5p9 ylYsCMgRBiBA1YKRVExH8YCNMF+Rz4U6zWaJ9HfVEHNI3fm2w5FwzwErmdVutszp dpTUr2jjihxFnduP9vA7Y79EEgFZ7NT/KLlUBXyfiYSu4nwRzV8h+RKZYD+XIFeB FgQPSMbrNG2hOviTPq1ACkoH2vEV4WGYrjvGT/kTl1W5pzVbjE+Ja5aLRm1X7QbU f+X38/n4N5yEMd/q7WvCzlq0BMhy28iMjzSdPKw4c/R5LwltCq6VNzjjwm4WdC3l l9CE4RhwFrZQl1YViX0rB8GKOMihyhGLS5jctIYLUS+vDjZzh/m4SS9QArnSph+I tNahrxZZaiLE0RFViIV6Oi3ek1qmxTjYunNU/fVxuLvlHYNzHqvPLTDu6IS3zu4o IuYvX8gxa8VkMJUQvtlOTG4HSj4LmU75f/SOsogld4o= -----END CERTIFICATE----- client_cert: | -----BEGIN CERTIFICATE----- MIIELzCCAhegAwIBAgIRANl6/eH1wRl29GgiXTULy/YwDQYJKoZIhvcNAQELBQAw HjEcMBoGA1UEAxMTdGVzdC1jYy11cGxvYWRlci1jYTAeFw0xNzAzMzAyMzUyNTRa Fw0xOTAzMzAyMzUyNTRaMBUxEzARBgNVBAMTCmNsaWVudE5hbWUwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEToHAV8xJ2gCXVuwZWJVq/zz/VcGCy/GS Cin7b3cEA22bWYYUCvJy4mVWETFg68gCVcAWwNelA6ByoGsNJqg/nMiVzx6vg6NA 6hhZX+8QjXL8QB4vtEtOPUCw1WowmjC2760lBdl5vQr8fj57epCxGE52ZL0+tY98 I1yaW/t2tEIeithCxb52o7OvrmsDyi+PINbfEUem6DkOkPVdqnHRGqIr1uisF5Qe SVjWbT2dLZw+G87N7CysksyiCczFX32HjrlBMEZyXZsLAy0i/AZOdUO40yE5BzT0 AiFTTS9gNU3XE2xiILvZzVeLqa+yuqbwws4YQIi7OBoqa7j+LAxlAgMBAAGjcTBv MA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw HQYDVR0OBBYEFOK4eo4nD4maNMLLiFEr73PwaWvuMB8GA1UdIwQYMBaAFFeWZj2A twif0o35GiMFuXmPkpVXMA0GCSqGSIb3DQEBCwUAA4ICAQCt+5rcsZjgBUHvNP1Z 89eqXonqDLa59aupdM3SKtnVdvPAClinhLeTQOBeMJIVxa3F4j6JAymHl+REtStq 0Oxl7rKk8wEeVFljA2ntfdp/hy8xASO93o0W3jafKEsqRa3VHzV6e4YOZeejPGri JIL/4Fm2nR+9yzS4+/y2EwCsflW12CaVFBYVRzUrsILM+SN2r+ST3v0jtJnRotcD Dv3FcPxMbODcLhwKTvmxDpLK/rkKkf/OKa2/7kPPooXV8gcgiRKA3za8zX2Ch9nl 9rG7JNZ3bsJVY5SCybgqf1QUXfe9ILeUL5Gu+2JP0Ms4JuT89r8iShvQm5t32wuV 3mZsfKI8iyPXcZoWmZZrxUjY76lo/CCSAA/IF36tSkJHm3D7xJPNSXVkv8LIHFEu pXU5uzkJWOeAWqsKMzHrycmLBGmWqKlleDOnUUU7bEZUHYu1HAXB++dZc4JDC99s nt8FpJv54xJrkesNiPyoOKpONFtIpD0HTWAF/3hKhZntOMoHN8/axFiTmCtFbtph K9oWDM0Fqqv7xTkcMVmJYiBxwtlctXbUjD6R3HpX5SgP0HryZ2hfbz8qp0Mw+J2+ oaxH9Cvtduw/gKQgHpK10FMosJmzmxvl1lcSRxEIHOV4wmUXR8gSw46L3+fYR29u bTpi2XcempkmVbezvOGXVY2BqA== -----END CERTIFICATE----- client_key: | -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAxE6BwFfMSdoAl1bsGViVav88/1XBgsvxkgop+293BANtm1mG FArycuJlVhExYOvIAlXAFsDXpQOgcqBrDSaoP5zIlc8er4OjQOoYWV/vEI1y/EAe L7RLTj1AsNVqMJowtu+tJQXZeb0K/H4+e3qQsRhOdmS9PrWPfCNcmlv7drRCHorY QsW+dqOzr65rA8ovjyDW3xFHpug5DpD1Xapx0RqiK9borBeUHklY1m09nS2cPhvO zewsrJLMognMxV99h465QTBGcl2bCwMtIvwGTnVDuNMhOQc09AIhU00vYDVN1xNs YiC72c1Xi6mvsrqm8MLOGECIuzgaKmu4/iwMZQIDAQABAoIBAQCCKcgRAGZdxaZE swcD21/fvXP1nigckRwRiJnDtWoGCDviGR81JPkTwhgNVIMYT96j5bXjoGScbuYx ezrgUnSXEV9TLi2blT5naZFRmbHLmO7YYa9iVDrmmujNGAU8StDoS83T0agc94NU XmURvPg55PMJv8xXy01js5LQaxM25i/vyBggNOVmQBdDshp77OXsewUBzZLFQR1p G3WUGn51U0/G8gSPLk+diTQrlvtzl0/3gyeBOmGEVU0OjZvgMEEbxLihLpVirCGY Q52SuTovJm4Na6FvTEPGwBQDQd++ukVLaU1OzBxKEm8Rh0JQ7toEJ2MFIQkXqG+I cgbMbA2BAoGBAOJtrfZ9JDHndCRTMGPQHPP0qHOnmCSKfwAYzTV69hxkA++c4/PC TVrrcp1sRxVKYz8UeI/5CyPcUoQGFfcI6VioQ8Y6faqbTSZBPwCY2mNXMqSLLb5M 4pZ0l1e5BS+WKjkxYFdpcgylDFVA1gESwocny58VJV0QiLcwWFsYZadFAoGBAN3x v26+2CUKBPC8xm3odMpkElsYBdaJ7yFe25A9kbJBCrhdlRiMMq4+sV9ENwwVb37Z aspZdcgYUBBQb47wAJ6kZ+Pkcf3C5VTWjgSAVejJGved/f7/RHphBQfyXc1kjOjj wN/wTXxbxEueo2w3+8hpzy6DpRTFBvghNpIkvxKhAoGBAL3FbOrMYVyN/tI/Aqx1 DP8Ny2z7RtFBXkWng73R65lJ3d6iII75BzovYSU9TaozaVDCCHWqJcMNcf8C1r/v sRrEE+F8vjwR4ywvvOz0LvzZZTFxEIqRB8tPtlQoVodWlNbQYk2Aq7ybS+Xb7ECE B5OdL9SJtYH1TJA0LalTnkb9AoGAUol4m4K1dvDG7ZAGaxErfajBesbwRNx+5XYV SQrch+HQTsfejoZ0wn/mDnubzQ6brBzGrgGe347LF4YSNqHiWRzi1ck66xfzmR1B K0Ner3c6ZCOJNa9QlAJIkK/9Wkiubl1keOMwrbKiyUxxkekv5VQUDERAu/yZnuUb GjY4KIECgYBM8kSpb3MNFEpTJOg6IlfIQYavO42DJ4OIwOIC7dXKGxTjTSg0EXpH DAVYQ59ALtjLzrDB4e6d/7MdQG1MBDfVahREg+BwxMgsaj+creWuUj0WzFDyj6jx n/wyed0oRrl5j8HeVqqvPwHMHlJyJEACIRQWgYTRYuCoXYhFX1GeFw== -----END RSA PRIVATE KEY----- mutual_tls: ca_cert: | -----BEGIN CERTIFICATE----- MIIE/DCCAuSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDExN0ZXN0 LWNjLXVwbG9hZGVyLWNhMB4XDTE3MDMzMDIzNTAxOFoXDTI3MDMzMDIzNTAyNlow HjEcMBoGA1UEAxMTdGVzdC1jYy11cGxvYWRlci1jYTCCAiIwDQYJKoZIhvcNAQEB BQADggIPADCCAgoCggIBAN3Pa74Y46cXWmhQtXpp0sIpHtd80QI/zuTkU0TB8Jzg O+ehnRMpeetCr+0YsKeIM0l1WQHt0zBmUi1emc4OcABnXE/Qp3SQuO3u3emi+g+k svG3Kb5gSOswHPlR3EjvCeB38SS3A0bxnvJMbKPlXvhhtkzWRoZDSlxjHWzeSJ8u XPjuMSPP+Tr+97rtelbufyEta61sr1ahwoBJHFnre2s7KdiG34AOBzbBb8GoAtQ7 IpHHyQQzVTT/YNjdgmHz57uIptbWwBXch0hxBiMleb87Zxpx6EEt4GzSyOt8Qkcp Ja0z68SEaL0P92G92Os1jvfiBFVos+q0IPnvIhCvAgh2LojjBHRVSSGlBHSLEd/D dzaXuYBJrpxoHl0eRZGGa39BJY/gsvOgJ27xFB8kN3PCYSRekF4tuxkWFOmPGLKc TC6jYHG1SIReZgouX16i4lwlejNf+f1La0ZCEr13neaaSZmpd87DNMaQkw+vovUO oUeLCFPknOOFFQiKrI1SmLPjo+0hJPZa0CKz7Jp7ynLBSA5JZDYzf6asxTYvaD2E fjQV+Ucz/blDCbsZrH4HxN42jACYg0sWUQOdyLaTrOpo67k8iPxeizg1pRrIP4U1 emnMjAbW2hZOZdIR2Rel1XfwW99rBD7ejun53l+gNUIkyi7XMz4OE3/fHO1+X4gx AgMBAAGjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0G A1UdDgQWBBRXlmY9gLcIn9KN+RojBbl5j5KVVzANBgkqhkiG9w0BAQsFAAOCAgEA JwOX8/GXfnNt/9YjSlORbwKWYKrigNatGzvOqrbROnueyQkWCOsKXrqX+ol4DOpO 2I+JYdparoqvyAhNKaNsKfW8E4VOta4bIvh0oFQPJXrQAhdHocyTCIX18qbp6zIN AEJLdDvjeBCEo2t/Ip1Ly5bhFCfGeP7LU36tD3T15/8eEARwQ7v3tczBKM3NQ5ON lnHOheXKdAQcJou8kJ1x+n/Cy2MR/86qJV6R2OixXvWiHK3c8P9goREPPELPc5p9 ylYsCMgRBiBA1YKRVExH8YCNMF+Rz4U6zWaJ9HfVEHNI3fm2w5FwzwErmdVutszp dpTUr2jjihxFnduP9vA7Y79EEgFZ7NT/KLlUBXyfiYSu4nwRzV8h+RKZYD+XIFeB FgQPSMbrNG2hOviTPq1ACkoH2vEV4WGYrjvGT/kTl1W5pzVbjE+Ja5aLRm1X7QbU f+X38/n4N5yEMd/q7WvCzlq0BMhy28iMjzSdPKw4c/R5LwltCq6VNzjjwm4WdC3l l9CE4RhwFrZQl1YViX0rB8GKOMihyhGLS5jctIYLUS+vDjZzh/m4SS9QArnSph+I tNahrxZZaiLE0RFViIV6Oi3ek1qmxTjYunNU/fVxuLvlHYNzHqvPLTDu6IS3zu4o IuYvX8gxa8VkMJUQvtlOTG4HSj4LmU75f/SOsogld4o= -----END CERTIFICATE----- server_cert: | -----BEGIN CERTIFICATE----- MIIEUzCCAjugAwIBAgIRAKECdnHbq0ZQU/jHt3QE0+wwDQYJKoZIhvcNAQELBQAw HjEcMBoGA1UEAxMTdGVzdC1jYy11cGxvYWRlci1jYTAeFw0xNzAzMzAyMzUxNDla Fw0xOTAzMzAyMzUxNDlaMBQxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAKsIzoC42QbEl0r9EZOfwc7MbZ6dls2DSi0S U0bZdybQ0yBrcqkLjddLdxPA8/1n41chU2QkHMXzc23WE2vyg+VO3sEn/tvnxATV pjLABbH12s8JHN0QBi07Oj66TTAf3aQQbrXi4A1Uoyq63AL9VErTqLHvSgC4xsi2 c6da9/KDh8i6ryXEnznHaA8nJncD45rHIozdQ3Np8r/7G24wgTNCKR1qmjnGtfyV mxHA1Rc5TJoLvTU7675xYBzICDzo1dpHbA5QrkEECiTpm5b4a52El6XJ4EF4nWMT l8urht8P51xsFa3fPkpOB/MUUSc5Au/NhV8N1f67FsSr18ysu1UCAwEAAaOBlTCB kjAOBgNVHQ8BAf8EBAMCA7gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC MB0GA1UdDgQWBBSsq7/T5TdI0pFhfjeJnBzgLn1aMjAfBgNVHSMEGDAWgBRXlmY9 gLcIn9KN+RojBbl5j5KVVzAhBgNVHREEGjAYggsqLmxvY2FsaG9zdIIJbG9jYWxo b3N0MA0GCSqGSIb3DQEBCwUAA4ICAQApA4T/Xa0cieRs3mp+uYG78XWikyTdhB38 1uWz0CVSe0xc5QL/3LHeXyB+++GtTkI/itkPG5XeWSWXftj/wqgM+PSz4GWsNRuU HL8PrtsoHnSLp8xtz/ioDL6tTeShkN4dYmS8YHapPuoEjU6Jzb8jWbHDJbH+TOmB /hLBxivVm6oJqwKfft0BC4qn6i/Il7rC6YzDGAhX6i4d3AUAE4czxTu2lSbusoa8 Y5+673wtaPzCwIitX8oCCVEXCSimxrQErNAPSajwwEYmz1e65/Y655sakFfMVgkh rdkNCpYMbdjZURVRLoD5nW9g1WfX1p53vGWoEArrfbDL+WWY0RoaISGyL/5+mjrR tlMHrSSBpAEyT3b/nkx1C8S9Xdyj0TqgZHRI/7aK9gyxr3k77rXcGUxfMbFUxnze 6CvMLSwHfQNvdjCe4eBCu0GrGj4EQvfXcswkuLbzSHakd44iDlHInHzSVFfIMIVB 88nrI4rIHTib01HjNSNMBkISp23wm5D0fnVg5PQUvY35ZCg7mWFtpnBbuXeOUjox tlO3va8l/IMZv4gKcdj9S6m088eCI4BW8RNwazkg4l0elrvkHLYxEBlBqaPYYTy7 jBVeW1y9jn4njkiE8u2UlLiXKT2Vt3xrRLJukt8z7gdGPsFQ07ebjcRyNeZyLq1J pMYRyV+HdQ== -----END CERTIFICATE----- server_key: | -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAqwjOgLjZBsSXSv0Rk5/Bzsxtnp2WzYNKLRJTRtl3JtDTIGty qQuN10t3E8Dz/WfjVyFTZCQcxfNzbdYTa/KD5U7ewSf+2+fEBNWmMsAFsfXazwkc 3RAGLTs6PrpNMB/dpBButeLgDVSjKrrcAv1UStOose9KALjGyLZzp1r38oOHyLqv JcSfOcdoDycmdwPjmscijN1Dc2nyv/sbbjCBM0IpHWqaOca1/JWbEcDVFzlMmgu9 NTvrvnFgHMgIPOjV2kdsDlCuQQQKJOmblvhrnYSXpcngQXidYxOXy6uG3w/nXGwV rd8+Sk4H8xRRJzkC782FXw3V/rsWxKvXzKy7VQIDAQABAoIBAEMbV3rmDDE9nWcM 2IKlojNzvmcHyg2kv8vjbs1Tsg6GzO/heMGfCO46a+RSRulcg7TCHKgkCy4YEWg9 IK2wH9QvF/ONr8+0phKHiYhME2/52Pp2xt5t1R6WKIpIKtUBC8O9ttKiy+ovFT5E xuJdZ19coMn/63dRCJ3kCIjXhoWeNbSM0feZxKvnoJrD1ZW+0bjNu7QRK+H9uqEb NgyT45Hti3mqOZMD2V5C499aA+IgpGsDP53QHBze4BYd1aLtEcYqxrRqNUkEsgpJ 1X8h3LSe+RSRIfD6SUlEIIFDCtCS5fF0fKXZjEHurm6HksQEK9/VfIbsoO5HnLSv et6anIECgYEA2CWVMoXuMjHm+m1xX+eFtYl6OZs4pZf6c9UrJiYqToTHUz/pywEj dvWL4ckyJWVe/q/vZvpLP2ub67ZVtVktzFDJUUDqTbaW6hvN8eLkiR8017DU4+7W WMt3hWr2n3PogXbjxHMxLJFoVvFzNzlBB6UA5BC5zzshAJh5fW2sxwUCgYEAypHb sLVN/aFPd/tOgxC2okYcV1WW1qcSlVQ+kvD+DYJJFTshFVYsA2lv7WOUAp+/hKd4 hSF57DWTAER1brK4x8H0pek0+uas+GHfwHjtcASyQREHozLVTE1n7SE2w9Iod9VM 67fH6b7XZDdZm1FG7l6jK84bjy/+aPYEH5J0tBECgYEAxVFp5nmFfaU4qx0GBvsg gR1Dyxr8l48qQFw1y9nDfXKRVFpgX8ZmTc7TKAe4E5N7KR4LewK7duYRrRkDHU6Q FJkbb2XHf7JUCtvfIhZzcwpd/xma/4mle+Ii9lUzV1VEyAt02n4eQgVsLxK0j5Fg 4E2thoYOWjQsaJLJNcvNktECgYB43g73oTan31hLfueZzJ8stCi085zM92NfNqUf iCwOY263/FABKymX35GpU4E9D5R20nZW+WKGTnEn97EaHAmlJ1WSqVOzYXBTxBJ+ Bamm7SZvLHoiJnKe1JDuLKNAtGTxG5SKEV53Wieq5FvTEOwBzvYNbS2Egl6KwkAz lm+MAQKBgDVoO5nlJ8GkJ7OK6JGmaX35oPwGZ13IFNUQ1gGtYEG9MoEqI+w3tn80 4ugdcsVR5yiLAHREWGFIQ6R2A+KfPMiqwSWg351D/2QW9WTO/LAzzCaT6ABbtI2b mKM0JQdkqmYAEGtO+oFkrSDKlZ9M5ggwHO1DkKTLne2YFy0sYBDQ -----END RSA PRIVATE KEY----- nsync: listen_addr: 127.0.0.1:8787 listener_debug_addr: 127.0.0.1:17006 bulker_debug_addr: 127.0.0.1:17007 bbs: api_location: bbs.service.cf.internal:8889 ca_cert: "" client_cert: "" client_key: "" require_ssl: false cc: base_url: http://cloud-controller-ng.service.cf.internal:9022 basic_auth_password: internal-api-password diego_privileged_containers: true stager: listen_addr: 127.0.0.1:8890 debug_addr: 127.0.0.1:17011 staging_task_callback_url: http://stager.service.cf.internal:8890 bbs: api_location: bbs.service.cf.internal:8889 ca_cert: "" client_cert: "" client_key: "" require_ssl: false cc: basic_auth_password: internal-api-password diego_privileged_containers: true tps: bbs: api_location: bbs.service.cf.internal:8889 ca_cert: "" client_cert: "" client_key: "" require_ssl: false cc: basic_auth_password: internal-api-password ca_cert: | -----BEGIN CERTIFICATE----- MIIExzCCA6+gAwIBAgIJAOPFFRMyK2dVMA0GCSqGSIb3DQEBBQUAMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzAeFw0xNzAyMTUyMjM1MzlaFw0xODAyMTUyMjM1MzlaMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOPQlCJnidk 8XLD0TysGURSJ35BBCaKPGULVEWklO5nzP68J21nY/1oUEdnA1d5cJh27U2D6gZ6 PEN7RsZTmpygFOQQaxbc8IKx86ackI6HCq3WwiDA92IJMMvedPrGWUNoG6h/qAwi RCo3TdV61zfy0mqBdxa1X0algUQOZCUHk6R+DRbCThXQyZW7MNyfnNb1ubw03eHp eSTxMvYm0k/+EbYtheY1h/MJklidEEwTw5ygw8KcxowcCFjdJjaqVgPhNZCNTuA6 GUrIQJ9hB/KHpHmmiege3peq5RQZg/EfoDUtRbVd5V1z7t+2O+IgBTEKBY5yzr4S RxK9tdHEn+MCAwEAAaOCAQYwggECMB0GA1UdDgQWBBRRUvkBTZ+jf0ao85VurNMQ v2QJdTCB0gYDVR0jBIHKMIHHgBRRUvkBTZ+jf0ao85VurNMQv2QJdaGBo6SBoDCB nTEeMBwGA1UEAxQVKi5zZXJ2aWNlLmNmLmludGVybmFsMQswCQYDVQQGEwJVUzER MA8GA1UECBMITmV3LVlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMRAwDgYDVQQKEwdQ aXZvdGFsMRAwDgYDVQQLEwdQQ0YgRGV2MSQwIgYJKoZIhvcNAQkBFhVwY2ZkZXYt ZW5nQHBpdm90YWwuaW+CCQDjxRUTMitnVTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 DQEBBQUAA4IBAQBk19J3yfMb0DEC/BBDlHUyGvvsLr0PVbZGtYT7qxHkqOQBFz1k q65aeNuT8D0GSMy6gfF64cRPp3A7a8NfeYsSoynufMHMaMKEzlYjSyNGwDcxyRwv eQ7w4QeX9EnRCBf/JQdC9bIIs9IoJAgNHhEZHnzdnt76NX1hJ+w8SVTgi5zdQknr v+wroKbStKy2R5qxnW1bPgt6AtMoE3M/ZUj+DNQvU3wEcTasWuxvDUOhZfoOM0Rd UxpHKQp+6PPugE59i/xg/Vm53FrAQ6+4Tn6w5jjtWBszH8OxFkyD+mKhKsh/DkfV kXvnbnHRmaEsQBbnWkhygDws3S1YT8/vTZBw -----END CERTIFICATE----- client_cert: | -----BEGIN CERTIFICATE----- MIIExzCCA6+gAwIBAgIJAOPFFRMyK2dVMA0GCSqGSIb3DQEBBQUAMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzAeFw0xNzAyMTUyMjM1MzlaFw0xODAyMTUyMjM1MzlaMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOPQlCJnidk 8XLD0TysGURSJ35BBCaKPGULVEWklO5nzP68J21nY/1oUEdnA1d5cJh27U2D6gZ6 PEN7RsZTmpygFOQQaxbc8IKx86ackI6HCq3WwiDA92IJMMvedPrGWUNoG6h/qAwi RCo3TdV61zfy0mqBdxa1X0algUQOZCUHk6R+DRbCThXQyZW7MNyfnNb1ubw03eHp eSTxMvYm0k/+EbYtheY1h/MJklidEEwTw5ygw8KcxowcCFjdJjaqVgPhNZCNTuA6 GUrIQJ9hB/KHpHmmiege3peq5RQZg/EfoDUtRbVd5V1z7t+2O+IgBTEKBY5yzr4S RxK9tdHEn+MCAwEAAaOCAQYwggECMB0GA1UdDgQWBBRRUvkBTZ+jf0ao85VurNMQ v2QJdTCB0gYDVR0jBIHKMIHHgBRRUvkBTZ+jf0ao85VurNMQv2QJdaGBo6SBoDCB nTEeMBwGA1UEAxQVKi5zZXJ2aWNlLmNmLmludGVybmFsMQswCQYDVQQGEwJVUzER MA8GA1UECBMITmV3LVlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMRAwDgYDVQQKEwdQ aXZvdGFsMRAwDgYDVQQLEwdQQ0YgRGV2MSQwIgYJKoZIhvcNAQkBFhVwY2ZkZXYt ZW5nQHBpdm90YWwuaW+CCQDjxRUTMitnVTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 DQEBBQUAA4IBAQBk19J3yfMb0DEC/BBDlHUyGvvsLr0PVbZGtYT7qxHkqOQBFz1k q65aeNuT8D0GSMy6gfF64cRPp3A7a8NfeYsSoynufMHMaMKEzlYjSyNGwDcxyRwv eQ7w4QeX9EnRCBf/JQdC9bIIs9IoJAgNHhEZHnzdnt76NX1hJ+w8SVTgi5zdQknr v+wroKbStKy2R5qxnW1bPgt6AtMoE3M/ZUj+DNQvU3wEcTasWuxvDUOhZfoOM0Rd UxpHKQp+6PPugE59i/xg/Vm53FrAQ6+4Tn6w5jjtWBszH8OxFkyD+mKhKsh/DkfV kXvnbnHRmaEsQBbnWkhygDws3S1YT8/vTZBw -----END CERTIFICATE----- client_key: | -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAw49CUImeJ2TxcsPRPKwZRFInfkEEJoo8ZQtURaSU7mfM/rwn bWdj/WhQR2cDV3lwmHbtTYPqBno8Q3tGxlOanKAU5BBrFtzwgrHzppyQjocKrdbC IMD3Ygkwy950+sZZQ2gbqH+oDCJEKjdN1XrXN/LSaoF3FrVfRqWBRA5kJQeTpH4N FsJOFdDJlbsw3J+c1vW5vDTd4el5JPEy9ibST/4Rti2F5jWH8wmSWJ0QTBPDnKDD wpzGjBwIWN0mNqpWA+E1kI1O4DoZSshAn2EH8oekeaaJ6B7el6rlFBmD8R+gNS1F tV3lXXPu37Y74iAFMQoFjnLOvhJHEr210cSf4wIDAQABAoIBAQCTF1gb18cbfnOV jO/+oLvIhbqq3iBPFL7kiabzUx2qTG0GVWOaiJ/O5P0tF7CNxQwJwbowCb6m7J4T a9AKMKwkjsvn1umVos1MoKjRcwXQDobbxqLxm/L2zE7lqQd38GUHrHDRRmOR7Nw0 nLBwmBr1PDFEZui6LeXh727RT7nHlx6yo6cIYUrQBWaFSZJmfPD2pCMLRvEEY/0v yuv6NwuRVdO/P7R+pLDXDDbOktOiFvy9QUz4KtY2ZgZHobHZ9LJlyqFiC7wFQkMs la9vBniARgE1vX9D1QJJZ01ilivjiRDHaEq7EnZ9kRoO/ln3Yqlhr5OjAeQMFlMR AkX9h2VxAoGBAPnfruRdP5JTdXmun4IA0Nn3a3ZG7dNkUIl/yfhTKCD8ITGq5MXV aNSkOTVurkhrA38RuM6RQPypbjGRYdQrRMeKv6IrTC+sb7BhgcYe32370K8Y3TTX hgB24larb8jPot6f7nvkTbJJpwmHE8cXm7Gkmr6n340GPJzfmJke+H3fAoGBAMha rS+fCIyI3YwxmcyrA7nEKmAg2tTLiJ7xIY8i/ADwedqAnV8oAfScMw7IAF1EBkAt z2xfQhm1/pIqr1GcLxOgqvbixXfmM2qsLS/Zb/T6aOJ5xejsI3d21CIg5LwxF/EO 1hm5ereMdDTFw914HcO2Wap0Kyqg8MSd1GxgIhZ9AoGAOOqKm9nhsSLxj1YHX0Vw TTXedIKTiaM/9RH2n2nRqjHEHdwfYDDMQCNoJJOhfz1g/oC659KOSv8M6p2C+yEf +ZPRMs9J+1H73uFW/hnqKtNBJaE0QeUV0OVDiRpjzAn/v1YOrInEaOf99F2gU6k8 /anQ1bzHXwgcpl8IE1jKoWECgYAFVORm8AR6OOosYOWG3MYsm1vFUxp/ryrjj+ck t/mczMlxVxrY/WeP6tgw/IGF+dlwu8dZSu+nX4B2w0wHD/DwxMXH7CD1H9sea5aI P3ELQ96mqDbsC9ylwTPD9LwhheztLUflR1pMqCAvh1O/AQNJwgCA2LaNW9sMYGbW u3gswQKBgGsjcgS8l6cAYXOncwN6ROyosL6xkvc8zzUSH/KdPcXbAJZm/hQYeAyS QFAzUdyCXnokknYbLcsNmVqO+FAXQ+S2lwaBxS0uHWc7oc0KYaNPdFHSW0PCGj9u rvaEn/skAHkQTbLPPoPmuOs5qwWgYkMB6AHcSeCmBQokX7Zn7nfR -----END RSA PRIVATE KEY----- watcher: debug_addr: 127.0.0.1:17020 listener: listen_addr: 127.0.0.1:1518 debug_addr: 127.0.0.1:17021 traffic_controller_url: wss://doppler.local.pcfdev.io:443 cf: api_url: http://api.local.pcfdev.io skip_ssl_validation: true nats: machines: (( properties.nats.machines )) host: (( properties.nats.machines.[0] )) port: (( properties.nats.port )) username: (( properties.nats.user )) password: (( properties.nats.password )) bbs: api_location: bbs.service.cf.internal:8889 ca_cert: "" require_ssl: false routing: host_ip: 127.0.0.1 routing_api: sqldb: type: mysql host: 127.0.0.1 port: 3306 schema: routingapidb username: routingapiadmin password: admin listen_ip: 127.0.0.1 debug_address: 127.0.0.1:17103 enabled: true system_domain: local.pcfdev.io etcd: servers: [etcd.service.cf.internal] router_groups: - name: default-tcp reservable_ports: 61001-61100 type: tcp tcp_emitter: debug_address: 127.0.0.1:17105 oauth_secret: tcp-emitter-secret bbs: client_cert: "" client_key: "" tcp_router: health_check_ip: 127.0.0.1 health_check_port: 8088 debug_address: 127.0.0.1:17104 oauth_secret: tcp-router-secret # For Diego: diego: file_server: listen_addr: 127.0.0.1:8080 ssl: skip_cert_verify: true auctioneer: listen_addr: 127.0.0.1:9016 debug_addr: 127.0.0.1:17001 bbs: api_location: bbs.service.cf.internal:8889 ca_cert: "" client_cert: "" client_key: "" require_ssl: false bbs: listen_addr: 127.0.0.1:8889 debug_addr: 127.0.0.1:17017 active_key_label: key1 encryption_keys: - label: key1 passphrase: bbs-secret require_ssl: false ca_cert: "" server_cert: "" server_key: "" health_addr: "127.0.0.1:8891" auctioneer: api_url: http://auctioneer.service.cf.internal:9016 etcd: machines: [etcd.service.cf.internal] require_ssl: false ca_cert: "" client_cert: "" client_key: "" sql: db_username: bbsadmin db_password: admin db_host: 127.0.0.1 db_port: 3306 db_schema: bbsdb cfdot: bbs: ca_cert: "" client_cert: "" client_key: "" converger: debug_addr: 127.0.0.1:17002 bbs: api_location: bbs.service.cf.internal:8889 require_ssl: false ca_cert: "" client_cert: "" client_key: "" file_server: listen_addr: 127.0.0.1:8080 debug_addr: 127.0.0.1:17005 route_emitter: debug_addr: 127.0.0.1:17009 healthcheck_address: 127.0.0.1:17012 bbs: api_location: bbs.service.cf.internal:8889 ca_cert: "" client_cert: "" client_key: "" require_ssl: false nats: machines: [local.pcfdev.io] user: nats password: nats ssh_proxy: debug_addr: 127.0.0.1:17016 bbs: api_location: bbs.service.cf.internal:8889 ca_cert: "" client_cert: "" client_key: "" require_ssl: false host_key: | -----BEGIN RSA PRIVATE KEY----- MIIEhgIBAAKB/DMF5qOW+fh608KhX7qBLNHHmfzCfOONd176Oaf8rGht5KdnoNge TYSGqBFuYB1r1RbYEVhWAkH/8mW14XRVNmQ4C9eQDFqeWmmaOoSBG5GdP5GUfhI/ z5vprQw+rnV4gt4InCA7QaR86pLj5sMiUij5OE/CW0dw29+z5E0p5WnQX5+utRmw ioQJD8jUDvzFrvzKIdE0HVOEl0agbeXq8U2e9E1de4iR+NiDc1zeiQmDNCIhFJb4 FL7WqqokL+49SwSWGmOFKAlpj4Dlhx5dDwJWpcDe0XBXCkfcXn8xXNOT+4YBxJUG idNMPpLKpDUphZRj8CNBSMkjehIKVwIDAQABAoH8MiCAAQQYvXfeh36HT/IMmGSi 8mIY1G5tclAfSNzCfS5Jz/XNXcYXnjW09LsdjoocJX9NOx30xeawvCA+SU5WS4uM htEscfLVHJ67EubMsPhuNZZPbZpnWuPucPM77ojg+UY4LKpKyVE4G+vvEJKtaTe/ jQyDJOLKATL4/p5DtbDH7hVZcJVHU94csiE9a9OtyAvSwZLmNxGIBHshFntjcI+/ hmQSFl3d1iduYGx7oeq3wX0sQ1mk/QksUTHRrlLfSQhLi5ZmH9Hnn/Qw2WeXKVdk BvXAUBiHG7Y0qGHXl5FOkB1BSlmk/EOkBk6gWl1a1Kx4A6oyNL4+HsuBAn572PqW IDutj4shf8ysI5fLJnvGCygZmk8LPZIlZZqLpDGo+l4iF3VCsd8CU2jKfWqel8+Q axdmu/BrQ7xyuWpxoHtKICv+CitI1ivzeYQwRCmjIN84jeGP9Pty4AJzhySegf/h n3irIp07wEzdedoj4A3RWWObX+AeubyUqfcCfml3scNb2oBK24RDVGYaUSWkSHBe OEU0QlOaJXZ2kCK2rIK/IVI7cD12WpkWTGY782VBmipEXwtMTprQzMrnK25shS+z AjCDGXtqr0GjxJh73WRurs1dVk6sqslSp1M/R9fmjGU4vdYL2JfMczEH4+57aOpR sW+H0FEYDayKoQJ+Eo8gdjDcYJT7N4jsRfuLesEImVQArV2HbNrMNNh2AWkYnAbw 5lD3nIgFMFcJhBapTJzZWP4DYrzVOW3MJrEMd3yiHSiXDxm9BMw7h9/05DrCtpRt fw8b9zOyHrPdCiz9WteGXexE6/hi8ZpOqn3hJ7EiwPWRTK5gappQ3UJfAn4Tr0t2 cwZtO4uNPCPcirzqkacTkgJeqEpY4ERtv+NXF1FLdfD6MC3ayuRN/mN0EWx0UbI8 gVZb/XoOWzpeBJeOnKKfLIIUG+P9rQPY9IAVFclUnXPy0KDzPjcCLHMejokSOu2p VtXXxY4/huFZHWflcxM56NV9Q5QWDq8+rQECfjQTbNbd4ehbC/Q5EZ1SIzeaSLrn 0ICmiRajnISbje5vPntqPXjBkbiVGx31qOaZ+DlGGLOyzW/GP5X4NOUwza2bYh3q nnzwBhoGLZfvoes5Nw06leOdVqcvIjLIDhb+XbiiEeAnONUp+BAKzDYOIp7K+LPe 1rHeshh0P/QfCQ== -----END RSA PRIVATE KEY----- enable_cf_auth: true uaa_token_url: "https://login.local.pcfdev.io/oauth/token" uaa_secret: ssh-proxy-secret rep: listen_addr: 127.0.0.1:1800 debug_addr: 127.0.0.1:17008 zone: z1 bbs: api_location: bbs.service.cf.internal:8889 ca_cert: "" client_cert: "" client_key: "" require_ssl: false ping_timeout_in_seconds: 600 preloaded_rootfses: ["cflinuxfs2:/var/vcap/packages/cflinuxfs2/rootfs"] localbroker: service-id: local-volume service-name: local-volume plan-name: free-local-disk plan-id: free plan-desc: free local filesystem for bosh-lite localdriver-url: http://localhost:9089 # For CF: nats: machines: [local.pcfdev.io] user: nats password: nats port: 4222 address: local.pcfdev.io metron_agent: zone: z1 deployment: pcfdev consul: agent_cert: |+ -----BEGIN CERTIFICATE----- MIIEJTCCAg2gAwIBAgIQPrEW7lFCsRKIYPCRnoi/ITANBgkqhkiG9w0BAQsFADAT MREwDwYDVQQDEwhjb25zdWxDQTAeFw0xNjA0MjIxNjM4MzJaFw0xODA0MjIxNjM4 MzJaMBcxFTATBgNVBAMTDGNvbnN1bCBhZ2VudDCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAK2Owzr/x4wzewIKCx9b7kA9zaXemyEUFsKGZU/FiQYbliUh rEmGJZX7uUBUxOQD+gHBQSlP2tWRW1W6hug6fgUUcTevhkYrn6educiGK7PSde5j 3uljV+YpzOpQjfXLtVpXP7Fjg9fPw5FXAXMGpltsysnlqu/YWkVTj4nRo8t5MtmN BPyA/x3GvdCr1K3LV7yvxXe24jRtCcaNJIwcTksOND2pl1fcGkkqnzi1EaT8UfbD YzQeVH4LSg+ukUQprgrdB8stoBl7EubWgi9ixfNbw3THxVL3kZgMEzO03yyP92tC MxXhlkt92+w4seAMDDZLD2e+3r4iHd+1qANFzL0CAwEAAaNxMG8wDgYDVR0PAQH/ BAQDAgO4MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU V2EJqyuNEQDeTMz1/P2B5lEeq/swHwYDVR0jBBgwFoAUgxYmzKGS/VZO9JZTFy3C Zt27Mm0wDQYJKoZIhvcNAQELBQADggIBAJU0RdHhWr3hICn+Ck3PFNRw/d83LRuq hfrrNdvSqaiN/FXuo7Xroax5PHT3DewQBFTqiJ+x3iMCK4NyuhevB5itExm2sJkw IpdjepnfpPLa1ygc/xNZtvWustlChKDFiBmA2uDwm4z1V8UnPSP3qS0lP57WMymr 9b7tv62qgyz2uhlP5dhjGdLUnFdUr6EFwpUjxHfHeOmM21p2tRjcsemMHFMKeoX/ 0+WgBAT2Rgx991JSHOS3n1f92MRICCb5Gm006z6X4y3lnpgWAR6nBAlwvVNUwUja sZCqiLxGOMXgXLIwRR++yApnAL+xOq67QBYVQN9weludj0bsOi38qPVftmivEwy3 cxnSS0FeOKyNkllFYtf40J3A9hWeP07SyC5/hL7tzKo5hYEGC/MNrLlixJ9qBXmD 7Y4MOrAVTFsb2jgYdRZzsUGWO1PZhI7oUxc8axr3eN9Wz39P+Mq+ihoHFo9u0YKH LBYmRKFm/INw8i5xhdWwVfTk96DY/MnlYm0Jb710pL19v0QpDsX1nHRJQ8g5ENul g25UGJCmh4+maQZ/bJ5GxqKfpMfq+iBadx0mu3AWjrfoDspPxOsult2rE0MOSGMy ep6clZEN8IfPJD2H3Rk5aZydPcCH415pN/80YJ6sSsaMFcyCjPk6smkzqixxJtMw Sr49l3sAAm2N -----END CERTIFICATE----- agent_key: |+ -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEArY7DOv/HjDN7AgoLH1vuQD3Npd6bIRQWwoZlT8WJBhuWJSGs SYYllfu5QFTE5AP6AcFBKU/a1ZFbVbqG6Dp+BRRxN6+GRiufp525yIYrs9J17mPe 6WNX5inM6lCN9cu1Wlc/sWOD18/DkVcBcwamW2zKyeWq79haRVOPidGjy3ky2Y0E /ID/Hca90KvUrctXvK/Fd7biNG0Jxo0kjBxOSw40PamXV9waSSqfOLURpPxR9sNj NB5UfgtKD66RRCmuCt0Hyy2gGXsS5taCL2LF81vDdMfFUveRmAwTM7TfLI/3a0Iz FeGWS33b7Dix4AwMNksPZ77eviId37WoA0XMvQIDAQABAoIBABVoisR4UJEGuKGj w4N2v4jFFtzi/Jez9qrAETcp0qEiPf8OjEX1eiVqC4vX6QGHTAtzXypNY1z8tRt6 CrISpQDTaLPJvvJg5yyx0/zcL//achmZ0CFR08HcXh55GUm8ev5NzNmAwP6Z7jG7 Xb5mj5avcMQ+xDsZoOj0SbxiU6YBdS5lmV0VABfvxVRGw+WHsxbsnD9tVjsaRca1 T+iaTsfK9u6EVEIPTl9MZb8Dev5Exqt/nQoo1mceQChLhgF+6VxKLO3GPmpCHZNr /6+ydS6Qrdjs9EdVx7WSN9B7SPARrHFERM0VWBdumAWjOx9De58TqMvNhC5VKonH Tkn0NgECgYEA2t7fi+8+6ttFFCHJP+U+Y6KyzdwBDUzgJc0ZRx+EEKRqvVQn6AWY wZhbE7QxUkf68pgQ0YlcQGWf9uUKXeR6VsD+6yO2JJI7906ba4fsWYDm0spFxDxM REvDAJZ0BSOD/a2zJBZeNMbztdUgW9RmHNoEzgswsIkJt2FlZKaXWSECgYEAywAJ UPBt3qYSyVlhPuRN2i2BPKRme9dyg+1ypFyw1Zafc5JhjKovkn8Rgche8x2tfL+n iBxSVnjLXRfHFrbOCAS4c84AJ0bhoW+lhP5KUIwco1i3jCm7Knv6nsCfbeEwkSUG kc4rsCe7cNFzQtbe+MeWMCbGK0x8kZg49CdGNB0CgYBvI+OCTG+3lLakPW/TOVaQ A6smK8SA+3uK1nYyjodiaAsnrtdA0665B+Ofws2UyaZdj+hibozgynoLRk0YVo/l A8Wuo4i3U2aN82Wqme/jlzge68W3myLjP1F7N+scPOemZpDkD1OxGyHgQKRY3Scp GXB9LGOCEWRUsWlqTcnm4QKBgALu7jOINd44wh68tuYEwIc9jxeEPKLfex0i6jwr xrZfZdBytgwlTWitg2A/t/eFX0NlNZOG7T2ooy+mL09JtvJwtwWdXW0z3gDKLzcb wZEmZSeLGaPh2n2DqxxuJh+dWGlQgqbKtuDlwhSgQi0eE7y+jZIGjWiEw2wLKg+F HcOVAoGAbY0NUyuWkRUnSRO0e8+h6AU0Pmdp2qGu8UhewKslmL+WoUm8REwwC2UJ FSxb96zvg2HXLtbzXSLoovSTsJditm0sAiZldeE6k3QstF+2H0uCk0xg0+sKK9tt 6Vi0fCrH4M2LqLYZF/SQVVpQMalZ/eDRNnlYGU0e9PIm7hgQFjs= -----END RSA PRIVATE KEY----- server_cert: |+ -----BEGIN CERTIFICATE----- MIIELzCCAhegAwIBAgIQFhPJIp4iCJ6HrRu9+VKOJDANBgkqhkiG9w0BAQsFADAT MREwDwYDVQQDEwhjb25zdWxDQTAeFw0xNjA0MjIxNjM4MzJaFw0xODA0MjIxNjM4 MzJaMCExHzAdBgNVBAMTFnNlcnZlci5kYzEuY2YuaW50ZXJuYWwwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDU213a8PJdM3huWrOh3pK82AU83jDr9y/d 2m/mYtD908O84IxAjwKUETE16sNnmEWSP+C7eEfQg71uTU4HSO0rS9xS50JNMn4V wPVfzK7xVk9CcKlVSIg/TzHevVMTyp7uYIp1E3KyrDJhDD/44T4d02fyVXAyOg8v zEuqYU37jb5bf+16utWi9U4NB3tR3L4EI6oVOXQjQ2MrF7prjlm2UM0yM+yzFb40 1QkMmUID+EdmCT05hCcNWYL+OsHAG1HakSqB1Pi/Ux5B8/2GRPw2lntaWF3MMKhc KKXo9z8RaRrAlIBR6GVyG69CG2uoOWrrdqqIVNKREWXKgcvLu+qTAgMBAAGjcTBv MA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw HQYDVR0OBBYEFBSTT2GxUt5mSHT3kK1/ar1tMZWLMB8GA1UdIwQYMBaAFIMWJsyh kv1WTvSWUxctwmbduzJtMA0GCSqGSIb3DQEBCwUAA4ICAQA0LpofKdohWTRSq+wW bo7CvM6+vDw6Wjxk2CoXxEFzrpVJvgx4Tw6OyoqEMN8kH4F+7dl5lkG9jC2VdPmq hnbZfqJQgOA3B5Or01dHn2XnzUqMpb0cxMwLNYhY6ribq2V+B6HKvKdJZv9ww3g5 qAU3O5JYd4qpCNjdu7ZKRv3D0SLy7SE8hwpAQCuca1F/Wievu48kGGE9JO256nuD BlXQzGoVAKxbvBCNlxpPErG948CLPjZ2Arbuczwvgb8A1ji4UAFQrAwZ5D7/F0OO nS3rrbzAh7HO+X71Ow9kjbRKvSMNIRIiMHV31Vl1I2MBFS9FvuWKhPTo6J+dkkEG WgxAcc3BcOsQy+/c0z2kzPMwDGOrcLZH9ysP/oYrlpsJ0K8ubL5TYpVYE2e6y7fS 83Ynqli69Ge7Y2VNkhN+3SKothNdsMCAVDUgWNfHaPM/JRUgOElGSS44weZGnQLO 0gCkE6J1+PdaqK5tRUwr9SzIBCQx7Fu+qKa3wqQoB73o+IC4U16dPZj6IqM4PLCJ 7sPyF3JvNOsAN8q88YvEsFtO4LfIzIPX3+FC3AqezRYMGk/4TCmkQdB7GiDOTj9/ dPF5ub6pGG5yIm9k8s3yocmZceHofo4ioy3xQR4Y3EEBUSvRR5o4nrMll3deVXK/ GrZJY9Ap7M9qpluBdd4BJ5pg3A== -----END CERTIFICATE----- server_key: |+ -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA1Ntd2vDyXTN4blqzod6SvNgFPN4w6/cv3dpv5mLQ/dPDvOCM QI8ClBExNerDZ5hFkj/gu3hH0IO9bk1OB0jtK0vcUudCTTJ+FcD1X8yu8VZPQnCp VUiIP08x3r1TE8qe7mCKdRNysqwyYQw/+OE+HdNn8lVwMjoPL8xLqmFN+42+W3/t errVovVODQd7Udy+BCOqFTl0I0NjKxe6a45ZtlDNMjPssxW+NNUJDJlCA/hHZgk9 OYQnDVmC/jrBwBtR2pEqgdT4v1MeQfP9hkT8NpZ7WlhdzDCoXCil6Pc/EWkawJSA UehlchuvQhtrqDlq63aqiFTSkRFlyoHLy7vqkwIDAQABAoIBAQCYqe0axo1Nw0iw /WSwyA2+W8EF8uZrlxJBsBVpy53RLzzIDtUIyIk04U/GN+aGOnRLfH0WeCIprxMC NXetSeSwlOwkmbC35WsA9zAF0av3c8vM/ziz7h2qKoa+FlOrcjujBKLJbXVqKI7J hButyP7gLWv0Jssdev7BbWknfjqMG8GZTgzzlqrTXVSvoQdLwIdfVy1a8Y1B2vUE b0CZVZzUmrvpprhroePNxq+VefNjCpQyU8qQdd9KnIofCDpORCSaTe+5XEj3BMzT frZb08Adr8FVheiZYEu0vTsbn+TMCh6LyhVmMPL9sMGwQeI16MXFAViPu6mU++Vp 7sk4dlYBAoGBANj7M/qaklvI12u/lvqBMjvCW1G6gDJcff3duvoCTEb5j5mCnf+X vV1LIGzYnlgWxNyO8DF4j7eUOeLbbi2hHI4jiCNvAjeaAO9NQ5kTvcvTZSJgxpRE UV8SVtCXK5eBckzSwH+pWQNouRgnYinw8q2qx/tnIYj/dPBmtgbMZRbTAoGBAPsi TCHsUQFju+/ITLc1fV/QoyHFPQOJ8fP0yA+N45mZOaDv/Z0CzWQS2DM36jiydO4d LnTCBRpEk//BGcdYwbTM6m4OjaN6Vvof6erfAf5WsEvaZhL+tOLTefOvBUZKfxRk 8nlN64zq7jdUkPC4EO5ed8EvE4+KN8Z3DZwLhQVBAoGAbTh9oK7/7z242h71w6EX BSe/SfOEJlWSgiCDxuczOCLVGuO53nemNXjkmIWtpw/HBnLZCz3xsenl/YCRBFzt /8p488UkK5LU16Bf34Ula508ckKekvGUuDOGCbeelMPvIiaQCXLYQLQNP9BLRGtp 7OtjgPQX2FsmpQA+rktis0sCgYEA+JvVXmfBMWz4KcHSIDR1rxqtw8qsQgqXWXhj bPJ79Bx5rlambH7PsVfua5XY6tPPacG9sZw4zO5CzRbuXCgDaubI1LbXhJSh8e8R 9I9cO9q5n/3OutMnYr0TpycGQ7WP5DKiz29R1ijkNiYjbgnpyPAAAWCHLrwXxwMo l+fXgYECgYAFyw5Vcm69GiD+IHodrQLavVw1OSyjQwbDdo955XPhpTzZ3FtLqTdD nfmDn3ANf/ISCP+V5V9C1eKL1wVDOT2TZVLaE3y092KCxU+FsptC7oNOmIcff/x0 McJN1YzWFsHdV5hPCqAFV2zXDKMSy9Zd1B6wBUQCN5fl+8TLkFf/EA== -----END RSA PRIVATE KEY----- ca_cert: |+ -----BEGIN CERTIFICATE----- MIIFBzCCAu+gAwIBAgIBATANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDEwhjb25z dWxDQTAeFw0xNjA0MjIxNjM4MzBaFw0yNjA0MjIxNjM4MzFaMBMxETAPBgNVBAMT CGNvbnN1bENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAySc/E5I2 yi8MFRNMZuFSxiXpVCxxozC9md6FO8+8JnO46lguozUJV+5u+fHWkiZ0Cu2IZ8Qj IgrGrj+z8c817IlimS4jUJ2RQ28SyEsf/CMK3pcfil0nJpoz+yEcgmROkaMc2LKb Tj8DBhfjRGMM5L1GS0fEYoESe9GEr3QHbbkWD6E18CiBBbZWuw2JqqvxeElnuT5x Qylw/0YdYA+O4Wa4yFTt8Igh34kjJUxPS5Z5u8hGG15icOZj//Kd9Q8XRlbGBQOi OsilzUpbpJm++UtPf5CXNanWK3mQWEweGsgQU/vieKXbABpoZEP5B1/qxgew0SoR P2C9G/L+TGWluqlu2y2wSUpedTcpEz+DV26RlsaC+YUekBIgQDinHwsq2EIGguOL UvbQ9/IcB5QN5l5TbZZKsazFcRTYGTCcNTcZGxUHms/Yz4HX/rs0zSOUcJrjZLsr /r/1sdIkJrRO4ANSrVtM1WTejpsHKN/gp71fDyoi3CT3hXdS8TOQWBXT94c6y3TI GMr5HIYtFAH6H2DXzpyRXScGdSOWfamMQXJkbAOx782RJQOpm2um07J9DbH8ovES 9I6ieUvJ1exxn5sqe4cocdFm/5sxNHTXB01M2Fh0BJHvC6JYHocGO0cIe1qImJeP zU5e7M50iOw3W4F9PqfR4b0aN9moOs1TVOcCAwEAAaNmMGQwDgYDVR0PAQH/BAQD AgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFIMWJsyhkv1WTvSWUxct wmbduzJtMB8GA1UdIwQYMBaAFIMWJsyhkv1WTvSWUxctwmbduzJtMA0GCSqGSIb3 DQEBCwUAA4ICAQA/8/xbZ+09AxI/3zAeWoYWVxu8e06yIqxqX4UUw8wB0I3A599j PbvWPmaho7v2IxjSt0XrGynoBnWyPaPesCqOR7ggIYmTbsBYiN7Zncu9uL9JPb5t 3MkxBiBA0Vr4hfyruOt1OlyymctyQFcQh6PzAFer0Dd41lMbbm70yXtczSV7Kpl0 eUaTvlgmdBlnXnplePVLlTtTfQSGAkgmPg1HEvw6egJs4vB888mnt6ou6GeUK/Iz OmjEpbcHNHv3BOUw5AssigDvickjWiP8l2MmBJte5ukySeRsYrR7LkrXBXNsC0Gy bUyYqxdfCmerEiX4nF9Bh8Q53JaPcI39u3IrYylzZhofIMT+YFDltKBy5a5VSBNe nySfZSG8gQBNUe5avDhkY6VPP3ZmanzFDTHCJ5PQuRSti5DlmP49Wq3qdbEmLkBB KeLPdCSUGTEhELDXFZjmq+QTqd/DP0gK1KE6ccqYtP4LwrGk6LFrDDCZATORNZJq XIH3pgQKoWhMzYGLG+zUHk1ORsL/khCt6sRk6mHLJBSVbv+mj48xV+x5qD77X3WI FN8Sifv78INAlFMf5FgaoMloqI8WYrSLshKwzlMlOGD3cIEx7UJXOuowl05kQIBY izb0yvD8f628ImPg5I2QK5Veo/MFNK5i9egoWCtluGyfjABmongS/V1F7w== -----END CERTIFICATE----- encrypt_keys: ["consul-passphrase"] ttl_in_seconds: "300" agent: domain: cf.internal mode: server services: etcd: {} gorouter: {} uaa: {} cloud_controller_ng: {} blobstore: {} routing-api: {} silk-controller: {} policy-server: {} servers: lan: [127.0.0.1] doppler: zone: z1 outgoing_ip: 127.0.0.1 outgoing_port: 8083 dropsonde_incoming_port: 3460 incoming_tcp_port: 3461 websocket_host: 127.0.0.1 doppler_endpoint: shared_secret: loggregator-secret traffic_controller: zone: z1 outgoing_port: 8084 pprof_port: 6062 loggregator: doppler_port: 8083 uaa: client_secret: loggregator-secret url: "https://uaa.local.pcfdev.io" etcd: machines: [etcd.service.cf.internal] tls: ca_cert: | -----BEGIN CERTIFICATE----- MIIE8DCCAtigAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDEw1sb2dn cmVnYXRvckNBMB4XDTE3MDIxMDIzMjAzOFoXDTI3MDIxMDIzMjA0NVowGDEWMBQG A1UEAxMNbG9nZ3JlZ2F0b3JDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC ggIBANN+QfqnZl2cAoWsVwUb4Nk3hBXlQXnm+U4xitLqmtHVFrEVUGm7xEzbbAqB 5KfRBMhQPzmGsfgX+QKFOjJ73zlrbVSSWVmWS/UrbwUmc1Nk0w+t8s6uTn/KaGfu 4zDNlR/ZVkQ5CkJXAEGsA4mJJo/JNH8aswJHUn96l26JfT5P/CuCfOmt2mo9yu/A O8/EdU06d6DjHIogUHKYmRp4r/4CfYed7V3jgZRqxbtIhvnDCL0zH0C1BX/wGJNm H5YM181nLzTUp/aCIQSNzQV33vCGvlAaCfmJiEDXyGuDjOiTd8Lio7pLb7VSNHga 8EF4HvbZMNMS//dfdJ2aR72twnPFRiaJM1AScvtD55Pqty0dg0QH+UPQHor0BKVL stZ9yLQeL6lPv6vjbTUWRSAHNLb+0rXYBXq42yMmoniZkq2DWTQIcXMzSENNyDaP pzcZUTrTGuvWAFyrmOX7K836QTAhxbcpRLy6FVYo5/YnvSoVy3rKXxY7C75MZW7O 4/CTIjU/bfPYKwyGgOjocVGTgf7buUhjRuGrfYhAs9bPbd+f7zplZ+Tr09i1xa+j V5vPREQckNCPxO0rr7I+v8jdpbdWNEJ/BMovuW9YKCx0xuuN+c8hM2myCBzRNqHk kKu66pMSTKxZjHI/JcEGadjuwLq6Ynk6VubGGngRUq9w55mpAgMBAAGjRTBDMA4G A1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQskvGk RgSOZOlUmPl8i/yHY+PAnzANBgkqhkiG9w0BAQsFAAOCAgEAkvzipBJxnUH16F8L qSJ6epHJGjVstFnmFk0cd+h0hjm3pRr6zvYMN9mdiEzZvpGF7yWz3ykDHZkT03Zl +P/XYrwh1ettl71ouWkwNsnzTGhrdRIBOXJB3Ewh2toRhuP2kNYgkaE9x5vkklaJ FJ9gpxf7V1pRttr5imIU23t+UcPeV/PKldL0Lqk452iHpwdGx+CiNrxXIc4WWnTt gJcFWqOeBWPeIU7dnRuI2p16+vOO7NR1ujyxsCyC/YxZHAGMril1cKK+Std9DDeU wxoaSZTC5tcLJxup/rd9BozbJSSM3MwmYOxfZYoCVzxaSd6UI00TD+5pThrVbX6b eslSaVKrei1Ir9pAa+OnXcxyw4wWqgumX+/NHlsOTUX/VbK11vM8VZ9zDk3QxstB Nye03iMbPBQ9y+TQWbN8FVsi1IabVZAG/99ZYXj2hiWkpNIEhx38EQ9Z6hPCBLiU THkTfMyz8eC3k05zEKdNoqciLshXB5Vk1gkVnYPxrkOGmeHIaP9B3GXFX8OKFY+j UE311qePXJEsP9rT114asPCL6+51y0wkqKd0kbsEnicQr0Rw3aTF1ehEIE4+rtRK SDHGmlQr1Vi8HtonlFG+fPQGkaoVIcsCWQIjwp7JC1ELYpX14g2gNY3cSSYCj4Kv CaJ+B0v34Xp/XcDb5qR8Efv33Xk= -----END CERTIFICATE----- doppler: cert: | -----BEGIN CERTIFICATE----- MIIEJTCCAg2gAwIBAgIQWRLU9fVC01iejTbyzp9SSTANBgkqhkiG9w0BAQsFADAY MRYwFAYDVQQDEw1sb2dncmVnYXRvckNBMB4XDTE3MDIxMDIzMjA0NVoXDTE5MDIx MDIzMjA0NVowEjEQMA4GA1UEAxMHZG9wcGxlcjCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBANq6Zv+ja9IRiMDh8DBTiA41O8wMKgAa0oNN4k5Ty5o0wGO7 OOosEC1jMAvKE7HKd8MvWojeKel7JEk4tQTLB2oitU5Kv5G6Ai84jjVEpL5F89Hn kTqANAD3hMgeVBV94KD2+ETr4J6LMvrV3fs/AEFef3O27QvyRKDjUufNT9LyAf0A rJlfhsHdTBx/YznO1rONdjJ1IewQtq/j0ymSEvLuJJPVntHHdIR/69mF7aeYf4IE ajmslmFNNGCag5tqIsDFICyTBVheLSxHsTgEkgirSwPmfNfwKdqs7zmdSHkVxa3J kzTmH/zAg6CpP3CfP0RMqxdsfD2oJmseQKkKW4sCAwEAAaNxMG8wDgYDVR0PAQH/ BAQDAgO4MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU ciEo4XTzXwzldlVCvnyDMjSYv6kwHwYDVR0jBBgwFoAULJLxpEYEjmTpVJj5fIv8 h2PjwJ8wDQYJKoZIhvcNAQELBQADggIBAF150pKlhMLknK8XWt/dUu0UHyF6MRyA cuoFIYRhnAxyb9K7+lRrkAPJ5kSG5c/fxRI4wj3ydI4ZfpHAGQGporJ3zdo1f/mD fE3riecVlZpZ8aQwNh3MZsZnpwUn9V/VeYwFdsvpKlR1hdQJCKxK88HpXrq4dJB1 BPLM62AvFkNouWVrn2O9YDSluk5tzJ8A5sm8TFbOjQX4T9ceOfPQiSGYLiTaBORc oFAzHNIT/ID0ONTrkt+ZSjYQJrPdyJheoSfRP8LLDM9hslsI+07xEHBces36T07d 0dlnFxrLxpiv+gB7UxCrnOW538Zxila8Z7CpDvafmMuwzYY2QmeeeekKKCf+xZAR BKGg94XteD/w3hbEtyjUqOmNHVClC64aRzKR2eELMkZZzUlOLHZz5lw2miXjcwZU 0TTpM/ZtgwKTjTZXw6MQJmDoaFuxRjY3z0eqbnrZZtfosSSlO6psQLlTMcXIy2M9 t/vPzinQY7NsUY4Ty7Uw65tPbUhpnz0d1VVvcxUEqbyTEEHiL5WnjXSfOwZoZt2Q 21SJiAUq6NjPDwdGtAKWWAREYIKxFg0KZf7vWlLBV7Kdulot32T4WIZVJ+Hv1jZt qhTTSxtYYAiUEY3ueJesXhARo+DT7w1pOSENlR0YhpNkLOkWKwoPwheqzdtSgx/m HOoF5Coq8Y3+ -----END CERTIFICATE----- key: | -----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEA2rpm/6Nr0hGIwOHwMFOIDjU7zAwqABrSg03iTlPLmjTAY7s4 6iwQLWMwC8oTscp3wy9aiN4p6XskSTi1BMsHaiK1Tkq/kboCLziONUSkvkXz0eeR OoA0APeEyB5UFX3goPb4ROvgnosy+tXd+z8AQV5/c7btC/JEoONS581P0vIB/QCs mV+Gwd1MHH9jOc7Ws412MnUh7BC2r+PTKZIS8u4kk9We0cd0hH/r2YXtp5h/ggRq OayWYU00YJqDm2oiwMUgLJMFWF4tLEexOASSCKtLA+Z81/Ap2qzvOZ1IeRXFrcmT NOYf/MCDoKk/cJ8/REyrF2x8Pagmax5AqQpbiwIDAQABAoIBAQCbV8GpE5aS9lMK siyVFe5OMO6MJ6N4uZQDH0B34rl6hraQ3jo4zhybL5PC+7zrC2HtZOdGx4o6wXNu 8XBWvB9C+O2NcjcGN3YvtVoCaQMcA7B7xpv1UXIdsa1DN47+SI1NpLmEsYWw9Cm7 zkK+musCgivAsg0+68xj+6845C8qH9hFEYxG4soBE2AVj0TWzFc6s3uPoLTZeEQV 1+ucEoUUMliFV49PDifeuwO8c+hHEXurYpWGY78xKjCm66C0H8QcYOnPh8vI3/AK 8ku/HDoc9KeobiujAvpqfBmWfW5XJYLkPhpOrZr3OaILNl7Jo7L3XWIjCdR4HDrs WyfWYuOhAoGBAOB6AFLBrrZlJmOtzlKHYCiP1Ho9NR7O9+AY6Q60/k6FFWnGOM5N cU70sdIa071UxH1Ilu5lKzE+oEhRSHDMgb6qYtODF8YpzADfjaHkQJSnvPU9dgvh Howy7KcK0odb5d1IkbKFAeTLbqi9ZDwWU+qE/AQoGO4PU0Sf7bi+d8fbAoGBAPlx vkKptbnfiWN8RlyrO1ZK3jk///NON6WATYTK1A59JqJOwkWVCwnUwogI8A9zKg73 +yvMiMzpNAxmSTFlOL7WaD/d0Q0pJkMvopksPgpMGRsIu3j+QzNaauHZ3ZZkVMZC BgFzvOhlUcg0du/kuloPXczKF1lZCR/D3PIPESIRAoGAO06gdTzszw3MZbuO7mkL 88uEZMN1HG2sOc37DUKuicpJjQetDHyTejvWG1+xH62cuEkMb3HVRo54RIMNM5gk k15q+9z/1ABJANYPkn0+vsfOebDCVoMk0f/GXJ/UXaTfB2bb76GKjYtd8kEPkXyI sUZvWx3I8GSmKFRkt1HDTc8CgYEAwCtRkVffSaAd3wfpyRCduQAarW5Rx+aVVio/ DjOYJMVj0xzr6+FDzMIdT+Ha13w4hamj1f1P0tVCJN9UOfqqOdNCIxnHKOVvtcjn 8is0bIhtuvcCPtdbfB+HQhGu9WK8MLTCnbHFciBEXgGVM4E505INCG0Uid/e+JrT B6R15ZECgYEAiGchj4kQFVtkZg1raBcP14gsSW6dRGroIYRcN2HC0qfcNeviaFWC BMs8X+svgJC8D5lI/Xov/Gdc7VXK/k50kWGChZDZK/O+a6TUyirYxBllB9LBmn46 pa2wmxyASvITto3jDCHpeyOJt+8Sq8XrHfPVWJkWcFbyj8bcrQXcVCQ= -----END RSA PRIVATE KEY----- metron: cert: | -----BEGIN CERTIFICATE----- MIIEJDCCAgygAwIBAgIQRSoVfjx0yvwbhBGomUWfezANBgkqhkiG9w0BAQsFADAY MRYwFAYDVQQDEw1sb2dncmVnYXRvckNBMB4XDTE3MDIxMDIzMjA0NloXDTE5MDIx MDIzMjA0NlowETEPMA0GA1UEAxMGbWV0cm9uMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEAy2HbU3xqYqGU16NAJQRJGAAMD4MtcXXNFAdwCN4pn/wrRKI9 JsiMgBMg7uiA8C6sB5NNIZ3VlO3y58BMG+Lc400N2MylpXCfrap+QNPnIR6ZB8yH apwOQqJ36G3bag0VQhRacFdyDgACsbxnswmw+z/PtjILDp4XmWOibdvm/bPDxHTP 2+jXbkyusaW7BPtNa+zG0i/T2ZC0K0kuMx/O4o65yWXuKmYlK9TUUWibzkDVtuyu QEcVK9No/beLDaMYMrKCuKfdxfK//HE/NhCXcx/n0AGrnSjD/rHv47KX4AeMUKfD 6/koem8TwCNwNNT63DENK9j/wkuZwZiIh4KGAwIDAQABo3EwbzAOBgNVHQ8BAf8E BAMCA7gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBQg JJ9Ag2xtyyZeO/NhfFSPQZcf9jAfBgNVHSMEGDAWgBQskvGkRgSOZOlUmPl8i/yH Y+PAnzANBgkqhkiG9w0BAQsFAAOCAgEAvc+T0iwzT7G8oYy+9IZpB6RfAF7ZjTBM 7J1Q7GAh8M7YgPldTwv+I7Jnyv1ogehnb0K8vhbad2S7OBljLdbsIe8UIxgcVSNP B/nW6d37EPxamj26aaFhvxaAL4HMb3lLKQRvyN7jM0upHhgv5NKsgpQp+WRgr76A 2pBUZlxtilG4an5gX/GB21e2Mv62Fx+W81VMGVAxIeh14XAK89+mXjZvTMPyFAYV HvohpSOzkp8nxyltOvxHqymPZNGPxe2AII6yJT+sqLmiCHCYZOqTBgKbSdblTYnx xae5QCpVrFBHfZVRARsYXMm0WZKWZZ3YTCqPxMx7oFDha6mY1PeJExg5amXK/arm 3lNS5LZysfwmyooucAoI29R6XvK07nyVnuLoZkVNtaqMrlNalwVtZEgLkJuy8gCV +G3zpkPpzxYzuWePt+ug1RGICzsaImNPpc3YhFCOXTRCzL/ElcTiYnPa94FKpwHS vafjBU2oXy0jLQkozQhD0y64fASXmbxp1EqfXDMhUN/IPTWZLWRsO8/cS4pcSheQ YmKA9xwJOZvDgM7shc124mjw5TKici4TUbpY0k/3WJlwAPxqXP3OWiv5tUWmNagu 2A8gc9W6NNin7COTgCcpMdp99XRP95TildxBsHRDrgE/F8gxGtlkLb5pohkPni5G nOHB7OPKG0w= -----END CERTIFICATE----- key: | -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAy2HbU3xqYqGU16NAJQRJGAAMD4MtcXXNFAdwCN4pn/wrRKI9 JsiMgBMg7uiA8C6sB5NNIZ3VlO3y58BMG+Lc400N2MylpXCfrap+QNPnIR6ZB8yH apwOQqJ36G3bag0VQhRacFdyDgACsbxnswmw+z/PtjILDp4XmWOibdvm/bPDxHTP 2+jXbkyusaW7BPtNa+zG0i/T2ZC0K0kuMx/O4o65yWXuKmYlK9TUUWibzkDVtuyu QEcVK9No/beLDaMYMrKCuKfdxfK//HE/NhCXcx/n0AGrnSjD/rHv47KX4AeMUKfD 6/koem8TwCNwNNT63DENK9j/wkuZwZiIh4KGAwIDAQABAoIBAAvtEhJkMkzUUskO Tp2dEbgxkIN8WrbThJIPGZe7h09VVygwJ0vV6L893+mCgsUSx42uKpC1E6gnB95l HVFpTTCa/RvgbDo2T3a8j6i3hE8h3zFg4fPzcLahlkxv3LTsTXnRfbgmuI5vm7jW ZnJOOC2TgVeauaFCzfl1qTmt8m6f+BhqpQ50kPk9Qkue+cWa8BR5sxX7IOpuThK2 doTygApvpRGt1hyTnuhvVc8gnfIFzS8TENrpysoBxP/xqtqCXefwpXP9nD5Z7zDZ INlZDvGNzagG+zLZ0iZi0nrHgjx1dD/otlO1r2FN+rWLcQ9GqYzHUFkWI/qE7lP/ 7BEM+GECgYEA+GQWuSmCuyhnECnz0QWvslaU+PuO+egF/pjO8NIBn5mKpDblyCdb svKTFMV+6gHxTNF5+d34Tr2jaTo7eTsj9+j+CjiZYM7kZRxQPGSjd66a+0bCQx16 d81HuIKf1U2wWd5TTmeX5/qCvECfcZt/W84py5hU3Ua6V+mGaHOrGFMCgYEA0ZzN 5zGobha34tFrV85aWT2XyIfPFrm0PkOi/hFyDaYqBV0D7RhxIjc+AGX7E3qoc5Z+ O9Acs2RboZbxDvIwwnldPvgoleGpMqeeVVJl+hbwOeMRfuR3rG/3yAatkkc4TqrB SqfienSCFy4aPKLP7/ZSlr/qYkFrOvzCP/zbZZECgYBQDOmp2O/x4057zhlutrdt 8StnpqLodVdhOtwOjo/JYNFmpO6e99g8rqKqIhAJ2IBssmHuHhRFRCai5gp+womP /v3IS39azLKcx2gwXnq0OohmDOLUgG6Up4rCsw5RzwzTmawda5NwRrLVerooAeYk ryeXHsvS2FV7uZ4Aka6FUwKBgQCieyr8iHioBYI7FtxfbvyH6n+qmOOFGSRHk4RX 70v6mpA+IhD2C5k+zZWJF4QdYFoNZ12onbRxtlx1EJ0BWelEBnGqaxCCxi6yrk3E k5+q0XcbWBFqzEyb5Rsr+Uk4d26FREWayjJ7e66Pq1P5JreKqeTxKAjWayFk0yL8 GNQ0kQKBgBALKyo8NHRJ+KvMwAGm49vIwaIgcq4yVhtzO0JoNuC60hwPrAWhJiGL yO6MJS7zcbCtzmJbPJRefOPg4Mp9Mr3B7nRzafqEX9lpKvUrJvPKhXZM215JZej8 ShcLxA/Cpsm0f7mZKGByBIInIQ8xesJAyl25xjfDDgh1VYa7dbLG -----END RSA PRIVATE KEY----- trafficcontroller: cert: | -----BEGIN CERTIFICATE----- MIIEMDCCAhigAwIBAgIRAPGFxcdjGPFKaz0GCLRvgEQwDQYJKoZIhvcNAQELBQAw GDEWMBQGA1UEAxMNbG9nZ3JlZ2F0b3JDQTAeFw0xNzAyMTAyMzIwNDVaFw0xOTAy MTAyMzIwNDVaMBwxGjAYBgNVBAMTEXRyYWZmaWNjb250cm9sbGVyMIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwL5w7niAM/v01u7hD5KYiiBwI/unxcUb 68f/vTlQYlE30RoW82/nuf2lAN4Hu/aXzNpT/PYYWrV/LmmglsneDUQCSr3OCv8S R9b6IlFhtGbKOqH+hJ5ReANAlhWfpLFokq+XKw8EN0Do4BCl1GjH2Xv2gQ3mn5yA CT91HYLDLaJAl5XLmUUZvNaEO0eyMGsDJdJbdVBwSfODwuoKzhB4RPyOE3WCQflJ L5Be/vqHmtqTI0dv6A21Vm5vxd+DA8t9BAq1Q5ZH6s6MaC2J5gzRYFN0IVBSGkEC jOKiHez7B4xL6s53pCF5YRnON6ILBGp2GeFAankajlop5FhRkZfzPwIDAQABo3Ew bzAOBgNVHQ8BAf8EBAMCA7gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC MB0GA1UdDgQWBBSce9TO1i5M/pHUtOexXdSHS/uNqzAfBgNVHSMEGDAWgBQskvGk RgSOZOlUmPl8i/yHY+PAnzANBgkqhkiG9w0BAQsFAAOCAgEAiSHgy0g5DFU/rlPX eiva6r+a1gHO/TSgd1anPqPkctHkl4264UKBBjIt18Fbf9dU0Icj+JEFDViLXUr/ KQc7r0+tDCJd/IS8QWX0z5jyvsx1lDxcVUWnddxqCC/xQ2d7n8eqEC34ywW+Vsr0 Eoq9boMOI1RnkBGI1ELbCK+3yDKo8jVUjsMmpzbBV44ydkhrsiDldLk4lsEByAD9 TdGVGXw7wEO8DiPSm6nj6UWNtIcM6rnttTV9KvjGIISeKLWz9+fd68S+1IpXw7VU afX4ELB1rTwnG7TTtGyQmRL2O4JZWwP8tu3IcnmxiwxB70PkIntxnNC5Greth4uH 7n2wkxvxhi+5v+njhtSNTgHGIq7EIN+8ztHlgx1Ol0nHpBCVfvMuc3aY4+jg3qe7 m55Vh3TaDrxQqXuEb2j6mu9Lk+B7Rl5WBjvJVzxFUL8NmABmEL+X8GfhMcwldPo8 qO8BZtSX/9UozkCItxuq1EsxiWNDKSDEF2XGxJP8U6uDk96rSnY4TuJNKjnF9SUm 7nrcQzrezF8OqQhZIomzYe3tVqCTI34p+iYTsrH8xLIPuiSaePpLsJ/747f2bHWR i8ESZ5P+ALVR4fOJiNZJHwLhs4umVzCaBOiAF+65d29/q9Cg7dX9l8rOhznz0q7d KQXFegrpMEzZdpvlJjkvr5dbkys= -----END CERTIFICATE----- key: | -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAwL5w7niAM/v01u7hD5KYiiBwI/unxcUb68f/vTlQYlE30RoW 82/nuf2lAN4Hu/aXzNpT/PYYWrV/LmmglsneDUQCSr3OCv8SR9b6IlFhtGbKOqH+ hJ5ReANAlhWfpLFokq+XKw8EN0Do4BCl1GjH2Xv2gQ3mn5yACT91HYLDLaJAl5XL mUUZvNaEO0eyMGsDJdJbdVBwSfODwuoKzhB4RPyOE3WCQflJL5Be/vqHmtqTI0dv 6A21Vm5vxd+DA8t9BAq1Q5ZH6s6MaC2J5gzRYFN0IVBSGkECjOKiHez7B4xL6s53 pCF5YRnON6ILBGp2GeFAankajlop5FhRkZfzPwIDAQABAoIBABrqfVrP+RdJWCer tEI4dpTTctWTjxpPLFcA1vXVyyPvs5u/yPS16+ZNRX2Zg/r7tLcmxhPNShlgvyH8 HjDwf9HabXeCigN/G05s9wFT3BEVSahmduSON1JLIfnTize0jqXtX27j6fLNXbfs mzvOZho49XOQPWSMtlSUSAaW/Cqi/9RB1AQNZcZTRFEyiyhMiQKZgA7ekAatsMoh fPMIJuvSgAqG6PnquT/gRJTSWqm6vyN2nY23cVkmXRU/DuMsYEfj5lZH1dDxG+dX oWi/uvsePSZz89udFm399O2tWoe3BWGi6MZ83wFD8jNE5txIjUPsGO+vofdIhZtz oh3EFAECgYEA4tjF6y+YOjk2sv6TLxyhVl9bql5DazFaFh2L9hO90ztPTaYgTop/ 9EYJZpRmaxWV4wNCedyaXbn5iQqM8g2O5f7pxWW943X1+SYjuI2YIaWIBNdM0HJ3 m/rKVzP/9iolD0sR3FBAXpmLAZCL5IEuUn9kPEd37yjXxESQhG5r4skCgYEA2YOw UQgRvr0bC0tITmkOHSKW11hungMuQR6XK20zfDMJHZnkxLNXrTspwTmZ8apDi3nR BD7HghywQF1xx4A3H2d5J4afqZTgRZhRLm0C517J3FxVHsIqdl9mFcbz80S+lzwl 8BmKIDPIb864VCE8xF+Y2i9L3VQ1gULg7qoo4ccCgYB0iI2sEwgtqOSbsUHlKt0K 5PPPIpuZvoGb6NPUtzGGCOrlZdkk3+t5jl0X8FZo3m7gbvVAav519armJqBfXG2z Y2+uM2UIK7oPovMoxLyJVGL6savJTXR6kaxOfe0ZBW+CWrszJZrbvh71z869tUsZ oE3a1ZAcMSwerGZdUehkWQKBgDghU46Vln6yLhhsBOy3D31VP7eyilkcWQNU8Y2z UGXshZ2t6OsZnLaHXe8O/jruxR9pABcoXDOnU5RIiOQCojbobMtWYj1Qvc83zzs7 xlQOkejbqtuVH4AMfjuAa9OLGePNEb0z2gEVW9P+dHLBYP0L7lXffqRO5r/EkmcE YihhAoGARgQ8aC2j2SEwl8v2cpv5zcA/lcdZiP2Vcz954bZOsHexxi7Nk0iWR3iL WapnbSaoNEsXer59rWea/sCGIpYv6RHLEx/ssO7H53l18+yxwX+Er1AuZaa/S69r PsgZJuOL9WAqdDsW7TyDQTjUzj9a5stNqPcBn2PMJgy56xUKq/4= -----END RSA PRIVATE KEY----- syslogdrainbinder: cert: | -----BEGIN CERTIFICATE----- MIIExzCCA6+gAwIBAgIJAOPFFRMyK2dVMA0GCSqGSIb3DQEBBQUAMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzAeFw0xNzAyMTUyMjM1MzlaFw0xODAyMTUyMjM1MzlaMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOPQlCJnidk 8XLD0TysGURSJ35BBCaKPGULVEWklO5nzP68J21nY/1oUEdnA1d5cJh27U2D6gZ6 PEN7RsZTmpygFOQQaxbc8IKx86ackI6HCq3WwiDA92IJMMvedPrGWUNoG6h/qAwi RCo3TdV61zfy0mqBdxa1X0algUQOZCUHk6R+DRbCThXQyZW7MNyfnNb1ubw03eHp eSTxMvYm0k/+EbYtheY1h/MJklidEEwTw5ygw8KcxowcCFjdJjaqVgPhNZCNTuA6 GUrIQJ9hB/KHpHmmiege3peq5RQZg/EfoDUtRbVd5V1z7t+2O+IgBTEKBY5yzr4S RxK9tdHEn+MCAwEAAaOCAQYwggECMB0GA1UdDgQWBBRRUvkBTZ+jf0ao85VurNMQ v2QJdTCB0gYDVR0jBIHKMIHHgBRRUvkBTZ+jf0ao85VurNMQv2QJdaGBo6SBoDCB nTEeMBwGA1UEAxQVKi5zZXJ2aWNlLmNmLmludGVybmFsMQswCQYDVQQGEwJVUzER MA8GA1UECBMITmV3LVlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMRAwDgYDVQQKEwdQ aXZvdGFsMRAwDgYDVQQLEwdQQ0YgRGV2MSQwIgYJKoZIhvcNAQkBFhVwY2ZkZXYt ZW5nQHBpdm90YWwuaW+CCQDjxRUTMitnVTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 DQEBBQUAA4IBAQBk19J3yfMb0DEC/BBDlHUyGvvsLr0PVbZGtYT7qxHkqOQBFz1k q65aeNuT8D0GSMy6gfF64cRPp3A7a8NfeYsSoynufMHMaMKEzlYjSyNGwDcxyRwv eQ7w4QeX9EnRCBf/JQdC9bIIs9IoJAgNHhEZHnzdnt76NX1hJ+w8SVTgi5zdQknr v+wroKbStKy2R5qxnW1bPgt6AtMoE3M/ZUj+DNQvU3wEcTasWuxvDUOhZfoOM0Rd UxpHKQp+6PPugE59i/xg/Vm53FrAQ6+4Tn6w5jjtWBszH8OxFkyD+mKhKsh/DkfV kXvnbnHRmaEsQBbnWkhygDws3S1YT8/vTZBw -----END CERTIFICATE----- key: | -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAw49CUImeJ2TxcsPRPKwZRFInfkEEJoo8ZQtURaSU7mfM/rwn bWdj/WhQR2cDV3lwmHbtTYPqBno8Q3tGxlOanKAU5BBrFtzwgrHzppyQjocKrdbC IMD3Ygkwy950+sZZQ2gbqH+oDCJEKjdN1XrXN/LSaoF3FrVfRqWBRA5kJQeTpH4N FsJOFdDJlbsw3J+c1vW5vDTd4el5JPEy9ibST/4Rti2F5jWH8wmSWJ0QTBPDnKDD wpzGjBwIWN0mNqpWA+E1kI1O4DoZSshAn2EH8oekeaaJ6B7el6rlFBmD8R+gNS1F tV3lXXPu37Y74iAFMQoFjnLOvhJHEr210cSf4wIDAQABAoIBAQCTF1gb18cbfnOV jO/+oLvIhbqq3iBPFL7kiabzUx2qTG0GVWOaiJ/O5P0tF7CNxQwJwbowCb6m7J4T a9AKMKwkjsvn1umVos1MoKjRcwXQDobbxqLxm/L2zE7lqQd38GUHrHDRRmOR7Nw0 nLBwmBr1PDFEZui6LeXh727RT7nHlx6yo6cIYUrQBWaFSZJmfPD2pCMLRvEEY/0v yuv6NwuRVdO/P7R+pLDXDDbOktOiFvy9QUz4KtY2ZgZHobHZ9LJlyqFiC7wFQkMs la9vBniARgE1vX9D1QJJZ01ilivjiRDHaEq7EnZ9kRoO/ln3Yqlhr5OjAeQMFlMR AkX9h2VxAoGBAPnfruRdP5JTdXmun4IA0Nn3a3ZG7dNkUIl/yfhTKCD8ITGq5MXV aNSkOTVurkhrA38RuM6RQPypbjGRYdQrRMeKv6IrTC+sb7BhgcYe32370K8Y3TTX hgB24larb8jPot6f7nvkTbJJpwmHE8cXm7Gkmr6n340GPJzfmJke+H3fAoGBAMha rS+fCIyI3YwxmcyrA7nEKmAg2tTLiJ7xIY8i/ADwedqAnV8oAfScMw7IAF1EBkAt z2xfQhm1/pIqr1GcLxOgqvbixXfmM2qsLS/Zb/T6aOJ5xejsI3d21CIg5LwxF/EO 1hm5ereMdDTFw914HcO2Wap0Kyqg8MSd1GxgIhZ9AoGAOOqKm9nhsSLxj1YHX0Vw TTXedIKTiaM/9RH2n2nRqjHEHdwfYDDMQCNoJJOhfz1g/oC659KOSv8M6p2C+yEf +ZPRMs9J+1H73uFW/hnqKtNBJaE0QeUV0OVDiRpjzAn/v1YOrInEaOf99F2gU6k8 /anQ1bzHXwgcpl8IE1jKoWECgYAFVORm8AR6OOosYOWG3MYsm1vFUxp/ryrjj+ck t/mczMlxVxrY/WeP6tgw/IGF+dlwu8dZSu+nX4B2w0wHD/DwxMXH7CD1H9sea5aI P3ELQ96mqDbsC9ylwTPD9LwhheztLUflR1pMqCAvh1O/AQNJwgCA2LaNW9sMYGbW u3gswQKBgGsjcgS8l6cAYXOncwN6ROyosL6xkvc8zzUSH/KdPcXbAJZm/hQYeAyS QFAzUdyCXnokknYbLcsNmVqO+FAXQ+S2lwaBxS0uHWc7oc0KYaNPdFHSW0PCGj9u rvaEn/skAHkQTbLPPoPmuOs5qwWgYkMB6AHcSeCmBQokX7Zn7nfR -----END RSA PRIVATE KEY----- loggregator_endpoint: shared_secret: loggregator-secret metron_endpoint: shared_secret: loggregator-secret uaa: url: "https://uaa.local.pcfdev.io" catalina_opts: -Xms200m -Xmx200m -Xss1m -XX:MetaspaceSize=144m -XX:MaxMetaspaceSize=144m port: 8085 host: 127.0.0.1 tls_port: 8443 ssl: port: 8443 host: 127.0.0.1 ca_cert: | -----BEGIN CERTIFICATE----- MIIExzCCA6+gAwIBAgIJAOPFFRMyK2dVMA0GCSqGSIb3DQEBBQUAMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzAeFw0xNzAyMTUyMjM1MzlaFw0xODAyMTUyMjM1MzlaMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOPQlCJnidk 8XLD0TysGURSJ35BBCaKPGULVEWklO5nzP68J21nY/1oUEdnA1d5cJh27U2D6gZ6 PEN7RsZTmpygFOQQaxbc8IKx86ackI6HCq3WwiDA92IJMMvedPrGWUNoG6h/qAwi RCo3TdV61zfy0mqBdxa1X0algUQOZCUHk6R+DRbCThXQyZW7MNyfnNb1ubw03eHp eSTxMvYm0k/+EbYtheY1h/MJklidEEwTw5ygw8KcxowcCFjdJjaqVgPhNZCNTuA6 GUrIQJ9hB/KHpHmmiege3peq5RQZg/EfoDUtRbVd5V1z7t+2O+IgBTEKBY5yzr4S RxK9tdHEn+MCAwEAAaOCAQYwggECMB0GA1UdDgQWBBRRUvkBTZ+jf0ao85VurNMQ v2QJdTCB0gYDVR0jBIHKMIHHgBRRUvkBTZ+jf0ao85VurNMQv2QJdaGBo6SBoDCB nTEeMBwGA1UEAxQVKi5zZXJ2aWNlLmNmLmludGVybmFsMQswCQYDVQQGEwJVUzER MA8GA1UECBMITmV3LVlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMRAwDgYDVQQKEwdQ aXZvdGFsMRAwDgYDVQQLEwdQQ0YgRGV2MSQwIgYJKoZIhvcNAQkBFhVwY2ZkZXYt ZW5nQHBpdm90YWwuaW+CCQDjxRUTMitnVTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 DQEBBQUAA4IBAQBk19J3yfMb0DEC/BBDlHUyGvvsLr0PVbZGtYT7qxHkqOQBFz1k q65aeNuT8D0GSMy6gfF64cRPp3A7a8NfeYsSoynufMHMaMKEzlYjSyNGwDcxyRwv eQ7w4QeX9EnRCBf/JQdC9bIIs9IoJAgNHhEZHnzdnt76NX1hJ+w8SVTgi5zdQknr v+wroKbStKy2R5qxnW1bPgt6AtMoE3M/ZUj+DNQvU3wEcTasWuxvDUOhZfoOM0Rd UxpHKQp+6PPugE59i/xg/Vm53FrAQ6+4Tn6w5jjtWBszH8OxFkyD+mKhKsh/DkfV kXvnbnHRmaEsQBbnWkhygDws3S1YT8/vTZBw -----END CERTIFICATE----- sslCertificate: | -----BEGIN CERTIFICATE----- MIIExzCCA6+gAwIBAgIJAOPFFRMyK2dVMA0GCSqGSIb3DQEBBQUAMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzAeFw0xNzAyMTUyMjM1MzlaFw0xODAyMTUyMjM1MzlaMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOPQlCJnidk 8XLD0TysGURSJ35BBCaKPGULVEWklO5nzP68J21nY/1oUEdnA1d5cJh27U2D6gZ6 PEN7RsZTmpygFOQQaxbc8IKx86ackI6HCq3WwiDA92IJMMvedPrGWUNoG6h/qAwi RCo3TdV61zfy0mqBdxa1X0algUQOZCUHk6R+DRbCThXQyZW7MNyfnNb1ubw03eHp eSTxMvYm0k/+EbYtheY1h/MJklidEEwTw5ygw8KcxowcCFjdJjaqVgPhNZCNTuA6 GUrIQJ9hB/KHpHmmiege3peq5RQZg/EfoDUtRbVd5V1z7t+2O+IgBTEKBY5yzr4S RxK9tdHEn+MCAwEAAaOCAQYwggECMB0GA1UdDgQWBBRRUvkBTZ+jf0ao85VurNMQ v2QJdTCB0gYDVR0jBIHKMIHHgBRRUvkBTZ+jf0ao85VurNMQv2QJdaGBo6SBoDCB nTEeMBwGA1UEAxQVKi5zZXJ2aWNlLmNmLmludGVybmFsMQswCQYDVQQGEwJVUzER MA8GA1UECBMITmV3LVlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMRAwDgYDVQQKEwdQ aXZvdGFsMRAwDgYDVQQLEwdQQ0YgRGV2MSQwIgYJKoZIhvcNAQkBFhVwY2ZkZXYt ZW5nQHBpdm90YWwuaW+CCQDjxRUTMitnVTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 DQEBBQUAA4IBAQBk19J3yfMb0DEC/BBDlHUyGvvsLr0PVbZGtYT7qxHkqOQBFz1k q65aeNuT8D0GSMy6gfF64cRPp3A7a8NfeYsSoynufMHMaMKEzlYjSyNGwDcxyRwv eQ7w4QeX9EnRCBf/JQdC9bIIs9IoJAgNHhEZHnzdnt76NX1hJ+w8SVTgi5zdQknr v+wroKbStKy2R5qxnW1bPgt6AtMoE3M/ZUj+DNQvU3wEcTasWuxvDUOhZfoOM0Rd UxpHKQp+6PPugE59i/xg/Vm53FrAQ6+4Tn6w5jjtWBszH8OxFkyD+mKhKsh/DkfV kXvnbnHRmaEsQBbnWkhygDws3S1YT8/vTZBw -----END CERTIFICATE----- sslPrivateKey: | -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAw49CUImeJ2TxcsPRPKwZRFInfkEEJoo8ZQtURaSU7mfM/rwn bWdj/WhQR2cDV3lwmHbtTYPqBno8Q3tGxlOanKAU5BBrFtzwgrHzppyQjocKrdbC IMD3Ygkwy950+sZZQ2gbqH+oDCJEKjdN1XrXN/LSaoF3FrVfRqWBRA5kJQeTpH4N FsJOFdDJlbsw3J+c1vW5vDTd4el5JPEy9ibST/4Rti2F5jWH8wmSWJ0QTBPDnKDD wpzGjBwIWN0mNqpWA+E1kI1O4DoZSshAn2EH8oekeaaJ6B7el6rlFBmD8R+gNS1F tV3lXXPu37Y74iAFMQoFjnLOvhJHEr210cSf4wIDAQABAoIBAQCTF1gb18cbfnOV jO/+oLvIhbqq3iBPFL7kiabzUx2qTG0GVWOaiJ/O5P0tF7CNxQwJwbowCb6m7J4T a9AKMKwkjsvn1umVos1MoKjRcwXQDobbxqLxm/L2zE7lqQd38GUHrHDRRmOR7Nw0 nLBwmBr1PDFEZui6LeXh727RT7nHlx6yo6cIYUrQBWaFSZJmfPD2pCMLRvEEY/0v yuv6NwuRVdO/P7R+pLDXDDbOktOiFvy9QUz4KtY2ZgZHobHZ9LJlyqFiC7wFQkMs la9vBniARgE1vX9D1QJJZ01ilivjiRDHaEq7EnZ9kRoO/ln3Yqlhr5OjAeQMFlMR AkX9h2VxAoGBAPnfruRdP5JTdXmun4IA0Nn3a3ZG7dNkUIl/yfhTKCD8ITGq5MXV aNSkOTVurkhrA38RuM6RQPypbjGRYdQrRMeKv6IrTC+sb7BhgcYe32370K8Y3TTX hgB24larb8jPot6f7nvkTbJJpwmHE8cXm7Gkmr6n340GPJzfmJke+H3fAoGBAMha rS+fCIyI3YwxmcyrA7nEKmAg2tTLiJ7xIY8i/ADwedqAnV8oAfScMw7IAF1EBkAt z2xfQhm1/pIqr1GcLxOgqvbixXfmM2qsLS/Zb/T6aOJ5xejsI3d21CIg5LwxF/EO 1hm5ereMdDTFw914HcO2Wap0Kyqg8MSd1GxgIhZ9AoGAOOqKm9nhsSLxj1YHX0Vw TTXedIKTiaM/9RH2n2nRqjHEHdwfYDDMQCNoJJOhfz1g/oC659KOSv8M6p2C+yEf +ZPRMs9J+1H73uFW/hnqKtNBJaE0QeUV0OVDiRpjzAn/v1YOrInEaOf99F2gU6k8 /anQ1bzHXwgcpl8IE1jKoWECgYAFVORm8AR6OOosYOWG3MYsm1vFUxp/ryrjj+ck t/mczMlxVxrY/WeP6tgw/IGF+dlwu8dZSu+nX4B2w0wHD/DwxMXH7CD1H9sea5aI P3ELQ96mqDbsC9ylwTPD9LwhheztLUflR1pMqCAvh1O/AQNJwgCA2LaNW9sMYGbW u3gswQKBgGsjcgS8l6cAYXOncwN6ROyosL6xkvc8zzUSH/KdPcXbAJZm/hQYeAyS QFAzUdyCXnokknYbLcsNmVqO+FAXQ+S2lwaBxS0uHWc7oc0KYaNPdFHSW0PCGj9u rvaEn/skAHkQTbLPPoPmuOs5qwWgYkMB6AHcSeCmBQokX7Zn7nfR -----END RSA PRIVATE KEY----- proxy_ips_regex: ".*" user: authorities: - openid - scim.me - cloud_controller.read - cloud_controller.write - cloud_controller_service_permissions.read - password.write - uaa.user - approvals.me - oauth.approvals - notification_preferences.read - notification_preferences.write - profile - roles - user_attributes - uaa.offline_token clients: cc_routing: authorities: routing.router_groups.read authorized-grant-types: client_credentials secret: cc-routing-secret cc-service-dashboards: authorities: clients.admin,clients.read,clients.write authorized-grant-types: client_credentials override: true scope: cloud_controller.read,cloud_controller.write,cloud_controller_service_permissions.read,openid secret: cc-broker-secret cf: access-token-validity: 600 authorities: uaa.none authorized-grant-types: password,refresh_token override: true secret: '' refresh-token-validity: 2592000 scope: cloud_controller.admin,cloud_controller.admin_read_only,cloud_controller.global_auditor,cloud_controller.read,cloud_controller.write,doppler.firehose,network.admin,openid,password.write,routing.router_groups.read,routing.router_groups.write,scim.read,scim.write,uaa.user,network.admin,network.write cloud_controller_username_lookup: authorities: scim.userids authorized-grant-types: client_credentials secret: cloud-controller-username-lookup-secret doppler: authorities: uaa.resource secret: loggregator-secret authorized-grant-types: client_credentials scope: uaa.none override: true gorouter: authorities: clients.admin,clients.read,clients.write,routing.routes.read,routing.routes.write authorized-grant-types: client_credentials,refresh_token scope: cloud_controller_service_permissions.read,openid secret: gorouter-secret login: authorities: clients.read,critical_notifications.write,emails.write,notifications.write,oauth.login,password.write,scim.userids,scim.write authorized-grant-types: client_credentials,refresh_token autoapprove: true override: true redirect-uri: "https://login.local.pcfdev.io" scope: oauth.approvals,openid secret: login-secret notifications: authorities: cloud_controller.admin,critical_notifications.write,emails.write,notifications.write,scim.read authorized-grant-types: client_credentials secret: notifications-secret ssh-proxy: authorized-grant-types: authorization_code autoapprove: true override: true redirect-uri: "https://uaa.local.pcfdev.io/login" scope: cloud_controller.admin,cloud_controller.read,cloud_controller.write,openid secret: ssh-proxy-secret tcp_emitter: access-token-validity: 1209600 authorities: routing.router_groups.read,routing.routes.read,routing.routes.write authorized-grant-types: client_credentials,refresh_token override: true scope: routing.router_groups.read,routing.routes.read,routing.routes.write secret: tcp-emitter-secret tcp_router: access-token-validity: 1209600 authorities: routing.router_groups.read,routing.routes.read authorized-grant-types: client_credentials,refresh_token override: true scope: routing.router_groups.read,routing.routes.read secret: tcp-router-secret network-policy: authorities: uaa.resource,cloud_controller.admin_read_only authorized-grant-types: client_credentials secret: network-policy-secret admin: client_secret: admin-client-secret cc: client_secret: cc-client-secret scim: user: override: true users: - name: admin password: admin groups: - clients.read - clients.write - cloud_controller.admin - cloud_controller.user - doppler.firehose - openid - routing.router_groups.read - routing.router_groups.write - scim.read - scim.write - network.admin - network.write require_https: true jwt: policy: active_key_id: key-1 keys: key-1: signingKey: | -----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQDHFr+KICms+tuT1OXJwhCUmR2dKVy7psa8xzElSyzqx7oJyfJ1 JZyOzToj9T5SfTIq396agbHJWVfYphNahvZ/7uMXqHxf+ZH9BL1gk9Y6kCnbM5R6 0gfwjyW1/dQPjOzn9N394zd2FJoFHwdq9Qs0wBugspULZVNRxq7veq/fzwIDAQAB AoGBAJ8dRTQFhIllbHx4GLbpTQsWXJ6w4hZvskJKCLM/o8R4n+0W45pQ1xEiYKdA Z/DRcnjltylRImBD8XuLL8iYOQSZXNMb1h3g5/UGbUXLmCgQLOUUlnYt34QOQm+0 KvUqfMSFBbKMsYBAoQmNdTHBaz3dZa8ON9hh/f5TT8u0OWNRAkEA5opzsIXv+52J duc1VGyX3SwlxiE2dStW8wZqGiuLH142n6MKnkLU4ctNLiclw6BZePXFZYIK+AkE xQ+k16je5QJBAN0TIKMPWIbbHVr5rkdUqOyezlFFWYOwnMmw/BKa1d3zp54VP/P8 +5aQ2d4sMoKEOfdWH7UqMe3FszfYFvSu5KMCQFMYeFaaEEP7Jn8rGzfQ5HQd44ek lQJqmq6CE2BXbY/i34FuvPcKU70HEEygY6Y9d8J3o6zQ0K9SYNu+pcXt4lkCQA3h jJQQe5uEGJTExqed7jllQ0khFJzLMx0K6tj0NeeIzAaGCQz13oo2sCdeGRHO4aDh HH6Qlq/6UOV5wP8+GAcCQFgRCcB+hrje8hfEEefHcFpyKH+5g1Eu1k0mLrxK2zd+ 4SlotYRHgPCEubokb2S1zfZDWIXW3HmggnGgM949TlY= -----END RSA PRIVATE KEY----- zones: internal: hostnames: - uaa.service.cf.internal route_registrar: routes: - name: policy-server port: 4002 registration_interval: 20s uris: - "api.local.pcfdev.io/networking" - name: doppler port: 8081 registration_interval: 20s uris: - doppler.local.pcfdev.io - name: cf-mysql-broker port: 19284 registration_interval: 20s uris: - mysql-broker.local.pcfdev.io - name: loggregator port: 8084 registration_interval: 20s uris: - loggregator.local.pcfdev.io - name: api port: 9022 registration_interval: 20s uris: - api.local.pcfdev.io - name: uaa port: 8085 registration_interval: 20s uris: - "uaa.local.pcfdev.io" - "*.uaa.local.pcfdev.io" - "login.local.pcfdev.io" - "*.login.local.pcfdev.io" - name: blobstore port: 8086 registration_interval: 20s uris: - blobstore.local.pcfdev.io - name: localbroker port: 8999 registration_interval: 20s tags: component: localbroker uris: - localbroker.local.pcfdev.io uaadb: address: 127.0.0.1 databases: - {name: uaadb, tag: uaa} db_scheme: mysql port: 3306 roles: - {name: uaaadmin, password: admin, tag: admin} app_ssh: host_key_fingerprint: a6:d1:08:0b:b0:cb:9b:5f:c4:ba:44:2a:97:26:19:8a cc: default_app_disk_in_mb: 512 default_app_memory: 256 default_to_diego_backend: true diego: stager_url: http://stager.service.cf.internal:8890 srv_api_uri: http://api.local.pcfdev.io bulk_api_password: bulk-api-password internal_api_password: internal-api-password nginx: ip: 127.0.0.1 db_encryption_key: db-encryption-key db_logging_level: info quota_definitions: default: memory_limit: 102400 non_basic_services_allowed: true total_routes: 1000 total_services: -1 security_group_definitions: - name: public_networks rules: - {destination: 0.0.0.0-9.255.255.255, protocol: all} - {destination: 11.0.0.0-169.253.255.255, protocol: all} - {destination: 169.255.0.0-172.15.255.255, protocol: all} - {destination: 172.32.0.0-192.167.255.255, protocol: all} - {destination: 192.169.0.0-255.255.255.255, protocol: all} - name: dns rules: - {destination: 0.0.0.0/0, ports: '53', protocol: tcp} - {destination: 0.0.0.0/0, ports: '53', protocol: udp} - name: all_pcfdev rules: - {destination: 0.0.0.0/0, protocol: all} staging_upload_user: staging-user staging_upload_password: staging-pass default_running_security_groups: [public_networks, dns, all_pcfdev] default_staging_security_groups: [public_networks, dns, all_pcfdev] external_protocol: http install_buildpacks: - {name: java_buildpack, package: java-offline-buildpack} - {name: ruby_buildpack, package: ruby-buildpack} - {name: nodejs_buildpack, package: nodejs-buildpack} - {name: go_buildpack, package: go-buildpack} - {name: python_buildpack, package: python-buildpack} - {name: php_buildpack, package: php-buildpack} - {name: staticfile_buildpack, package: staticfile-buildpack} - {name: binary_buildpack, package: binary-buildpack} buildpacks: blobstore_type: webdav webdav_config: ca_cert: "" username: admin password: admin public_endpoint: http://blobstore.local.pcfdev.io private_endpoint: https://blobstore.service.cf.internal:4043 droplets: blobstore_type: webdav webdav_config: ca_cert: "" username: admin password: admin public_endpoint: http://blobstore.local.pcfdev.io private_endpoint: https://blobstore.service.cf.internal:4043 packages: blobstore_type: webdav webdav_config: ca_cert: "" username: admin password: admin public_endpoint: http://blobstore.local.pcfdev.io private_endpoint: https://blobstore.service.cf.internal:4043 resource_pool: blobstore_type: webdav webdav_config: ca_cert: "" username: admin password: admin public_endpoint: http://blobstore.local.pcfdev.io private_endpoint: https://blobstore.service.cf.internal:4043 volume_services_enabled: true mutual_tls: ca_cert: | -----BEGIN CERTIFICATE----- MIIExzCCA6+gAwIBAgIJAOPFFRMyK2dVMA0GCSqGSIb3DQEBBQUAMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzAeFw0xNzAyMTUyMjM1MzlaFw0xODAyMTUyMjM1MzlaMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOPQlCJnidk 8XLD0TysGURSJ35BBCaKPGULVEWklO5nzP68J21nY/1oUEdnA1d5cJh27U2D6gZ6 PEN7RsZTmpygFOQQaxbc8IKx86ackI6HCq3WwiDA92IJMMvedPrGWUNoG6h/qAwi RCo3TdV61zfy0mqBdxa1X0algUQOZCUHk6R+DRbCThXQyZW7MNyfnNb1ubw03eHp eSTxMvYm0k/+EbYtheY1h/MJklidEEwTw5ygw8KcxowcCFjdJjaqVgPhNZCNTuA6 GUrIQJ9hB/KHpHmmiege3peq5RQZg/EfoDUtRbVd5V1z7t+2O+IgBTEKBY5yzr4S RxK9tdHEn+MCAwEAAaOCAQYwggECMB0GA1UdDgQWBBRRUvkBTZ+jf0ao85VurNMQ v2QJdTCB0gYDVR0jBIHKMIHHgBRRUvkBTZ+jf0ao85VurNMQv2QJdaGBo6SBoDCB nTEeMBwGA1UEAxQVKi5zZXJ2aWNlLmNmLmludGVybmFsMQswCQYDVQQGEwJVUzER MA8GA1UECBMITmV3LVlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMRAwDgYDVQQKEwdQ aXZvdGFsMRAwDgYDVQQLEwdQQ0YgRGV2MSQwIgYJKoZIhvcNAQkBFhVwY2ZkZXYt ZW5nQHBpdm90YWwuaW+CCQDjxRUTMitnVTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 DQEBBQUAA4IBAQBk19J3yfMb0DEC/BBDlHUyGvvsLr0PVbZGtYT7qxHkqOQBFz1k q65aeNuT8D0GSMy6gfF64cRPp3A7a8NfeYsSoynufMHMaMKEzlYjSyNGwDcxyRwv eQ7w4QeX9EnRCBf/JQdC9bIIs9IoJAgNHhEZHnzdnt76NX1hJ+w8SVTgi5zdQknr v+wroKbStKy2R5qxnW1bPgt6AtMoE3M/ZUj+DNQvU3wEcTasWuxvDUOhZfoOM0Rd UxpHKQp+6PPugE59i/xg/Vm53FrAQ6+4Tn6w5jjtWBszH8OxFkyD+mKhKsh/DkfV kXvnbnHRmaEsQBbnWkhygDws3S1YT8/vTZBw -----END CERTIFICATE----- public_cert: | -----BEGIN CERTIFICATE----- MIIExzCCA6+gAwIBAgIJAOPFFRMyK2dVMA0GCSqGSIb3DQEBBQUAMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzAeFw0xNzAyMTUyMjM1MzlaFw0xODAyMTUyMjM1MzlaMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOPQlCJnidk 8XLD0TysGURSJ35BBCaKPGULVEWklO5nzP68J21nY/1oUEdnA1d5cJh27U2D6gZ6 PEN7RsZTmpygFOQQaxbc8IKx86ackI6HCq3WwiDA92IJMMvedPrGWUNoG6h/qAwi RCo3TdV61zfy0mqBdxa1X0algUQOZCUHk6R+DRbCThXQyZW7MNyfnNb1ubw03eHp eSTxMvYm0k/+EbYtheY1h/MJklidEEwTw5ygw8KcxowcCFjdJjaqVgPhNZCNTuA6 GUrIQJ9hB/KHpHmmiege3peq5RQZg/EfoDUtRbVd5V1z7t+2O+IgBTEKBY5yzr4S RxK9tdHEn+MCAwEAAaOCAQYwggECMB0GA1UdDgQWBBRRUvkBTZ+jf0ao85VurNMQ v2QJdTCB0gYDVR0jBIHKMIHHgBRRUvkBTZ+jf0ao85VurNMQv2QJdaGBo6SBoDCB nTEeMBwGA1UEAxQVKi5zZXJ2aWNlLmNmLmludGVybmFsMQswCQYDVQQGEwJVUzER MA8GA1UECBMITmV3LVlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMRAwDgYDVQQKEwdQ aXZvdGFsMRAwDgYDVQQLEwdQQ0YgRGV2MSQwIgYJKoZIhvcNAQkBFhVwY2ZkZXYt ZW5nQHBpdm90YWwuaW+CCQDjxRUTMitnVTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 DQEBBQUAA4IBAQBk19J3yfMb0DEC/BBDlHUyGvvsLr0PVbZGtYT7qxHkqOQBFz1k q65aeNuT8D0GSMy6gfF64cRPp3A7a8NfeYsSoynufMHMaMKEzlYjSyNGwDcxyRwv eQ7w4QeX9EnRCBf/JQdC9bIIs9IoJAgNHhEZHnzdnt76NX1hJ+w8SVTgi5zdQknr v+wroKbStKy2R5qxnW1bPgt6AtMoE3M/ZUj+DNQvU3wEcTasWuxvDUOhZfoOM0Rd UxpHKQp+6PPugE59i/xg/Vm53FrAQ6+4Tn6w5jjtWBszH8OxFkyD+mKhKsh/DkfV kXvnbnHRmaEsQBbnWkhygDws3S1YT8/vTZBw -----END CERTIFICATE----- private_key: | -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAw49CUImeJ2TxcsPRPKwZRFInfkEEJoo8ZQtURaSU7mfM/rwn bWdj/WhQR2cDV3lwmHbtTYPqBno8Q3tGxlOanKAU5BBrFtzwgrHzppyQjocKrdbC IMD3Ygkwy950+sZZQ2gbqH+oDCJEKjdN1XrXN/LSaoF3FrVfRqWBRA5kJQeTpH4N FsJOFdDJlbsw3J+c1vW5vDTd4el5JPEy9ibST/4Rti2F5jWH8wmSWJ0QTBPDnKDD wpzGjBwIWN0mNqpWA+E1kI1O4DoZSshAn2EH8oekeaaJ6B7el6rlFBmD8R+gNS1F tV3lXXPu37Y74iAFMQoFjnLOvhJHEr210cSf4wIDAQABAoIBAQCTF1gb18cbfnOV jO/+oLvIhbqq3iBPFL7kiabzUx2qTG0GVWOaiJ/O5P0tF7CNxQwJwbowCb6m7J4T a9AKMKwkjsvn1umVos1MoKjRcwXQDobbxqLxm/L2zE7lqQd38GUHrHDRRmOR7Nw0 nLBwmBr1PDFEZui6LeXh727RT7nHlx6yo6cIYUrQBWaFSZJmfPD2pCMLRvEEY/0v yuv6NwuRVdO/P7R+pLDXDDbOktOiFvy9QUz4KtY2ZgZHobHZ9LJlyqFiC7wFQkMs la9vBniARgE1vX9D1QJJZ01ilivjiRDHaEq7EnZ9kRoO/ln3Yqlhr5OjAeQMFlMR AkX9h2VxAoGBAPnfruRdP5JTdXmun4IA0Nn3a3ZG7dNkUIl/yfhTKCD8ITGq5MXV aNSkOTVurkhrA38RuM6RQPypbjGRYdQrRMeKv6IrTC+sb7BhgcYe32370K8Y3TTX hgB24larb8jPot6f7nvkTbJJpwmHE8cXm7Gkmr6n340GPJzfmJke+H3fAoGBAMha rS+fCIyI3YwxmcyrA7nEKmAg2tTLiJ7xIY8i/ADwedqAnV8oAfScMw7IAF1EBkAt z2xfQhm1/pIqr1GcLxOgqvbixXfmM2qsLS/Zb/T6aOJ5xejsI3d21CIg5LwxF/EO 1hm5ereMdDTFw914HcO2Wap0Kyqg8MSd1GxgIhZ9AoGAOOqKm9nhsSLxj1YHX0Vw TTXedIKTiaM/9RH2n2nRqjHEHdwfYDDMQCNoJJOhfz1g/oC659KOSv8M6p2C+yEf +ZPRMs9J+1H73uFW/hnqKtNBJaE0QeUV0OVDiRpjzAn/v1YOrInEaOf99F2gU6k8 /anQ1bzHXwgcpl8IE1jKoWECgYAFVORm8AR6OOosYOWG3MYsm1vFUxp/ryrjj+ck t/mczMlxVxrY/WeP6tgw/IGF+dlwu8dZSu+nX4B2w0wHD/DwxMXH7CD1H9sea5aI P3ELQ96mqDbsC9ylwTPD9LwhheztLUflR1pMqCAvh1O/AQNJwgCA2LaNW9sMYGbW u3gswQKBgGsjcgS8l6cAYXOncwN6ROyosL6xkvc8zzUSH/KdPcXbAJZm/hQYeAyS QFAzUdyCXnokknYbLcsNmVqO+FAXQ+S2lwaBxS0uHWc7oc0KYaNPdFHSW0PCGj9u rvaEn/skAHkQTbLPPoPmuOs5qwWgYkMB6AHcSeCmBQokX7Zn7nfR -----END RSA PRIVATE KEY----- ccdb: address: 127.0.0.1 databases: - {name: ccdb, tag: cc} db_scheme: mysql port: 3306 roles: - {name: ccadmin, password: admin, tag: admin} login: url: "https://login.local.pcfdev.io" protocol: https logout: redirect: parameter: disable: false links: {} saml: serviceProviderCertificate: | -----BEGIN CERTIFICATE----- MIIExzCCA6+gAwIBAgIJAOPFFRMyK2dVMA0GCSqGSIb3DQEBBQUAMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzAeFw0xNzAyMTUyMjM1MzlaFw0xODAyMTUyMjM1MzlaMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOPQlCJnidk 8XLD0TysGURSJ35BBCaKPGULVEWklO5nzP68J21nY/1oUEdnA1d5cJh27U2D6gZ6 PEN7RsZTmpygFOQQaxbc8IKx86ackI6HCq3WwiDA92IJMMvedPrGWUNoG6h/qAwi RCo3TdV61zfy0mqBdxa1X0algUQOZCUHk6R+DRbCThXQyZW7MNyfnNb1ubw03eHp eSTxMvYm0k/+EbYtheY1h/MJklidEEwTw5ygw8KcxowcCFjdJjaqVgPhNZCNTuA6 GUrIQJ9hB/KHpHmmiege3peq5RQZg/EfoDUtRbVd5V1z7t+2O+IgBTEKBY5yzr4S RxK9tdHEn+MCAwEAAaOCAQYwggECMB0GA1UdDgQWBBRRUvkBTZ+jf0ao85VurNMQ v2QJdTCB0gYDVR0jBIHKMIHHgBRRUvkBTZ+jf0ao85VurNMQv2QJdaGBo6SBoDCB nTEeMBwGA1UEAxQVKi5zZXJ2aWNlLmNmLmludGVybmFsMQswCQYDVQQGEwJVUzER MA8GA1UECBMITmV3LVlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMRAwDgYDVQQKEwdQ aXZvdGFsMRAwDgYDVQQLEwdQQ0YgRGV2MSQwIgYJKoZIhvcNAQkBFhVwY2ZkZXYt ZW5nQHBpdm90YWwuaW+CCQDjxRUTMitnVTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 DQEBBQUAA4IBAQBk19J3yfMb0DEC/BBDlHUyGvvsLr0PVbZGtYT7qxHkqOQBFz1k q65aeNuT8D0GSMy6gfF64cRPp3A7a8NfeYsSoynufMHMaMKEzlYjSyNGwDcxyRwv eQ7w4QeX9EnRCBf/JQdC9bIIs9IoJAgNHhEZHnzdnt76NX1hJ+w8SVTgi5zdQknr v+wroKbStKy2R5qxnW1bPgt6AtMoE3M/ZUj+DNQvU3wEcTasWuxvDUOhZfoOM0Rd UxpHKQp+6PPugE59i/xg/Vm53FrAQ6+4Tn6w5jjtWBszH8OxFkyD+mKhKsh/DkfV kXvnbnHRmaEsQBbnWkhygDws3S1YT8/vTZBw -----END CERTIFICATE----- serviceProviderKey: | -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAw49CUImeJ2TxcsPRPKwZRFInfkEEJoo8ZQtURaSU7mfM/rwn bWdj/WhQR2cDV3lwmHbtTYPqBno8Q3tGxlOanKAU5BBrFtzwgrHzppyQjocKrdbC IMD3Ygkwy950+sZZQ2gbqH+oDCJEKjdN1XrXN/LSaoF3FrVfRqWBRA5kJQeTpH4N FsJOFdDJlbsw3J+c1vW5vDTd4el5JPEy9ibST/4Rti2F5jWH8wmSWJ0QTBPDnKDD wpzGjBwIWN0mNqpWA+E1kI1O4DoZSshAn2EH8oekeaaJ6B7el6rlFBmD8R+gNS1F tV3lXXPu37Y74iAFMQoFjnLOvhJHEr210cSf4wIDAQABAoIBAQCTF1gb18cbfnOV jO/+oLvIhbqq3iBPFL7kiabzUx2qTG0GVWOaiJ/O5P0tF7CNxQwJwbowCb6m7J4T a9AKMKwkjsvn1umVos1MoKjRcwXQDobbxqLxm/L2zE7lqQd38GUHrHDRRmOR7Nw0 nLBwmBr1PDFEZui6LeXh727RT7nHlx6yo6cIYUrQBWaFSZJmfPD2pCMLRvEEY/0v yuv6NwuRVdO/P7R+pLDXDDbOktOiFvy9QUz4KtY2ZgZHobHZ9LJlyqFiC7wFQkMs la9vBniARgE1vX9D1QJJZ01ilivjiRDHaEq7EnZ9kRoO/ln3Yqlhr5OjAeQMFlMR AkX9h2VxAoGBAPnfruRdP5JTdXmun4IA0Nn3a3ZG7dNkUIl/yfhTKCD8ITGq5MXV aNSkOTVurkhrA38RuM6RQPypbjGRYdQrRMeKv6IrTC+sb7BhgcYe32370K8Y3TTX hgB24larb8jPot6f7nvkTbJJpwmHE8cXm7Gkmr6n340GPJzfmJke+H3fAoGBAMha rS+fCIyI3YwxmcyrA7nEKmAg2tTLiJ7xIY8i/ADwedqAnV8oAfScMw7IAF1EBkAt z2xfQhm1/pIqr1GcLxOgqvbixXfmM2qsLS/Zb/T6aOJ5xejsI3d21CIg5LwxF/EO 1hm5ereMdDTFw914HcO2Wap0Kyqg8MSd1GxgIhZ9AoGAOOqKm9nhsSLxj1YHX0Vw TTXedIKTiaM/9RH2n2nRqjHEHdwfYDDMQCNoJJOhfz1g/oC659KOSv8M6p2C+yEf +ZPRMs9J+1H73uFW/hnqKtNBJaE0QeUV0OVDiRpjzAn/v1YOrInEaOf99F2gU6k8 /anQ1bzHXwgcpl8IE1jKoWECgYAFVORm8AR6OOosYOWG3MYsm1vFUxp/ryrjj+ck t/mczMlxVxrY/WeP6tgw/IGF+dlwu8dZSu+nX4B2w0wHD/DwxMXH7CD1H9sea5aI P3ELQ96mqDbsC9ylwTPD9LwhheztLUflR1pMqCAvh1O/AQNJwgCA2LaNW9sMYGbW u3gswQKBgGsjcgS8l6cAYXOncwN6ROyosL6xkvc8zzUSH/KdPcXbAJZm/hQYeAyS QFAzUdyCXnokknYbLcsNmVqO+FAXQ+S2lwaBxS0uHWc7oc0KYaNPdFHSW0PCGj9u rvaEn/skAHkQTbLPPoPmuOs5qwWgYkMB6AHcSeCmBQokX7Zn7nfR -----END RSA PRIVATE KEY----- hm9000: port: "some-port" url: "some-url" router: debug_address: 127.0.0.1:17003 enable_ssl: true ssl_cert: | -----BEGIN CERTIFICATE----- MIIGqTCCBRGgAwIBAgIJALiQgFdICQWiMA0GCSqGSIb3DQEBCwUAMIHOMQswCQYD VQQGEwJVUzERMA8GA1UECBMITmV3IFlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMRAw DgYDVQQKEwdQaXZvdGFsMRYwFAYDVQQLEw1DbG91ZCBGb3VuZHJ5MUkwRwYDVQQD FEAqLmxvY2FsLnBjZmRldi5pbywqLmxvZ2luLmxvY2FsLnBjZmRldi5pbywgKi51 YWEubG9jYWwucGNmZGV2LmlvMSQwIgYJKoZIhvcNAQkBFhVwY2ZkZXYtZW5nQHBp dm90YWwuaW8wHhcNMTYwNDA2MjE1MTU1WhcNMTgwNDA2MjE1MTU1WjCBzjELMAkG A1UEBhMCVVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhOZXcgWW9yazEQ MA4GA1UEChMHUGl2b3RhbDEWMBQGA1UECxMNQ2xvdWQgRm91bmRyeTFJMEcGA1UE AxRAKi5sb2NhbC5wY2ZkZXYuaW8sKi5sb2dpbi5sb2NhbC5wY2ZkZXYuaW8sICou dWFhLmxvY2FsLnBjZmRldi5pbzEkMCIGCSqGSIb3DQEJARYVcGNmZGV2LWVuZ0Bw aXZvdGFsLmlvMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAyFt7kzng mcjaAghcnWzTjqmxBqDxxVeDORdUEncsDP1zW8rvP5HXIdkch8sqPFSL1aKcCwj2 ytIQLqKr3o0Gx8MIhxQfpGwNtg4nrNpKLim6agE8CuDMu9w9s3/fIhbQXKJE2Yz5 yNMo9UBtcNjX77EGUjjKD1GRgiQKeugfE+XQcc5IcniVZcSzJi8279951pXk1sDB j9kczsP91z34UZnTCrtYXyk5iV7IYeTXB+UuNItIWm+gIYf6084Pz2ADtgMBswv6 LcCGZJBGluMCklrXg7Pn1CfaQOCPYj2fyt5YqQDGB5F8moWatw14ZxnsDBi2xqQK ryJYa2vYdKiVIWewD4iRpS5HHVjETYNlu2W5ypfRfGXvc0110IhHS83+bcJoUFUn u9bHo9qqshx/Bq6ew0iR12negzVHMI5R8+EupW2smmJu3n8d0L3NZA5eEfJgpvGd DALuv0+dI0KLBAPMrgGq7B47l0ygvO+MOWudmzSzvsXvDxqs8q/8EqHvAgMBAAGj ggGGMIIBgjBMBgNVHREERTBDghEqLmxvY2FsLnBjZmRldi5pb4IVKi51YWEubG9j YWwucGNmZGV2LmlvghcqLmxvZ2luLmxvY2FsLnBjZmRldi5pbzAdBgNVHQ4EFgQU 5ir0R2vhcWqdd7Bm3HnflLQMIOQwggEDBgNVHSMEgfswgfiAFOYq9Edr4XFqnXew Ztx535S0DCDkoYHUpIHRMIHOMQswCQYDVQQGEwJVUzERMA8GA1UECBMITmV3IFlv cmsxETAPBgNVBAcTCE5ldyBZb3JrMRAwDgYDVQQKEwdQaXZvdGFsMRYwFAYDVQQL Ew1DbG91ZCBGb3VuZHJ5MUkwRwYDVQQDFEAqLmxvY2FsLnBjZmRldi5pbywqLmxv Z2luLmxvY2FsLnBjZmRldi5pbywgKi51YWEubG9jYWwucGNmZGV2LmlvMSQwIgYJ KoZIhvcNAQkBFhVwY2ZkZXYtZW5nQHBpdm90YWwuaW+CCQC4kIBXSAkFojAMBgNV HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBgQBB9E/Mc/Zq/RJlLiu20EU62xjw WWYAPCGIvo64GvkC8N+mMZL8qHaSsYGKrvEPl30kIRaXfO2RT5Mhx8CyYhFVrWCq oRMVY2Li0h2vMYhRIlAjxzn6ZVUbd50t6hEmXioh6LxbrUUg/AXfbMuv2sW94xjx vjUul7ZO8JfC7Uk2g5rngC7yz4mXI1sXlIq0xpRAxdBMreH9uG48xlO6cE/5Xzim AmjvPWaCBIgiiJmW9lpt3oB+vttHtNHY+mnYtx9iE/R9mCL513uhsTtqOKLPN1Vb D9iouxOW4gXN7NnhNSKyzBVFh+SInj3moxcTQAgKbXOq6oaJEz61VedGVyh0ncpi pbtzQcoxSC88pMTZgm8ZFT5aL+f3Pod7MMAeuY3R24+JtlOlW5VYvwRfl050u5rF LgeP1t+Kpxpd0OxjShWhGoYD4MqJyfqPXjYSd5uSRRTxgZFuSrO+VjXcJfkBqfss RaK+wxioZDzc5z3vDJjaZGFdtki6f2hwsF1UPVw= -----END CERTIFICATE----- ssl_key: | -----BEGIN RSA PRIVATE KEY----- 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 -----END RSA PRIVATE KEY----- ssl_skip_validation: true route_services_secret: route-services-secret status: port: 8087 user: "" password: "" blobstore: internal_access_rules: - "allow 127.0.0.1;" port: 127.0.0.1:8086 tls: port: 127.0.0.1:4043 cert: | -----BEGIN CERTIFICATE----- MIIC0TCCAjoCCQDRLH9gxoogFzANBgkqhkiG9w0BAQUFADCBrDELMAkGA1UEBhMC VVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhOZXcgWW9yazEeMBwGA1UE ChMVUGl2b3RhbCBTb2Z0d2FyZSwgSW5jMRUwEwYDVQQLEwxDbG91ZEZvdW5kcnkx GjAYBgNVBAMUESoubG9jYWwucGNmZGV2LmlvMSQwIgYJKoZIhvcNAQkBFhVwY2Zk ZXYtZW5nQHBpdm90YWwuaW8wHhcNMTYwMzA5MTUxMzE4WhcNMTcwMzA5MTUxMzE4 WjCBrDELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhO ZXcgWW9yazEeMBwGA1UEChMVUGl2b3RhbCBTb2Z0d2FyZSwgSW5jMRUwEwYDVQQL EwxDbG91ZEZvdW5kcnkxGjAYBgNVBAMUESoubG9jYWwucGNmZGV2LmlvMSQwIgYJ KoZIhvcNAQkBFhVwY2ZkZXYtZW5nQHBpdm90YWwuaW8wgZ8wDQYJKoZIhvcNAQEB BQADgY0AMIGJAoGBAKpQpDfxV0enkW9q37vz6GAqGzQI4kJaOq0Vu0aNJE0QguZV y2JZaBGdYE25hviPesDhrFASUeMek//1FgpntnRU52AsweHJ67KayFEppk8qC5yd XOm177O4QKbMmA6BC3BMnF1nLnKqTS71cbGfzvqaAmNlr22BJP7krQleXiFzAgMB AAEwDQYJKoZIhvcNAQEFBQADgYEAKor/gSMkfVFPfmTLuCvH3YrvSFRPjTxXHeMR 8C6hmkOHxw2tgxc5WI0+ZLCgVCS87ZiLoTFWAmeeUb6S2nIHr+WhTHr11Y+0EjZa WWv8728elfnHAiWfmKgn80LEOVLU8dDciykSRGOdDYnTAXLgtZOxfLeReR232JuH TkCCeJc= -----END CERTIFICATE----- private_key: | -----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQCqUKQ38VdHp5Fvat+78+hgKhs0COJCWjqtFbtGjSRNEILmVcti WWgRnWBNuYb4j3rA4axQElHjHpP/9RYKZ7Z0VOdgLMHhyeuymshRKaZPKgucnVzp te+zuECmzJgOgQtwTJxdZy5yqk0u9XGxn876mgJjZa9tgST+5K0JXl4hcwIDAQAB AoGAFMLx0dP8tMJriy53CZ1pBVf8qvIuSrJfFrxgcPBBrZdGrbdlrJ6Dfio2FCN6 nZA4AY1BCR3Cl7IhjoEc57XO2tpv7Ct5YZU3R/UGMZBTQJGTMdYLsXKVQPJFZZfr nFvnL+dks1xmiLOPbSw45qvsC+KrQVFGV6ZqD6ZxjPKtlwECQQDiUcWMmL5k07XM lvXHp/ZrfFdwBjlAcHDYNbQM0zid6C4m6YD1WI6zU/oCCS+gCT4cauoad2hcsUoN zj1phOzzAkEAwKahynDyef2kSjsD8zDqY+HuRBKtDa8WB1mOgU737wIx8kfXgbNg MlChsARn0yThm1L2yx4ZTk+PAtxAr4UZgQJBALRQgDuXisIcZ1E8yU+sg8l5hNSt MLolm9K3Xt+E/ivZS8QW8HcJepBoDN3IYdh45LKRgDlb/5syaZT8R7Olg38CQQC3 EKDFgjan/YJUl2fVfDH+3/5N6YFQc4P3T/6+mY+4KtnTZLlAondS2JQMcuNGHNHV iyzBLsTVSXyYNzuwjkYBAkEAq/pT9lmw42qc6AQk/LcfZFYXKV21m5LCDa95/7X2 TVeavLJv6412vDf+E6r/5jG634SsMkRDGeUsW9gUvPnaXg== -----END RSA PRIVATE KEY----- admin_users: - username: admin password: admin secure_link: secret: secure-link-secret # For Garden: garden: network_plugin: /var/vcap/packages/runc-cni/bin/garden-external-networker network_plugin_extra_args: - "--configFile=/var/vcap/jobs/garden-cni/config/adapter.json" debug_listen_address: 127.0.0.1:17013 allow_host_access: true graph_cleanup_threshold_in_mb: 15000 insecure_docker_registry_list: - host.pcfdev.io:5000 deny_networks: - 0.0.0.0/0 # For CF Networking cf_networking: vxlan_policy_agent: ca_cert: | -----BEGIN CERTIFICATE----- MIIE9jCCAt6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBjZi1u ZXR3b3JraW5nLWNhMB4XDTE3MDUyNTE4MjQzNVoXDTI3MDUyNTE4MjQ0MVowGzEZ MBcGA1UEAxMQY2YtbmV0d29ya2luZy1jYTCCAiIwDQYJKoZIhvcNAQEBBQADggIP ADCCAgoCggIBAMQr/nlMLZYXNEpe1DCnkRoTmERogDJM8/PGAMQrwy9S+m/EV2Ju 0BryTq0JtOpdJPy52p49efc36K6N69z5ednssJNmiSMCF1Ia2EqCnuE0at5NK75b yB5fOY7LW9ZCHjttbqs+xQIFzPLJNJlLeIsKoBqbTnkopMOwy/Z7VcHt7+vAG3H+ KU7zyheleD5g6INFJK8TolhrHDdkRB7KxSssqEzhLXUtrBD2pzXSayboTnIA1Y37 Dnlv0nqVTR7YDbYZMkbr4CCd08fgChp+vE2WwPyFyL1EF71exQNNoKbs91ad+pvx jMGLj/ii8p13X30VBSWdsKbRKJvk7Q/vWx7tJkKfa4mMyPwXjWlWTjccCbflDqgz /CsMkOYK4vZySFfETyzcz2J++kejxnugEmD6AmUV+6GdyHWPdi3CKsnVwJFVm2cI ZiCshFjwKjp6yws4n3JcqmzFdOGY8Ij2YG4qjKCLrvaZIqyDwQ9fRXKTVNF3bmlm 8BAAsUhCbbtnnAFOPnadliClhJiXHM0NIB38GCZa0tuno2vAncGrfDaX4pNQL0t9 gS47wgxKEfK3WNe37JcOtwk8oET4PeTugiVWmcvxCEDwOXCvNBQOjv8HWb2LBYJz njW4q7yNmXtfsS9InwBq3mRxRgU6UjjppT8hQDubpUCFARj/pQa/+PdfAgMBAAGj RTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQW BBTKGOy47aC2jl6GVjNI/yaqpAlJEDANBgkqhkiG9w0BAQsFAAOCAgEAHXT0ch9V W9BJisT+rxBLsqiNrry6bxTFVbktG/kU0B4oRgYosAl5Y5rWHByFavZNuQ9LP4gA OVuRxs4vrvX+ym6/m5OCs7zVvunpXh1CzfpifXLTzQn5YNXxBSCBSxTF4vInES1k wg6uwnVFLO+7kTorPfizp3lO3ydI8DpdUr3KWiAP9QthSJav8TAVopgBqdVzQFNs rLD6Rr//4oK0i1c2escErwXbAWR1d2PIDl/z9h1PtSfXWOSb36g5JshFwzvWInXQ 65EQJvnxBoETHkGmwINE4Y1iy++duXQCF28gPD0GtesNqrTbJ91e3CHjI1thpre1 R0E+nlF5AXY865ARKGDJwdsQ2oGqLRCUZqaUHatZXON6+o5lOgzJ5W6vqciolX+y 3NrGZMWTBFnWziaXTAh7QspB8ZJwKEudIEPYBBqA0BEA/0SAxsINIFpeTipofmIV z6Gn/tv+77dzW3GoAiaDuRCCpR2HvQJEo3YQCcAKWOvYD3a3LonOD9VwPT6jlKRj nCYJNHYd7d92e7ykfsDq29PTtxzCAtZ2Nr/IqhZZmrI8aZftZ0GLq2BRcBnBeR4P pBiWkZMn4//XACyFzIBtLgkqua+JXgReL3qzYqToXk5AUv48Z7rfz0YAJ6azFeSb 9MkVxlFa6Wls0/oHBMciwq787gURtJwPRHE= -----END CERTIFICATE----- client_cert: | -----BEGIN CERTIFICATE----- MIIELTCCAhWgAwIBAgIQDaq/r8ootJP528H2AH8F5DANBgkqhkiG9w0BAQsFADAb MRkwFwYDVQQDExBjZi1uZXR3b3JraW5nLWNhMB4XDTE3MDUyNTE4MjQ0MloXDTE5 MDUyNTE4MjQ0MlowFzEVMBMGA1UEAxMMcG9saWN5LWFnZW50MIIBIjANBgkqhkiG 9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7BzjXP0OSXau0Svr79jJ2Ru+JtiidfOnIxYW z6C5LgbbbkzdC9A4XlJvGzK8/Ez+HFKFceGZObpkiF3OVEVa9bcr9mV/wqtX+jb9 uvlcuiyNGTV5RXjlPXPS6/RSsaC/1Q24XNeQJwDNOC7EnDSzuJTp2Uyc+ySv6+9Q 21qZqNNYNA4185QRE5JM5RNxfak0miPfLumCCYLMMc3WIZo1A6He7kpPHxJ7t0uD lRmfdF39dazalGJEKTKitpXRVZFdylNcIgcSD9rj70f6//uxNtjJDwlUpVexgS+C 8rOAtUP2B1lGvDLw4e2M+p42wSTTjuo+yp+TwS0CAKX4N8I50wIDAQABo3EwbzAO BgNVHQ8BAf8EBAMCA7gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0G A1UdDgQWBBSHckyXbkJHuPWB6/xfPiUSYCSgKjAfBgNVHSMEGDAWgBTKGOy47aC2 jl6GVjNI/yaqpAlJEDANBgkqhkiG9w0BAQsFAAOCAgEAcHq3+6mfiS5mCSWuKdAm hI157+AY0kSUxtqcNYz7clawX3VwuAL7d9VqDoe/okilP/xXsBoqWgc4TXZURQtC +yeUiMKQYitfvtzSI77+ZrCx1GE4rNUDzq7o411e1tumxxdVOtw3Rybf476rJsyP yIm0DeTx5cV1/MltYP2K/2rh9ATJIzRwc0clBhdINtSqr4cG1ChBbDZveyBoOSIC 5vrs2G9mnW7CYI1cydVeJsweJzajnFLqjOKTJuOG5Tc277wTwEmiDUfKrAJHM0TX /yC/VFSGooFGmT5bv7zNPzdH7SmMMwFFRkud6FkNynOhfIWaqzzclpc3BYUoo0r1 8L0FhgZx9kmmdHnMdzmmMMxKsvOLApObpcQibVT0EmSIjoWcoPH+ikoxwoLzTfgI 84nC3yqWUL01mew6iZIipLwws+rx5AZe0G7HE5uu0BSaKGcmSEaIFJvpqsDTsY26 IUlwkf5XsiLVMitbiSoI3ZZUHYGUjBLRNpvOTO3+TA12kmiouXqkHTj5M/Fb2f0v tqgEdklDywcgqoCSc3/+Lff9HR/OYTDeIJDrNrWleMGpmaj4hWu02aMKHQYoG/m8 /VlB1Uv0Csov4oWCejipytcoy7unj0NvFmGld9vJBF95o4OmfTQ7ir3M+1lcIxMn phiarcHdb/G3/1wiX453KBI= -----END CERTIFICATE----- client_key: | -----BEGIN RSA PRIVATE KEY----- MIIEpQIBAAKCAQEA7BzjXP0OSXau0Svr79jJ2Ru+JtiidfOnIxYWz6C5Lgbbbkzd C9A4XlJvGzK8/Ez+HFKFceGZObpkiF3OVEVa9bcr9mV/wqtX+jb9uvlcuiyNGTV5 RXjlPXPS6/RSsaC/1Q24XNeQJwDNOC7EnDSzuJTp2Uyc+ySv6+9Q21qZqNNYNA41 85QRE5JM5RNxfak0miPfLumCCYLMMc3WIZo1A6He7kpPHxJ7t0uDlRmfdF39daza lGJEKTKitpXRVZFdylNcIgcSD9rj70f6//uxNtjJDwlUpVexgS+C8rOAtUP2B1lG vDLw4e2M+p42wSTTjuo+yp+TwS0CAKX4N8I50wIDAQABAoIBAQCKsAFA2ods0WCo DrN8Y4tUkn4j1TXAMMkoy83EUXTUO0TiyhVA3iJuDN+kSy5EyHiubC5kEQ5uoTRy AR+z0jU2hUw2Y7Iix4BawbhR/izgUlDi0M0V6IhGi2UGIbH9Eh376B41sozCzC6+ 5IGp+y7hqd6eO+ktf4QyApUs80+0oKaobBSPJ/vafE1c4QSFgl+zZ5HvoZdHnW48 L/0YNNUK3O+d2dcbESNn/OoiUKfNLxnf7AnJBgF4xAwoJmxwLbC8vloxFuM+gU14 y23TcCHAE3kjmgO53yAanyj2UE4ZgV+TxKaxAZMDgSykZI0DsgHeHe5J4yzqflZP /6etCsQBAoGBAPWJIyRwBeMafavq3vw80VimBJA00j4R2/xDTo8wcq1X7X3moCDr xcDucarzI0kwmU3dSjv0Krjk73Qhm8bJ3UbbFQ7z4N3TZ1z9mlMnUlSVregz0TWk bl6S1eZTolHHoh7/swfltR7dBycAiVHfz99Cz4RfKTrOsgFCRUmxVc/TAoGBAPYs 8elfIpy/xk9ssUXyYnmQrgovjhr8xjISRhp1Gg/Gqirx9krevZm+1xsDecp92GPe fgwMTeYTrCmqhrWSaaXMV6p0B3br///v+f74v8dIyN9pqL2E0cTgpGcjHl/lIUwj o309NXxiQSO5QrzpKLToF9pE0/9AVTYF39RQSa4BAoGAAzQJ0FThzseusgp7ZEEK 3iQ0VQlLYOHsw8rBAJ86L8bA426Z0jQhPVYfB4Lqh+7pYRms+UFDOWxLL3GszZge mekLykkmOt6iL5VjaQhPS6k0Pp5GcXO2uOcjgUDAEl8PX2YomMbHaSKrEDgykm3g EWKWwHxZVloR+nA55S86Fl8CgYEAyWDM59ZOLyHl7NUCUzDLg5xp8qUiP0tmKlGu jTgcAKnITGcwzeBWA24M8ukt+QpnOJMqU1rBYqPXIyJ/HgtOZzW4xRQzgwHdohVC UWRVJYWR5Mi/I4GCQ+ZsNn6Q+2spiOpidDHdDgomNT34rSaiiRKPaJsDPPv4eL/n cPvYugECgYEAtdYzx5qDUjBkQyRc1vhXX5guGEisrNyR0+zFcrXvJhkemDDhD9fh rx9VITqD/1mBlUmqHiLeCzcLWybLFKuwgWwsWbgnPZ5wrlsq5BWdIxpSFhA3bLYT sN1syGAcMN4lHtB9A4u/6Z0t/mko4uT2V5CVHhw+5mFrKW0bVPHAmAA= -----END RSA PRIVATE KEY----- silk_daemon: ca_cert: | -----BEGIN CERTIFICATE----- MIIE9jCCAt6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBjZi1u ZXR3b3JraW5nLWNhMB4XDTE3MDUyNTE4MjQzNVoXDTI3MDUyNTE4MjQ0MVowGzEZ MBcGA1UEAxMQY2YtbmV0d29ya2luZy1jYTCCAiIwDQYJKoZIhvcNAQEBBQADggIP ADCCAgoCggIBAMQr/nlMLZYXNEpe1DCnkRoTmERogDJM8/PGAMQrwy9S+m/EV2Ju 0BryTq0JtOpdJPy52p49efc36K6N69z5ednssJNmiSMCF1Ia2EqCnuE0at5NK75b yB5fOY7LW9ZCHjttbqs+xQIFzPLJNJlLeIsKoBqbTnkopMOwy/Z7VcHt7+vAG3H+ KU7zyheleD5g6INFJK8TolhrHDdkRB7KxSssqEzhLXUtrBD2pzXSayboTnIA1Y37 Dnlv0nqVTR7YDbYZMkbr4CCd08fgChp+vE2WwPyFyL1EF71exQNNoKbs91ad+pvx jMGLj/ii8p13X30VBSWdsKbRKJvk7Q/vWx7tJkKfa4mMyPwXjWlWTjccCbflDqgz /CsMkOYK4vZySFfETyzcz2J++kejxnugEmD6AmUV+6GdyHWPdi3CKsnVwJFVm2cI ZiCshFjwKjp6yws4n3JcqmzFdOGY8Ij2YG4qjKCLrvaZIqyDwQ9fRXKTVNF3bmlm 8BAAsUhCbbtnnAFOPnadliClhJiXHM0NIB38GCZa0tuno2vAncGrfDaX4pNQL0t9 gS47wgxKEfK3WNe37JcOtwk8oET4PeTugiVWmcvxCEDwOXCvNBQOjv8HWb2LBYJz njW4q7yNmXtfsS9InwBq3mRxRgU6UjjppT8hQDubpUCFARj/pQa/+PdfAgMBAAGj RTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQW BBTKGOy47aC2jl6GVjNI/yaqpAlJEDANBgkqhkiG9w0BAQsFAAOCAgEAHXT0ch9V W9BJisT+rxBLsqiNrry6bxTFVbktG/kU0B4oRgYosAl5Y5rWHByFavZNuQ9LP4gA OVuRxs4vrvX+ym6/m5OCs7zVvunpXh1CzfpifXLTzQn5YNXxBSCBSxTF4vInES1k wg6uwnVFLO+7kTorPfizp3lO3ydI8DpdUr3KWiAP9QthSJav8TAVopgBqdVzQFNs rLD6Rr//4oK0i1c2escErwXbAWR1d2PIDl/z9h1PtSfXWOSb36g5JshFwzvWInXQ 65EQJvnxBoETHkGmwINE4Y1iy++duXQCF28gPD0GtesNqrTbJ91e3CHjI1thpre1 R0E+nlF5AXY865ARKGDJwdsQ2oGqLRCUZqaUHatZXON6+o5lOgzJ5W6vqciolX+y 3NrGZMWTBFnWziaXTAh7QspB8ZJwKEudIEPYBBqA0BEA/0SAxsINIFpeTipofmIV z6Gn/tv+77dzW3GoAiaDuRCCpR2HvQJEo3YQCcAKWOvYD3a3LonOD9VwPT6jlKRj nCYJNHYd7d92e7ykfsDq29PTtxzCAtZ2Nr/IqhZZmrI8aZftZ0GLq2BRcBnBeR4P pBiWkZMn4//XACyFzIBtLgkqua+JXgReL3qzYqToXk5AUv48Z7rfz0YAJ6azFeSb 9MkVxlFa6Wls0/oHBMciwq787gURtJwPRHE= -----END CERTIFICATE----- client_cert: | -----BEGIN CERTIFICATE----- MIIELDCCAhSgAwIBAgIQbv/BkuY4VmEhTvVFHETJkzANBgkqhkiG9w0BAQsFADAb MRkwFwYDVQQDExBjZi1uZXR3b3JraW5nLWNhMB4XDTE3MDUyNTE4MjQ0MloXDTE5 MDUyNTE4MjQ0MlowFjEUMBIGA1UEAxMLc2lsay1kYWVtb24wggEiMA0GCSqGSIb3 DQEBAQUAA4IBDwAwggEKAoIBAQDcbWXU4DwK5Aidqp9ncEZYeTbYBibxuqJgQcLe QwlVMpMUT7gZv8dBPTp+PftINcXa+2OW/F2r9VSWJuOsP7KgrwLdwj8O9QNSV72Y 1MXuit76+8tDb4IOK97pv4S+tq3RMDbUINRwvXR8P/am/3GZ4iYmv+GZEETQNLRb Hu+Gj4VHnYKy49MXxyTddpIni6oAxojv4fMJ5aYThn7gr9vT2ufOaMitRA2BNu0N YFPpp1MZe167/9xR39QZuLXZJAuNIAZl7J99fo+XOLEF9bsHwmVUVkZmeQKEgYxR eRpeV8ettjoetISyPSqr8SBU/I+VF4K/MXXFFLc/IhWmYrpPAgMBAAGjcTBvMA4G A1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHQYD VR0OBBYEFPK4Vsgkodl/kEhpfN5LA69UCs2wMB8GA1UdIwQYMBaAFMoY7LjtoLaO XoZWM0j/JqqkCUkQMA0GCSqGSIb3DQEBCwUAA4ICAQCqZVyhhqn9fI4wNzXJ0UfU GGJLKy4TrIdR5LSWwRtK7odoHKgjsIeAovalELj/0NBOoHIjtyfoztYk9lsYOTss XltT9T747yC+lO/1jhb7xdS4P1HYDfzCfJYvtpqoW06Vf5J15f4ToOFf72p1McXd RZZPRtcK/+ytGDRyqCCCWCVLkg+H6BRnSMRc01q0Q4BxbN4EbYNMBBkbfBZbtzE2 7RbxSPe6rFdlAlWKeL3bTuGc+Vp7LRK8nB6+w4HJgL68whk8OfKK3FgIA4gvBV7u HAKNYGCxf+8SyuTXnLISJD+aHIqpzH+NVouB68kEfzZLCuaYOhKtrSexW/uDV5Ak JNYaRqdUF5x0bkkiX5NpbFNmpeNHwg/kio8Lf4tcc0r2rx4vb0hMTU7PDd1wMFQP OxmgXrkVqcMmf17Syk5N7B7nDB8SVCl1aBz+Yme3lhGSXKkkSl7V3MeM7wURnfTZ Pk19emtJkRjVRBvXR56rYuN9BM3bb34PPDpXW/b37jTDZ3AtWyB64nL6Qq3Ie2Dq Zs9tt6S3rWktCudiJ4HHhMqcs8OzKq6Lhhsw9yoqEwb0fPq8kE74cBzHZg7r3Vo7 BCvhrhrBxWpoE58IzsuXfl0tAa4aakpUkeqKn20+TAF2H2/+Cl5+xCHPvntg8KeS /CZZ52J4s4vro3aq4oRYAg== -----END CERTIFICATE----- client_key: | -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA3G1l1OA8CuQInaqfZ3BGWHk22AYm8bqiYEHC3kMJVTKTFE+4 Gb/HQT06fj37SDXF2vtjlvxdq/VUlibjrD+yoK8C3cI/DvUDUle9mNTF7ore+vvL Q2+CDive6b+Evrat0TA21CDUcL10fD/2pv9xmeImJr/hmRBE0DS0Wx7vho+FR52C suPTF8ck3XaSJ4uqAMaI7+HzCeWmE4Z+4K/b09rnzmjIrUQNgTbtDWBT6adTGXte u//cUd/UGbi12SQLjSAGZeyffX6PlzixBfW7B8JlVFZGZnkChIGMUXkaXlfHrbY6 HrSEsj0qq/EgVPyPlReCvzF1xRS3PyIVpmK6TwIDAQABAoIBAFXqLe6zF7QG/XS2 tDrVABYr6Lx6aWN+oxtxhkqrRk/2zmz0RYWDwl4jR1E9R1v12ZBou4B2DOyhSr7b mZHhofYPQMa+l2V1Cj5mBHg1NpCrgA3DZo56P+7WGqRxCYRsH4ORj01PHn5y2Zw0 MicVGWopQ0WHNJ88QBYG9OUvQZzoSo8ZB7y+GEYdLbsQKtHsJ/JHaJeKwcbP28VV ATCsMQIfCxp0tZEuhGJ2P2FS1posTpfKV6eRngaZGcSEU+KJcTFlHOBWrVXviqrT IttDt/jjLrvL2ID+aijd2LGZs0zgCfo4PCgTwDH8nWgFNj1NS3VLJ+b1CBGq/D2c QosNecECgYEA8TuBms+2PdwNqukpkQCjYLde2GkSTzD4D0VPHvNakh8a0zzlQgHK zNWu54liWQexGFEKMcpKL4kFQffhUKFknpp9UkDIEwqrBptA91uT95jSOnEvwJX7 Y4l4dDULfnVIgY913hUTYGEq/q4bbD8H+O2nkAZIyktDl0OXuYK5+QsCgYEA6evX sDAWhbee+t+3f6XV08PrY5GZ6MhQvXps3dNh8FPRWIrH6llVRzwPqOrVu5L1vasW qcISn1AeULujCW2nA883C6RYcgZM1Zuy9UB8B0u1pK8XPw0dN/ZiomtL92efhVqZ 7oPRUxTkKEHMGZAG8OfU/0nljYDXetC4x6lPtk0CgYEAs7qeKXWwVg5psHjfm0Va dGiqpZpDJfVaHCaLeIffZxb9qXypYrBrJIngMmnNeH+elntqmQYal6gC3s+Mc8KL cQ+xZ2MUrfs4yUdK9ACrEcIuf5Rs+5PDJLn7oLkUwzcmukDklH4nXZuHqRCXJeMg UXrfaRMFkJLa3QxjMrgPT1kCgYEAzNlsGS8DijYzUx93YqGnj7uS968aSXCixEvh 6qCitAOy4Qcn62Iv/CHs1NBSO+GGsoKRZjg+dqWC5tBrBmawS/W7DsbtbW12+9lN 7th5xSnX+FAc22pwnAF4fyPXcuGcIPwmsWledpNk+pwkUH6AlZdwP+BG1pRuH2+J YdAzrkECgYBX7ydZUdMACGbeYqdaSuds6aTfFc92GWYADr4N6SdCPG2+O7aCsT8B Op9J5iuqCF2a39bbWssWk2dAwpSH700LVWUAqy0OXZEmYjFoSg4SK2E1TIeWLyIq hs70lbm2uRDIA8SRHr3AGT0exXAtattlB/HbfsEqLDkO0LbG56IlWg== -----END RSA PRIVATE KEY----- silk_controller: ca_cert: | -----BEGIN CERTIFICATE----- MIIE9jCCAt6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBjZi1u ZXR3b3JraW5nLWNhMB4XDTE3MDUyNTE4MjQzNVoXDTI3MDUyNTE4MjQ0MVowGzEZ MBcGA1UEAxMQY2YtbmV0d29ya2luZy1jYTCCAiIwDQYJKoZIhvcNAQEBBQADggIP ADCCAgoCggIBAMQr/nlMLZYXNEpe1DCnkRoTmERogDJM8/PGAMQrwy9S+m/EV2Ju 0BryTq0JtOpdJPy52p49efc36K6N69z5ednssJNmiSMCF1Ia2EqCnuE0at5NK75b yB5fOY7LW9ZCHjttbqs+xQIFzPLJNJlLeIsKoBqbTnkopMOwy/Z7VcHt7+vAG3H+ KU7zyheleD5g6INFJK8TolhrHDdkRB7KxSssqEzhLXUtrBD2pzXSayboTnIA1Y37 Dnlv0nqVTR7YDbYZMkbr4CCd08fgChp+vE2WwPyFyL1EF71exQNNoKbs91ad+pvx jMGLj/ii8p13X30VBSWdsKbRKJvk7Q/vWx7tJkKfa4mMyPwXjWlWTjccCbflDqgz /CsMkOYK4vZySFfETyzcz2J++kejxnugEmD6AmUV+6GdyHWPdi3CKsnVwJFVm2cI ZiCshFjwKjp6yws4n3JcqmzFdOGY8Ij2YG4qjKCLrvaZIqyDwQ9fRXKTVNF3bmlm 8BAAsUhCbbtnnAFOPnadliClhJiXHM0NIB38GCZa0tuno2vAncGrfDaX4pNQL0t9 gS47wgxKEfK3WNe37JcOtwk8oET4PeTugiVWmcvxCEDwOXCvNBQOjv8HWb2LBYJz njW4q7yNmXtfsS9InwBq3mRxRgU6UjjppT8hQDubpUCFARj/pQa/+PdfAgMBAAGj RTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQW BBTKGOy47aC2jl6GVjNI/yaqpAlJEDANBgkqhkiG9w0BAQsFAAOCAgEAHXT0ch9V W9BJisT+rxBLsqiNrry6bxTFVbktG/kU0B4oRgYosAl5Y5rWHByFavZNuQ9LP4gA OVuRxs4vrvX+ym6/m5OCs7zVvunpXh1CzfpifXLTzQn5YNXxBSCBSxTF4vInES1k wg6uwnVFLO+7kTorPfizp3lO3ydI8DpdUr3KWiAP9QthSJav8TAVopgBqdVzQFNs rLD6Rr//4oK0i1c2escErwXbAWR1d2PIDl/z9h1PtSfXWOSb36g5JshFwzvWInXQ 65EQJvnxBoETHkGmwINE4Y1iy++duXQCF28gPD0GtesNqrTbJ91e3CHjI1thpre1 R0E+nlF5AXY865ARKGDJwdsQ2oGqLRCUZqaUHatZXON6+o5lOgzJ5W6vqciolX+y 3NrGZMWTBFnWziaXTAh7QspB8ZJwKEudIEPYBBqA0BEA/0SAxsINIFpeTipofmIV z6Gn/tv+77dzW3GoAiaDuRCCpR2HvQJEo3YQCcAKWOvYD3a3LonOD9VwPT6jlKRj nCYJNHYd7d92e7ykfsDq29PTtxzCAtZ2Nr/IqhZZmrI8aZftZ0GLq2BRcBnBeR4P pBiWkZMn4//XACyFzIBtLgkqua+JXgReL3qzYqToXk5AUv48Z7rfz0YAJ6azFeSb 9MkVxlFa6Wls0/oHBMciwq787gURtJwPRHE= -----END CERTIFICATE----- server_cert: | -----BEGIN CERTIFICATE----- MIIEnTCCAoWgAwIBAgIQam2HuJ0ZkaKWP0+f6ZAEqDANBgkqhkiG9w0BAQsFADAb MRkwFwYDVQQDExBjZi1uZXR3b3JraW5nLWNhMB4XDTE3MDUyNTE4MjQ0MloXDTE5 MDUyNTE4MjQ0MlowLjEsMCoGA1UEAxMjc2lsay1jb250cm9sbGVyLnNlcnZpY2Uu Y2YuaW50ZXJuYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDi0p0d AU7TEB9wm2LqOAFoKcz+ti+D/01B7FpZl89jfrfiNfRvRxJZUFJqZCnQ+UAn6djg PELsOkeI7uYH4bPFleSK5j5/vRo4hsuQKzcwqY475ajqghdklZstigc7BPe5FQ7+ uKn5EnB4E9co8vE2lmYzoorchnZEFCBOKZDGzmziN6CbOmGa71rp58MtSzZUfpeH YIFfVeKx30Z+ui5yRc38sM3zSglM3OfNlle5k+usAqDENp5eMtcfFzQdn+ENxMO4 5csAI/xKRn0cGdgVlKINzr3HNxaSgb5JfWPQqGUr2wnqZFDdpvkGaCu68e78iiah tH6QWLGktT33PB+dAgMBAAGjgckwgcYwDgYDVR0PAQH/BAQDAgO4MB0GA1UdJQQW MBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQUJUzyZQ7q3rU38J1EKfBO 4MsVtqMwHwYDVR0jBBgwFoAUyhjsuO2gto5ehlYzSP8mqqQJSRAwVQYDVR0RBE4w TIIlKi5zaWxrLWNvbnRyb2xsZXIuc2VydmljZS5jZi5pbnRlcm5hbIIjc2lsay1j b250cm9sbGVyLnNlcnZpY2UuY2YuaW50ZXJuYWwwDQYJKoZIhvcNAQELBQADggIB ALOhokAvoaoYsf0f1bpn8EKBwPVWnda1RjQlWlOJkSmOq4zWYuAtGZZ8w4MA8e62 9KLUd3Mbdc/fYqTD/7NcINEKLTt6k0F9OeuvvbW2FhsRs8haimbujMxjpV2J1HEQ wt/KJuyEVeu24h8F8VFtAcZfnki6lOfr5Hw4nxdI4IIeDiffY1lzuoauN4kRKNLA avlCiLu8xcoaN1QeA0w4t6UwJxFK3NxDh23q+KIqKg+zb6pDZS6zgJbPFAa3UHoi fhXN4rA7kRv/k9SqoNJsCdNNKT3aZTvu7XcgLKAr4AYeM+xjAQSXeHd4xvT9/cyJ fpIhKA+cXOJ+EtvIpn66b3W1ZylfySBVF+L4iTFSayuw+sCjbJMK18r3GGJjHTjb BOrTNp/Psd1LLDMRKgEMzRbvpNxIIhw2AJ1ydbtvthqxCn9KXKf2j9rQ3sAWeE7t Q49UcailqVKSbgBVLmSkSYTFb/r2eOqna3cbC7vaaSxTkkPkT4RB9feeve5rNiPT m4RGrpnzB6DPS+oyDRVMf0wDDcvvcx0xfDF+KHRu6jEhlAb9HDiv302d3c+IxAKl VRnNjdSjBe8Cett2xXS9PB6Q3dHWUTkMpKVn6zoDjqDo6mdR9xmnpi0Z9rDHIISX Ur4TIwqXiV3bFMMgAZbqFnjv+vFWU5y8deFZpFf5Nfb1 -----END CERTIFICATE----- server_key: | -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA4tKdHQFO0xAfcJti6jgBaCnM/rYvg/9NQexaWZfPY3634jX0 b0cSWVBSamQp0PlAJ+nY4DxC7DpHiO7mB+GzxZXkiuY+f70aOIbLkCs3MKmOO+Wo 6oIXZJWbLYoHOwT3uRUO/rip+RJweBPXKPLxNpZmM6KK3IZ2RBQgTimQxs5s4jeg mzphmu9a6efDLUs2VH6Xh2CBX1Xisd9GfrouckXN/LDN80oJTNznzZZXuZPrrAKg xDaeXjLXHxc0HZ/hDcTDuOXLACP8SkZ9HBnYFZSiDc69xzcWkoG+SX1j0KhlK9sJ 6mRQ3ab5BmgruvHu/IomobR+kFixpLU99zwfnQIDAQABAoIBAQCBpSY+VOgMBZQi 1f30p+xN8E6Ga/W+uacb/g8qVHYqhVxvRK2hCPt450skGno4Qq8j4SqgCHGr+ie3 Ie2DJcOONP27Upz4gErDcnBZyAm0m8V7gOpKl+7tBAH9Rn6Zgl5hgKLgfwZQIfT8 /UIm2q16qP5jlw1NvOFOSj6ozmM87d5N+v7qBMGB5tIRQeeAgqFohmbXTI6Y0FqU ZTSrSlJm+LB4J9AtynJsW6IqM+5wajC9S7iazQA6JSb4Duml++oKwHfM7rtwFujK i07XrIXuyY08O68EFOYQy7NI/Tq+tFyOgWrLPZ8RbpwSNLFFcpSJuqo3ka1YadKu WHSP795hAoGBAOWQUkFrM75n58j13GBIlPy6mnPxM9HvFDAynmmaxFZ8qZtLCrSg N8kBHYKVQibCb9R6DYpYYxte/w4g1sIIDBxHNgAnMjCSLi6Zt2WPwj92hj6vZ1Qn A3O7rSklr17HN7HbFPMwTu4mbVdCTQqMFSxV9bheAjpuAOAgHGYkWz4VAoGBAPzx fBe3URlC7GzWKLMW1R2pgGtqW7D0AWfj+DOsfpjIWpZX9KXySe1rbGlllXkxaw/k mT6ItcFz/QB8JOtz1G7fbjIMDm0pUpIlxwUaXeLiwjp2CXZFQqnRpRdy0UuIDjt+ VJCaOE5SgXuLQR/JthYIK3/t2LxxE/fstta2xEVpAoGAGgIk35aGsT7Satk4E4yF nLCDiTk9lr5Qejlx6yMGtYnAKYDyAI7aYyKGNmI0sXF7/AWr/Q2QhOxZVz9vNWJ2 BMoomxHVxNz68Hqn5ZDJACmsgfObcFRPNtB/iNblLIbDj5nzoK3Lc33VC3rOgbBn QbOneDDmbbpCzSG2NfhOghUCgYBnRRyZ/jExNB6c7O7e93J5Usvojxryaxzr0qpy RnnFXP+HJE/xNLO0KEix21Skj2WbroRWgLBcVEO2X/ke3EKeJcCy1DNLpDRfEOdp kPNF/7i275w7Wlm2Ra62nR0QTnMpHRHfm+djKtJMo3UqSkt6QUmpSG1VuoEhltar YSFPCQKBgQCIkW9YddqPwqeNVavbAgklVHJ7R6lxHdUZjWFXr+L1nIwwhSXzxkPl SmpW0ahS59+X7svfwt5kVNioJfaGPEiyPPBjX6PpPn+2cCfEzsKokYeUKze8khYs Z6IQViludHOs/Aji4YL9Z8+OK4sDAkqI6x/F539yg+Y36Sfc2H97wQ== -----END RSA PRIVATE KEY----- database: type: mysql username: network_connectivity password: admin port: 3306 name: network_connectivity host: sql-db.service.cf.internal policy_server: uaa_client_secret: network-policy-secret uaa_ca: | -----BEGIN CERTIFICATE----- MIIExzCCA6+gAwIBAgIJAOPFFRMyK2dVMA0GCSqGSIb3DQEBBQUAMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzAeFw0xNzAyMTUyMjM1MzlaFw0xODAyMTUyMjM1MzlaMIGdMR4wHAYD VQQDFBUqLnNlcnZpY2UuY2YuaW50ZXJuYWwxCzAJBgNVBAYTAlVTMREwDwYDVQQI EwhOZXctWW9yazERMA8GA1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB1Bpdm90YWwx EDAOBgNVBAsTB1BDRiBEZXYxJDAiBgkqhkiG9w0BCQEWFXBjZmRldi1lbmdAcGl2 b3RhbC5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMOPQlCJnidk 8XLD0TysGURSJ35BBCaKPGULVEWklO5nzP68J21nY/1oUEdnA1d5cJh27U2D6gZ6 PEN7RsZTmpygFOQQaxbc8IKx86ackI6HCq3WwiDA92IJMMvedPrGWUNoG6h/qAwi RCo3TdV61zfy0mqBdxa1X0algUQOZCUHk6R+DRbCThXQyZW7MNyfnNb1ubw03eHp eSTxMvYm0k/+EbYtheY1h/MJklidEEwTw5ygw8KcxowcCFjdJjaqVgPhNZCNTuA6 GUrIQJ9hB/KHpHmmiege3peq5RQZg/EfoDUtRbVd5V1z7t+2O+IgBTEKBY5yzr4S RxK9tdHEn+MCAwEAAaOCAQYwggECMB0GA1UdDgQWBBRRUvkBTZ+jf0ao85VurNMQ v2QJdTCB0gYDVR0jBIHKMIHHgBRRUvkBTZ+jf0ao85VurNMQv2QJdaGBo6SBoDCB nTEeMBwGA1UEAxQVKi5zZXJ2aWNlLmNmLmludGVybmFsMQswCQYDVQQGEwJVUzER MA8GA1UECBMITmV3LVlvcmsxETAPBgNVBAcTCE5ldyBZb3JrMRAwDgYDVQQKEwdQ aXZvdGFsMRAwDgYDVQQLEwdQQ0YgRGV2MSQwIgYJKoZIhvcNAQkBFhVwY2ZkZXYt ZW5nQHBpdm90YWwuaW+CCQDjxRUTMitnVTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 DQEBBQUAA4IBAQBk19J3yfMb0DEC/BBDlHUyGvvsLr0PVbZGtYT7qxHkqOQBFz1k q65aeNuT8D0GSMy6gfF64cRPp3A7a8NfeYsSoynufMHMaMKEzlYjSyNGwDcxyRwv eQ7w4QeX9EnRCBf/JQdC9bIIs9IoJAgNHhEZHnzdnt76NX1hJ+w8SVTgi5zdQknr v+wroKbStKy2R5qxnW1bPgt6AtMoE3M/ZUj+DNQvU3wEcTasWuxvDUOhZfoOM0Rd UxpHKQp+6PPugE59i/xg/Vm53FrAQ6+4Tn6w5jjtWBszH8OxFkyD+mKhKsh/DkfV kXvnbnHRmaEsQBbnWkhygDws3S1YT8/vTZBw -----END CERTIFICATE----- ca_cert: | -----BEGIN CERTIFICATE----- MIIE9jCCAt6gAwIBAgIBATANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDExBjZi1u ZXR3b3JraW5nLWNhMB4XDTE3MDUyNTE4MjQzNVoXDTI3MDUyNTE4MjQ0MVowGzEZ MBcGA1UEAxMQY2YtbmV0d29ya2luZy1jYTCCAiIwDQYJKoZIhvcNAQEBBQADggIP ADCCAgoCggIBAMQr/nlMLZYXNEpe1DCnkRoTmERogDJM8/PGAMQrwy9S+m/EV2Ju 0BryTq0JtOpdJPy52p49efc36K6N69z5ednssJNmiSMCF1Ia2EqCnuE0at5NK75b yB5fOY7LW9ZCHjttbqs+xQIFzPLJNJlLeIsKoBqbTnkopMOwy/Z7VcHt7+vAG3H+ KU7zyheleD5g6INFJK8TolhrHDdkRB7KxSssqEzhLXUtrBD2pzXSayboTnIA1Y37 Dnlv0nqVTR7YDbYZMkbr4CCd08fgChp+vE2WwPyFyL1EF71exQNNoKbs91ad+pvx jMGLj/ii8p13X30VBSWdsKbRKJvk7Q/vWx7tJkKfa4mMyPwXjWlWTjccCbflDqgz /CsMkOYK4vZySFfETyzcz2J++kejxnugEmD6AmUV+6GdyHWPdi3CKsnVwJFVm2cI ZiCshFjwKjp6yws4n3JcqmzFdOGY8Ij2YG4qjKCLrvaZIqyDwQ9fRXKTVNF3bmlm 8BAAsUhCbbtnnAFOPnadliClhJiXHM0NIB38GCZa0tuno2vAncGrfDaX4pNQL0t9 gS47wgxKEfK3WNe37JcOtwk8oET4PeTugiVWmcvxCEDwOXCvNBQOjv8HWb2LBYJz njW4q7yNmXtfsS9InwBq3mRxRgU6UjjppT8hQDubpUCFARj/pQa/+PdfAgMBAAGj RTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQW BBTKGOy47aC2jl6GVjNI/yaqpAlJEDANBgkqhkiG9w0BAQsFAAOCAgEAHXT0ch9V W9BJisT+rxBLsqiNrry6bxTFVbktG/kU0B4oRgYosAl5Y5rWHByFavZNuQ9LP4gA OVuRxs4vrvX+ym6/m5OCs7zVvunpXh1CzfpifXLTzQn5YNXxBSCBSxTF4vInES1k wg6uwnVFLO+7kTorPfizp3lO3ydI8DpdUr3KWiAP9QthSJav8TAVopgBqdVzQFNs rLD6Rr//4oK0i1c2escErwXbAWR1d2PIDl/z9h1PtSfXWOSb36g5JshFwzvWInXQ 65EQJvnxBoETHkGmwINE4Y1iy++duXQCF28gPD0GtesNqrTbJ91e3CHjI1thpre1 R0E+nlF5AXY865ARKGDJwdsQ2oGqLRCUZqaUHatZXON6+o5lOgzJ5W6vqciolX+y 3NrGZMWTBFnWziaXTAh7QspB8ZJwKEudIEPYBBqA0BEA/0SAxsINIFpeTipofmIV z6Gn/tv+77dzW3GoAiaDuRCCpR2HvQJEo3YQCcAKWOvYD3a3LonOD9VwPT6jlKRj nCYJNHYd7d92e7ykfsDq29PTtxzCAtZ2Nr/IqhZZmrI8aZftZ0GLq2BRcBnBeR4P pBiWkZMn4//XACyFzIBtLgkqua+JXgReL3qzYqToXk5AUv48Z7rfz0YAJ6azFeSb 9MkVxlFa6Wls0/oHBMciwq787gURtJwPRHE= -----END CERTIFICATE----- server_cert: | -----BEGIN CERTIFICATE----- MIIEmDCCAoCgAwIBAgIRALjj0Acllm3jlXp/DGQs8dIwDQYJKoZIhvcNAQELBQAw GzEZMBcGA1UEAxMQY2YtbmV0d29ya2luZy1jYTAeFw0xNzA1MjUxODI0NDFaFw0x OTA1MjUxODI0NDFaMCwxKjAoBgNVBAMTIXBvbGljeS1zZXJ2ZXIuc2VydmljZS5j Zi5pbnRlcm5hbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALhD9bG4 ZSq4wuVnoMpK7tRqHyvq8Eaif0zojnkqNPIX1qpeypUyN2Tv+uvg/2yyhwlm4hcV 3kVNR2vxLhyyl4R7CjGvn5rtu36mr8FPzlXu2z02ceEKZLmzWeoL5eRknyDT4Qov DxOtY+WB9SO4BsUwjzmC4rrNZ+8keF8vApb9lSZQC6zNRcbcHoWCJpkvUAjY5kAS Uvrtf0jZGxJKEXbwVm2TRAFIrcoqQQa5UTOb8jpXo8ufdlXL5VXeAvQrzdRkLFUd RiZ8LIZMaPqm1lvYjXDKV6GikHgO+B5yusl8QZZSc5e/gzNHDZ5bQMSHXNNZ6xS7 N5rGUkPgq3AklnMCAwEAAaOBxTCBwjAOBgNVHQ8BAf8EBAMCA7gwHQYDVR0lBBYw FAYIKwYBBQUHAwEGCCsGAQUFBwMCMB0GA1UdDgQWBBR4E2bqAlWfsfSRuT3Y/LzV 7sgLJjAfBgNVHSMEGDAWgBTKGOy47aC2jl6GVjNI/yaqpAlJEDBRBgNVHREESjBI giMqLnBvbGljeS1zZXJ2ZXIuc2VydmljZS5jZi5pbnRlcm5hbIIhcG9saWN5LXNl cnZlci5zZXJ2aWNlLmNmLmludGVybmFsMA0GCSqGSIb3DQEBCwUAA4ICAQCMO5di StwKQnFy/eiOz9JgqDmkr/jR3n9ZlqyrTyafDR6dVkLJ07Lw6Kj5OsiBp+3dJFTE EBx9kWX7F7kX6EzYmimPALf0qMgtcl6SglYn5pUXRNYbx3N1VLe54zLyBcXZaMLP WWbzzEap9tSpoFIqaTaBAJpCD5oIG6SyjeAEbJy0RhBZVH4ARZcabPz1ghy5gQYR Gs1LqaOBwwLDER+sptRFvzQpE97NpxGLZs+BbTTkj+jYyKHBi85ztCjpb8WW+BaC pasqybl/PdQNjGpLW7jw0ql/HTd2hF1bQ0ae7JPhc9eMPMYFtQiPLvAEkEGLjXbX UMyBLh/9O2tMC45btIS86cDqpq1FI1PaCwxgRWTCQgXZtO8HouD6koaMSlhOLjEh N2GpE4FaHDZiteSujJrU5KAqoC5nrtyQfBSdzzb50i78XHhx+XR90Emr8BpM9l2L PDxomViysgy0HqcmjCoS203OOGMo2CFY4jxhzBhOmyIsThr6s5HJPtIQ8tJPjjow KN08ci8JWvwxAEbUM6ecqV7jlT5oABbjwviTHwSLiOq9957HAB+7GCIN+rMhl+Yx CQQaWE83Nd7GaYtxpjJGVjM1vXkEMFo7Aq0E0lVgBJSenQi7MSPT+igvlsiQNKPd dX0iSKMxryPEYTtl9ce4uUlzwH9Wu+wkM1NPiw== -----END CERTIFICATE----- server_key: | -----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAuEP1sbhlKrjC5Wegykru1GofK+rwRqJ/TOiOeSo08hfWql7K lTI3ZO/66+D/bLKHCWbiFxXeRU1Ha/EuHLKXhHsKMa+fmu27fqavwU/OVe7bPTZx 4QpkubNZ6gvl5GSfINPhCi8PE61j5YH1I7gGxTCPOYLius1n7yR4Xy8Clv2VJlAL rM1FxtwehYImmS9QCNjmQBJS+u1/SNkbEkoRdvBWbZNEAUityipBBrlRM5vyOlej y592VcvlVd4C9CvN1GQsVR1GJnwshkxo+qbWW9iNcMpXoaKQeA74HnK6yXxBllJz l7+DM0cNnltAxIdc01nrFLs3msZSQ+CrcCSWcwIDAQABAoIBABWsCI2qfluT93g7 w/GG9qgNAzWLIE9udUJ6Z6dgi3Gd1CWdmH4LtfAtOXncsK38IV29uAG3FLlZ6XiM mTvO1XtDbWOCoGb8ZvzyZeF6nW4F9csxSBuLuWUN7xlT5OoD26NkyCcGeeN6lTE9 I7PbxRAUMgQ1nK0T05GQ3Id1Y/yWC4ZQnY5oKziFU0d5+aIDfegm82i8+ZvOTpOK FEnqf1XWQEiW7P7+Xd2eUG8k/vHJ258GtTJqvl2sACWJE2vuAM7uqENds0K2MToG d8VNrYD2mdrNOO6aR/Ho1uZ021iUzrOWKbzf/LrHzhwKB5M4HABJpmqoDviMIbKB ourRB8ECgYEA3kA/VYwEfGGWp0yHW0II/dHAUr9+Zb6xgYEf3rT9HPW+D8Blf3b1 zGOlclNzu781yKS1w4XqpU6OIC/qZpW4F/alomDbscJIyWVd/SmMolbhELCoGjGt 9QvRiczx75hntZDLNJkORFopXVen5HITR6FMzXEA7iEzYx1akYGQXvsCgYEA1D8R x0xNLt6LWdYZLgwvfYkrDoffLJQM4jgXkHVA9QZkKCjjL9GNTjRLvz3JKvM+Qsvj 5QR6vEpAXd+iRoPeOxUo+kb0tKj333fTIKHCj/78LSCc3lLBPigP+D0vbiZQfFUT fZlFc6FNOA2SKUQ/xCT6KVHxf4Y5c8dtFBJRLOkCgYAWqQJMHJyQefq8UAc0/MSh 7HLpfPDMOucqRxoSwO1VuJCKVpmCp4RkNHy37V5NdC9tp62Io+zKsfm3umrxzq4Y c2Nr7Og5dY+qSRWOLGBUZPtJkllxYkNUSsIwhJ7eSPG6B2tQj5Ju0aqKA9fwaNki YoXMJIttvCDbKDEFyOoJZQKBgBh0V9kNqoru60FjkK0kjEg7iLF46DbbrAxYiCaF zAEvRlT2OQ7mZxCOp/eV59rCAfdyRIS7mmSdbYMjZDAZu341Nu53RHSYT075IGNP H/q1V1rfuhNHl6pQtV5VtmRLl9RrfP5orX7gI+SEc8W7bllsJUKjhV67GV2EqcW5 Qo8ZAoGAE07gkzFre6eseBm0lzdHoJoigKw4WXw0LG5tjOBqHZAUFpIikIhbY2eo R/22aXTo0PPbRnsSOk4Bf6SOIcSy1XNY1Zx9j59/n4okCfJTTfaPBNLExLUTdw0q pHvp1lIMgtuEOWGVUuT3XYOKEIjC8lN6ddpdwK6QQXhgdqhw8KI= -----END RSA PRIVATE KEY----- database: type: mysql username: network_policy password: admin port: 3306 name: network_policy host: sql-db.service.cf.internal # For ETCd: etcd: machines: [127.0.0.1] require_ssl: false ca_cert: "" server_cert: "" server_key: "" client_cert: "" client_key: "" peer_require_ssl: false peer_ca_cert: "" peer_cert: "" peer_key: "" cluster: - name: database_z1 instances: 1 advertise_urls_dns_suffix: etcd.service.cf.internal peer_ip: 127.0.0.1 client_ip: 127.0.0.1 etcd_proxy: ip: 127.0.0.1 cf_mysql: host: mysql-broker.local.pcfdev.io external_host: mysql-broker.local.pcfdev.io mysql: cluster_ips: [127.0.0.1] cluster_health: password: admin admin_password: admin roadmin_password: admin persistent_disk: 10000 database_startup_timeout: 120 galera_port: 4568 galera_healthcheck: endpoint_username: admin endpoint_password: admin db_password: admin ip: 127.0.0.1 seeded_databases: - name: uaadb username: uaaadmin password: admin - name: ccdb username: ccadmin password: admin - name: bbsdb username: bbsadmin password: admin - name: routingapidb username: routingapiadmin password: admin - name: network_policy username: network_policy password: admin - name: network_connectivity username: network_connectivity password: admin broker: host: 127.0.0.1 port: 19284 db_password: mysql-broker-db-password auth_username: admin auth_password: admin cookie_secret: 94046872-2602-4ca6-8d07-8b0da9762477 quota_enforcer: password: admin ssl_enabled: false services: - name: p-mysql plan_updateable: true id: 44b26033-1f54-4087-b7bc-da9652c2a539 description: MySQL databases on demand tags: [mysql] metadata: displayName: MySQL longDescription: "MySQL service for application development and testing." imageUrl: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAJo5JREFUeNrsXQtsVNeZvvPwzBiD3zyNwxgWhEKqmEibR9skdhQtaao2Rqtks4+qthKp1e5KxKhVCg3BbrKOst3lIW2rrUQVR5W2adgKp92ikG1ik2RbkpWCs4WWQomHVyAY8NhgPDOex97v+F4zHs97zrlz7z3/Jw1j/Ji5c+/9vv9x/v8/DoVgK9Rt7/arT37tv7XqozXT7zorK1clotFgYnp6PMtLDquPoPZ1YKxvd4DOsn3goFNgOYK3asRuUx81SQRvM/hQhpIEYlz7f1AViGG6SiQABH6WHMS+U/u61SKHDxGAp/CxJgzDqjAE6aqSABAyE75NI/iD2rPfZh8xoAnDYdfCquEr218coqtOAiC7K9+hEb5N0tMw5PBUHE5EpgcodCABsDvha5MI36HF8YRbQIgw4PR5D8dD4QEKGUgA7BLHg+yPSWzli7sx3e4hxeV8w11bO3B5y7YAnRESAKtZ+i2KdZJ2pobT6x2Oh8N74SGQZ0ACYFbig/Rf18hPEHGzulzqP44BR0XFq1d39A3QGSEBMIOLD0vfSTG94WIQdHi9/a5FC/dSiEACYCgaXtjeEZ+aImtvnnzBQCIa3auGB0N0NkgARFp8WPqdiv3W6O1xM3s9gUQ40qsKQT+dDRIAXqSHa/+M5uqTm2+R8MBZ6dvrXe3fc+HJpylpSAJAxCchICEgASDikxCQEJAAZCF/DxHf/kJwZfuLPXQ2SACSid+pUHJPnpve6wk4fb7eK8/29pMAyE38No34bUQLCW9+t3vI3VDfe3nLtiESAPni/N3KTAEPQe6wQHF4PP2+tau7ZcwPOCQkf6dGforzCXPzAwurumULCxwSER/x/Ssyufuwbs5K35zvOauqsv5NfHJy7v+nQkoiFpOGEE6fd8hVU9MlS3mxQxLy9yg2zO67Fqpkdjox3FMlu3OG7M75pOcFXRxmRCGuPk8pielp9n+bIeiuq907+u2dPSQA1rf6BxSLt+UyS161gBEd5Hb6fGrcWmGqY2SioIkBhMIOnoOWJLS1N+CwMflRzLPTilYf5Haprroak7Jns5G9EFGIh9THjUklpopCIjJtydyAq66md3Trjj0kANYgfq0W63dY6CZTXNWLLE/4XIAAxCYmlBgEYeK6xXIDvgHfujVddlspcNiM/G2ay296q8+sfHW14q5ZlDMxZ1dABGLjE+zZCuGCw+NBbmCzneoGHDYif4/m8pvb0tfVKupNJCxRR2JgiLfWa5cEocMGxDe9yw/33l1fx54JuREdC86KgWmv6aKFA96WVZYPCRwWJ3+rRn7TZfnh4rvr6hR3Y/3MLDtCUTkDiEF0bMyUCUSH2zXsaVrRdekbW4dJAIwnf4dGflPF+1ib1918Al+vIHrlqulqDpAXUK951+i3nh8gATCO/Fji222mYwLh3fW10ib0jAJqDKY/G2UrCabKC9TVdFtxqdBhQfLD6neaifgVS5fYdunOzOHB9GeXmWdgmnuhvq5f9QS6SADEEN9UyT4ivnmEIHL+gmk8AqvVCzgsRP5BxQTJPsT4FUsXk6tPoUFmEahaMOxb09JuBRFwEPnzPFGqpfc2NxHxTQ4sHUY+vVj2VQOIQHzyZrvZtzJzmJz8ID0q+/xlO0Eul+JubGBWn2AdwBvAqkE5i4rUeyfgWblis5mXCR0mJz8sf9nW01C441mxnOJ8K+cHVG+gnAVFWCb0LF/ablYRcBD507v7ID5V7tkoLDh3oWzegJlFwEHknwvd3afqPZt5Ayr59bCARMCkAlBO8oPwnuYmsvrkDUglAg4TkR+kP6qUIeHHYn2V/GT15fEGIAJlyg2A/KZZHXCaiPyD5SC/Z8Uyxeu/jcgvEXCtcc1x7cuAVmfVgsGm1/aZolnEYSLyG7rOz9b1V91GffmSA81F4TNnDa8bMEuxkBk8AMPbeVHN51u7hshPYPcA7gWjcz/xyZutoZOnXyn35y+r36s19jxp5Hsiy++9baXicDrp7ifMeIPqveCurWEOceq+CEJzEdHo+kWPPeq/+dbgG9IJgNbS+x1D4/3mJqViSSPd8YSMnqHD44F1VtmZMCoEaV20+cvjNw8NHpEmB6AN8zhg2IdE0me1n1x+Qv55gU8Chi0VsnkCNdWbyzFUxFEG8hu61g/Se1Y2EfkJhbnnkWmWHDRqAlG5agScBpNf7+k3jPxk+QnFEbLC0HsnEYnURi58+orRy4NGZ8IMy/jr5Kf1fUKpoSPbg9EIEYjGWsMjZwxdGTCMHdrc/m8a8V6Y1uNBpp/ITyhVBLBCoN5PCAmwzZkBnsD6RV/9kuPmfw8N2SYHoO3YM2gY+Zub6M4lcAfKh42YQajNoGg3YgcihwHkR0wzYkTcT+Qn2EYEPJ5g5fq1LaIrBY3IARiS9NMbeggEkcA9ZsSeD0gKGlEpKDRI1op9nhH9IVjCDw09VN1HMACummpWLCS6f4BVCgouEnIIJL9fmWnvrRVOfsr2F4zmqoXKyqrs9e8TkYhyPHiVTlY6csZirFhIdJ2Ael8H3Y0NGy9v2RYQEjYLPPYDRH7jUV3hUTbUNcwSfENtPftetUf9fm1DSa99fvKGcm5ypof+t6OXVIEIqwJxTf3+dfX7N6Q6z/oSoWgRUIWmNnr1GkKBdst4AEZs1U3lvTO4b8nymcfiZSrpF6mkX1iW45iYVr2FsatMGNjz5Yvse7b3BNQwIHTqtPCyYXddrZAtyR0CyG+I6y9rOy8s+6amVYz0eDYzED4cunBWOXT+jK1DCYN6B4IVS5dwDwVEhADCs/7IxMpG/ida1iqP+9cy4lsFCDnw2LphIwsf9p08prw+csp2ngHuxYoVy9gSoUDUxsbHuYcCXD0A1fp3agIgzhVqbCjXKKeyEX/rhrvK5tqLCBX2nTyu7PvjMdsJAaYOY8NSkXDVVHddeba333QCYETBD2qyEffL4urvuvsBS1n8QgCPoPvDd1muwE4IB84KHTaKVYHKDeu5FQjxXDjfLZL8bLOOVc1SkB9u86FNm21LfgAezf72R5mHYyew6dICd5LCqkDo1Ce7uYUvnKx/m/rUKfLEYoCnLMt9P/7iw2zpTgbAy2m2SXijWWh2r4pEIhLpXLL3pTYzeQBCl/wQ88uS9INFXGkjQuQD5DjsBDaERmCeCqsN0avXdppCALTEX5uoD4u4H4k/WZCrOs+u4YDdgHtW5KThRDTa1vjyzs6yC4BI68+265Ik7ifYD6J3m4qHQjvLKgBaxZ/fqieQQBCdDxDZoZoIR/yNfc/1lEUAtGW/LcJcf9V9oo06CVYH7mGRIWx8KrSllDmCpXgAaPMVsuwnWjkJBCMhcrt5LAuGPwk8Y6gAiLb+5PoTKBQwxgso1gMQZv2R9ZfZ9UcnnXSfOXhNilBA1H1dihdQsACItP5MKVfK7fofunDGduWx2YB+gF3HPpLis3pWLBfm2RbrBRTjAQiz/kiWiCyjtAqeev/XUkziAfkff+egFHMDmIFT721RCcFivYBiBGCLqJODZAnhFjHQNWdXwMvZdOiAdCPHWEJQkJGDF1BwaFKg+9+pCNrO29u8UnF6vcR+DeF4TBm6dJ5N2EGtfLNNKgTRBdgzfETpOfqBNJZ/ntX1eJRYcFyAG5DwVd5/35nQe0fy3l+w0IEgQqr+ZE/85bKUj6sPiMBT6+5gvQJWbBTaP3JKeT1wSqr8Rsb7HQlB9Z6P3Zjk70l7PeBof96/X4D1F7alt2+NX3FWVRHb84Q+Duy+JctKHvQp0tKD7G9qSU1ZrX1Gd31yUgmdDojxMCorN1/d0ZfXVuOFeABfF2X9ify3AAs/Homw1YBsXoFuSeENQBAwCRiDQfFcDg8Bx4PlvN8HZwaC5jslGAK2aeUqaVYCZkmq3vOivIDE9DS4mpcA5OUBaIM+R4RYf0mHe2bC1jvuYjP0QKJdx48W7TJDFPQR4ez/i5fN+VkhQKIOewTMfH2NWXN9FHixI8ER0qAN+HFV8FiYM3hQumuNicJTJ04Kee2KpUta8hkgmq8HICTzjy2WiPyZCbxffYAc+9XYGcM0C7XIQDZPolyf6wn/WkZ82cGWBVUOiNhrMHb9BjjbzUsAOoUIgER9/qUQBo+ejfey8dqIqc1G6nzcfBD+kaZV0g07ycNSCxGARDjcyUUAtOQf98IfFvuT9c8bcOdBIt1ysjzA6KU5+QAzER4JSl28ZBlvVqwXICIXgMKghhe2d+RKBubjAQhJ/lHRDx/PQNmwcTZOR+YdMTr6CRCnixYGEB1bjuE4mhcsZNbdzoNMxXkBi8uWDHTnsP6w/B28DwyWnzL//MnIMuppdgtKTuLBayhKcEpIIhJy8KFqxhvmvsdgItEBDo/17Q4W6wF0iPjAFPtnBjbcFCEOZiYv1QjMcIL3zkLaVmXgcH9G8cnxGtyz/3rmk5Aedtw6Kxfs3POQtwConBDRI+D0erNy2JnF/ferT638P2gdsTyHNew5ekSaz4sSYSoPFseNeDjcumTvS/5iPAAx7j9Z/7y8ALQE290TQKETtgcjiOVGNBjsKEYAHuN9IGiCoH7//IC1/nt/+TNmIe2GmVbgAenKf/MJj4U0xcXiGbnsyOD+Q4rGeB8H5qKRB1A49LJZ1MxbeU0dooZ4n1z+LNZ6LChqm/G6dKsBbqPcf4xCIvIXh3PaTrrVRz3KI6oIYKkv3XKfGYElSHgxIH8xPQMyhgHTn17SM/jc4PR5064GZBKAB0W4/4T8rH0moiAngPyA3hegFwNhjd4sy3vHWTfgrQrFfPIY2T6zjABXeJcHx0PhBwsRAO4egKummq5sHni8ZR1rloHFz+Uqp5YBY70f1XjoANxQWz/bDSgibNDfF4VFekdgoa49iI/dgdnnlrAbMBtXBPQHgNNdOXMAavyPpb+jvN3/yg3r6crmAb0dWCdZMZ2A6ZDcGjwjFqpAeLx5Ex0otvU3FakdgbK2A2fD1PET3MMAFRvH+nYP5/IA+Ft/cv+LJgoeSACiCxCxdLFDNFN7A4xOxMHaI28B0pt1ipHdwwCHpwLczikA/ON/cv9LAtz6p9dtYA80/Ohjtsw+aksXsE1NtxHpTRAGJCLTD+aTA2jj7f6TByBGDAB4BL8fu8ae0QlYriU21oxUV6/cXjuTf6CGIVN6zW1ZBUCN/9t4v6OzagFdTdHEw8ANZe0cdx8twfAWzt28Mc/l19uFC7HkqbkDllNQv8a4chryIU4EYhPXub5mY99zbVe2vziUyQPgXvtP7r/x0AeFzlWKjXRirCYAGBTCWQBiNybB8VkBcAqP/6nvvyDIWCVX7IwC+3sAQoznHI47RXoAqG2m2v/CBcBqM/9KAcKUfX88RhfeOP60phUArf3XT9a//Oj+4F0pRACJSxm6Hk3GIb/W6zPPA/DzfifnQhKAYgBCgBiYC2BXcqApCBugyrY5qEk41JpOANoo/jcfSfSWYLsIATwbtALbWdy4CoBPyOTsWa4nrwLcyTV+cbko/ufkDSR3Aj61boPlimoQ52Nj0P0jJ6npp1ABqPQxLnEuC74znQD4eR84ga8Q6J2Aelmtmefu6/sWYDMTcvNL5xLnseH+dALAdQWAxn4XB73CL9ugTFhR/Fz/ndQqPKM3CAXZZ/YkKLwaUW8MotFg2bnEWQBa5wiA1gHIXbUIhQNVdugGfHrdHcqu4x/l1Qk4QzxY2VPzyJX8rG/eke530pE61QMBudn7aZWEhVYUpr4vPud92v6HBGO5BM6jM1D3ALiP6hGUvJAGK7VeeXQCFhs/z/bsm4Rg8EqsmscoJxwVQnJptckhQBv3g6YEIDchgKXEw4rjtXTSW2mMmQwegMb5IV0Aani+sovW/4WAxfobG9hOwee1CTy/Hb2ouuLXTJNoQ4LydrY56HK2QShZen4iwHnrsJpkD4BvDsDppCtmgGeQvFuw7urrHYA84vRcMbz+rHcGGp18lC4M4CsArckCwFmtKumKlQHZevB1MZjzfy2pl9GapyQNqfW3nB5AJffOQGE5AIeLPIBigbl7omLxVIEwS0x+noqDysEpxnkhTKUlwOLx5vkz0pXIYpWDUB5OObUuQM6v6qIrViRAfjTJyCICW/MYf04QA3AfHgB3ASAPoDQgo2/3Tjm94/H1EbL+eXFKTGWtn4J1E4sA20Dz+FHbeQOoZUCXo0yDT8wKJAG5VgGic4nAD9hBFxNznmhZy8qDrZqF15uZfnzyGHUElsAtzl2BtRAAvk1A5P4LIY/e/MMmAKti8EjTKtOLAY4b3YDYx4CsPR9u8W4KctNptV5ocPzoVTZQA1V3M5uDLldur6sve9Wd3hE4s2nJJWoDtkgIQLAo4EqfG5m7d2DyBqF6IQ/PAp7k6kIUEhW7MSiBBIAgykNQH5lcbngNK6sK23VmIhIha04CkGecQoNAzO81UBLOmjkA/oNBFFoGJBBkFhU6BQSC3AJAUxoIBDlRQx4AgSC5B0AVGgSCnBgnD4BAkNwDIBAIJAB8EJ+cpLNKIAiACG6RB0AgkAdAIBBkBPUCWAzYOxDbh6UiWzMO1fITsgnAMNc4he/sckISdt/9wJx9AOZgw8aiX5ftJZBlGrG+10A6YGAJwaAcAH9usb0BgzxfkfPEEoIyM9J7/0OPCuv3X1m1sOh2YaO2/27Wjk/mRiYB3ApSCCA5+UsFPBIMKBEJjEPDRqm6N4IJQwh5aMpQ6XBoY8FHeL6ob42f2oIlIL9OyHv/62fCXh/7ICLvkQkQAgxOtftAEiwBhk4HeL9si3Osb3eAqEbkLyV8EHGM+Pw//uLDWckPYCQakpyEwgHuC1kGpERgaQCh3tq02TI76/IeTorPDfHLZ+syWH8ZVjhEcUrPAQwpHPcHTMTixOISb36r7LKLEIBnLA6LDsufz+cH8WVZhRDAqaFkAeCsVlPEZAnID/Dc1y852ZcLGEr69Pu/lubeEFVirwvAMFcPYHqa2CwB+QFsWsIDWWsc0rn+quWXaUlQwBLgcLIAjFMOoHyA5UO220rkZ7P/Ry+VvG1ZMclOvDc2SZEJAjg1npoD2Mn7gGmXIL5ur2hgzz7dpTdiWQ2kR7xfSBIRgoMdhYn8fHMAQd6vzsIAEgDLkJ+RfvSiYevpyPDvvueBgr0e2Vx/gSE14zxbBhzr2z3M+9UpDLAW+QGjiIW1/Xwz/cnAaoNsrr8oLumcd6ckBbhtFDqTtVxMTE+DrXfcpWwtoXlHFHo23qPt73ctZwyeDfrWYeni/d6N9xaU7Et2/bs/eFfK+0XACsCswU8WgABXASAPIC0KzXYbCcTkeOQswCmDeIH8pSYcyQOYw3VlNgTQ8DHXuCUWIxGwEPnNjEMSby8ODglYAvw4nQAMcT/4EAkAkb80yOz6C+TQ0DwBqFi6JMD94G/QgFDEvUR+cv1NxqHheQJwecu2QHJswAMxySYEI7mX2r2G2nYif3FAxl/2nn8BHAqM9e2eXfZ3p1EGP7c8QGSaPRyeCqlcfFis10dOzcavKLAhESgMWI2QfdyYzh9R1j81BwAc5q5gExO2d/EPbeqYQ3Cs7yeXtnZ/+K7tB1Zwd/0/lNv1F8idwxkFwLWwintBUMzGeQC9gSddHXvq9596/9c0mbcA158EUxh3MnsAV7a/OMRfxa7b8uIgts/WxALPYNc9989Wu+ntq7JbNXL9y8sdNf4fyhYCACQCOYAy3v3tuVt3dQ9BB0ptH3/nIIlAFjxFIimSM/O4PU8AHJ4K/nmAcfvkAdC2W0gNP0Rgd9LvIwzoOXqEmJ4Gsoz3KiNnDucUgERkeoA8gPTAEl+uIZXpgARh8t9hhYBEYC5kGu9VRs7M47Yr9Ruh945cqrz/vmfUL/n18iYSirOyUnF6vZa+KH+aGFfalq9UlvgWFPy3+LvzN2812nx0dVRprlqkbKhroLtdxdcOv6WMhmiUnE7+6Bj3Dv2gGv935/QAMikFhQHaMIoP3is6RkX4kLo8SC4vuf4GcSUtp9MOBXX6vIfjoXAnhQHpXVUk8rD2Xyj08VebDh2Y7b3Ha1lh/n+yCKLdt7RzeG2OiJLrbwhX0ub2HOm+Wbe9u1Z9GuN9BJ7mJsVdV2uLi1TKQA9dRHQSFDsQFHmEXL37qTg/eV3q/fXMDrj+kXMXRLx0XXIJcFYBAOqf//ZgIhpt43kErupFitd/m20uVimDPVDo8vjgwdn/QwTy9Sr0DjnaG89+CAfOivAAhlTyt6f19jOz1fmGCNdGQG1z+WJX1XXdP1LcXHwUEqUuD+Yz7BLkZyEIkd92ADcEuf8ZuZxRANy1tQMijkRAdrOsKCWRl255MNvMO7zPvb/8GSXMbOz+C0JGLrsy/WDyzbeDVQ+3dSRisWVcVS4UUiqWNNrqwv3i7CclLQ8ijj99fWZrhqFL59MuD8LiU5WcvRE5c44tmXPGsOr+v1ywBwDEw+G93N2cWMx2XkCpy4MYj528CrCTJfduWXmEGUR++1t/AaO/gKwczrU78IDD5eL/Ya/Yz4UFYZ/Kc686NLwgCXhey8bry4PJjUOI8/Fz5AW6P3yXGGJ3ARDHiayhfFZ2h947Eqps+0KrEo+v5+oFRKNoPVYcHo+tLiIIi2q/bFN12XCQwYPK/sBMvA+yIwzwqkKLZ4QT4XiMPfDzQpf5CNYDxn5PX74ihPyq+/9qKR6A4qioeFXEkU1/NmrLi5ktkQcvIdWaJ/e+s8ahex4gRkgGgVzIyd2cAnB1Rx/CAO5BO4Yd2HVsOAp00i0PHrpwNu3vY5NNHWzLrLtJBKSx/ioHBA3+QO3/QMkCwLwAr7ffYnFP2ZGayNNj/XRI/T6WB5+gGYIU+5eGvDiblwC4Fi3cK+TDI/Npo8KgZCQn8nSA1Kk1/yB/OrKjzBjFQgR7W3+BK2J5cTavFD9qAha03889GQigLsAu/QGpQCLvt5cvKY+tWs2SfHjga7S9Vnu8yudVgv/wvoeUxb7KeX/LtupWH3gNgj0ROXdelAFE8u9H+fyiO99XRDIwEY128D5SlguYnFScVVW2vMgs8ffBu2w3XN3i52oiQmKQBobY3Pqr97zAgbl5e+x5L/JPDb53YsHDD3YqsRh3c439z+3qBQCo8su1PKgD6/4/+MP/EUPsbv3PfyrK+gfSDf4oKQcwS9RwpFfEEUMJ7To9WAfc+WyNQyxnMHhwdkMRgn2Be12g9S+Io45CX71+x7fGEgK8AOweVLl+ne0vPkKBVE8AiULaN0AeTJ04Kcr6Y+mvrpA/cBb6Ds5Kn5AVAZwQuxYHJQP5gGSi4+u/OHSAyC8JcI8LXPkqmJsFC4B3tX+PiMIgAGuidl0WnOPqa9OAEBJsOjRATT6SAPe2wHV/cHJPoX9UcKfP9f/8RajqkYcq1Q/Txv8MJdSTFFHctTW2vhGwtIea/9cDFO/LBIz6ioeEVb++rLr/bwr3AER7ASxBYvOEIEBz+eSC4Pu6KOtftABcePLpoKhcgK6UgnqjCQTjXX/1XhY06HM29k838FOYAIj2Agw4YQSCoa6/QINWtPUvSQBEewGyhAIEcv3LZf0BR6nvXt/77EgiHPGL+GSYRuRbv1YRMZWIQDDC9Q+dOCXS+qPqr6WUF3CWegROn69X5AmkUIBArn9GlMw9B4+jELGJSDI8K5Yp7kbaRJNgHWC9P/LpJZFvkXGzD0M9AMDdUN8r0k3HibTr9CCC/YB7VTD5uVh/bgJwecu2IYfH0y/y04bPnKWlQYIl4n7cq4LRr1r/IdMIAOBbu7pb1LIgO7GR6ZmNEwgEM8f96j0quJwdHOvm9WLcBIAtCy6s6hb5ydFCaYBrRSAUHaoKbPPV0V3Ksl8qHLyPruF73xmMh8JtIs+AnbYZJ9gDArf1TgaXxF8y3LyP0FVT0xUPXT6qfimMoTjRTp8Prcl056UBxk3diknjRSdQMaPBqT5m3UWbjm0r+Xwj6See/LD6Xbxf1CHiSBd/v7dHVcSdIs8GVh28q/3SiQDiy8R0hN10M+SeUu9A9TkSMayVekYYPKoiONXzX6leCye7Do4KD/uZbOQPfxIwIkHdq1r/HksIACC6NoBZJPWmgwjYtVIQlhw3GCP79LQR8SUfLxDbvlVUsOvDHjb1HFjGXyW/AUvU3F1/YSHA7As31HdFr1w9KmJ8WKr62kEEGNFD6gNTkkMhS9c9zArV2FyxZmGbKg52CN8MJL8Q11+4B8BCgV0vPBO9cm236DNkRU8A7npsYkIbi35TuhoHXCtn1QLmLbiqqy0VOhhIfgBZ/z2WFACg4XvbDqgWrUP0+2BVAKsDpraM6AwbV0mvuvZ2H31WTF7BpYYKrppqVRAWmfpYkfATuKNPMrDBx2ahvBH9CXzr1nRNnTjVlohEhK7b6RfETCIASzFLemptzukRRSPB2esIEdDFwEyenYHkF+r6G+YBAEv2vtQWvXJ10Ag3t9yeAJGeP8wiBgaSH2jnVe6b9dwa8Ukm33w7sPArmxxqKNAm+r2QQIM1QbLJ4XQadnMgY4+Rz9MXLiqx4Dg2USHm8hJV9VwyUb02pn4dVhxulxoyeAwVdVxXA8mPJb9+Q0IvIy9k40s7DsSu3+gw4r2MSAwya6/eFNMSjDM3Y86gorFBcaken+hrbGDCz5C4fw5PjLxo3pZVXap6DxtikQUWaMDawx2cOn6C1X8T+cuTM8C5Z9cA47YnJ+1A/mEj4v6yeQDAsh/tao1c/GxQdFIw2RPwrGzisu4MFxAW3yoFOdLlCrCkqHoEPPpEWHnv+QtGkj+oxf3DthYAYPG/fK8jNj5xwKi171LLhkH86c8uk6W3UniwdEnRQmBgeW8yNqvkHzBcNMtxgW6+NXhiYceXxuM3px4xxl9MKNFrYyxxlK8I4OJHR68yKwCrr8TixCyrQL1WSBpGtevG+hTyTAjjb8IjZ9g9YyC6jUr6mcIDSPIEXlGJ2Wnke2K2IGYMZr0Jrlyd2cTRYtV5n1vepNyxfIVyW139vJ/97uIF5djFT5WzY9fk8whUD7Bi6eKccyWRUxC4d18mYLpPV9nOTbkvjlGVgqmxomdV87zssRVdfZD+m59/QHn09juUGl9lzt+HAPzPyGnlpx/9r/L+yJ/m/fyLLX+m/OLpv+dybPXf3WqJ0IBNnz5zrhy5HUMz/mkNYrkvCioFQ6dH/PHJm62GeYjqhQ6dOq14V93G3ENkkMMY4Wwh4sPK9z3awYhf6N/h8dd3/TkTgn/4+U+l8QrYyoF6nSHy3uYm1qXI4n3MmzT+2hue8TelAGCUWNNr+9pVERg0UgRwwSECTAAs1nkHK/2Tv+vKy+JnA8IFGUMCdu1PB8p57UH+dp6jvYqF0wwXBCKgkr9dOzGGwmrkh+WGi14q+YGDvz+myAzZyW8KD0AHTsiyH+3qMrJGwGpAvN/35czpkvHQFCO1nvDT8YXVa5TPLWtiz8nC8e+/eZdOqrFgDT5mIb+pBAC49I2tw6oItJMIpMe//eWTGS0/yPzy24eYCKRCT/bhb5EzePahTez/EIp88dV9P0ybNCQURH7DC30sJQAkAtldf3gA6YBEHrL6uQBxwO/BS8j0WgR5yG+aHEA6EfAsX9ru8HiCdO/MQLfaqdj+q4G8yJ8qBGTNifymFYBkEVDKkBg0Y+yfrrgHy3gUx5saw2Ymv6kFQBcBnEBn1QKpRSDTWv9/fPQhUYzIb18BAJAx9a1pkVoEsO6fDoW6/gTDyW/6ENZthbM5Wyx08vQrRpcNmwHNtXVp3X8jgaKhfHA2eE3K4qIkoKOvywrkt4wA6CKgPm0uRwNRuZEu/h+fmjL0GLLVHyTj5XcOseVISVHWxh5bhgCpGP3W813uxvpuu+4GlC9+d+mCQjAVuq1GfksKABOBrTv2uGqqN8u8TMijFJjABcwzFbl5BwlAek9ggNUKGDRj0GygQh5TQE/2DVj1A7itfPaxTIjkYHjkzCtGTRsui7t/8cI8wqdLDIo+holQ7uYZiRKAlkr22VIAgNnk4Pd7e2IT13facY+9c2Nj8wQAiUF8r5B6/lLw3V+9QdWDGhyeit5rPf/cY4fP4rTLRRn99s4ed2ODLcuHMxEP/QEEw+P9druQ31YCAFzesm2ocv3aFqfPN2Cnz3XwD8cyCkC6JUKCMJe/xYjtukgASgwJrj7/0mZtqdAW3oA+xy8VWAn4yd920YqAeKuPJb7NVo/3pRCA2ZBg6449akiw0eF220KxMxXXIA9Q6IQgeA4jO/6JhCM3cO9stOoSXz6wdTXN5JtvB6cO/+bVRV/9EjYmxbxBn1U/C0psQfa1i5fM+9nSRdVK1z2fV3wVFcq54FjaoSD6INB9f/U15W/uulvxuSuUd079kb1uut9LBfoOUn/X5lb/ZRT2hN47YutaE4csV3TJ3pf8sfHxV+KhcJtVPwMsNqx9rhoAhAwQAh1YMkyXK0hXtptpLLhEE4Fg9bG8F5Dhw7plEYDLW7bhgrY3vryzM35jcnciFrPctCFY9n/8+Wss7s+W/NNHf+cC5gQS5sX6/TJ9aKdsV/nKs739lRvWtzgrK/ut2E+Adf8H/+1fuXQD5tvhJwFA+hbZyC+lAABspWBHXxerG7BgkhCewFf2/aCkTT0gIPAmJAeuPUp5u+yY4accQJ5gYUEotDMRjvitePyI2zE1CLmBL7SsyZgXwKhwxPGoK8gkHFmTgPYp80U42CujxScByCYEfc/1xKdCW6yYH5gX36tigKQhle/Oi/P3qsTvoVNBApAWTa/tqw1/EnjGLkJAuEV89bFHVlefBICEgIhPIAEgISDiE0gAikLd9u5Oh9dj2WShBAgolNwjATBACNocbveWRDTaQWfDFECn3l67deqRAJgcrLz4+o0tiXC4k8KDsrj5/RrxA3Q6SADKioYXtnckpqe/riQSHXacSmQya/+qlefwkQDYOzyAJ9Dh9Hq3xMPhVjojXIDhm0jqDVBSjwTAUiFCNBjsUGLxxxLRaBudkYKAeP4NjfTk4pMAWN8zcPq8HfFQ+EF4COqDcgbzY3q49YfJ0pMAyCAIrQ5PRUciMg1BkNU7GEoi/DDdFSQA0qKx77m22I1J5AwgCHj22+wjBrRYHoQfpiU7EgBCjpBBEwJ4B3dqgmCVpOKwRviPNSs/TC49CQCBU+ig5Q8gDDVJomB0GDGURPZx7f9BcuVJAAjlFQh/UvhQy8FrAKF16x2gjLy98P8CDADMneNqQ66ddAAAAABJRU5ErkJggg==' dashboard_client: id: p-mysql secret: p-mysql-secret plans: - name: 512mb id: ab08f1bc-e6fc-4b56-a767-ee0fea6e3f20 description: PCF Dev MySQL Server max_storage_mb: 512 max_user_connections: 10 - name: 1gb id: 11d0aa36-dcec-4021-85f5-ea4d9a5c8342 description: PCF Dev MySQL Server max_storage_mb: 1024 max_user_connections: 20 nginx: ip: 127.0.0.1 port: 19284 ================================================ FILE: pcfdev-base.json ================================================ { "variables": { "version": "0", "cpus": "4", "memory": "4096", "disk_size": "60", "eula_url": "", "security_group_id": "", "subnet_id": "", "vpc_id": "", "ssh_keypair_name": "", "ssh_private_key_file": "" }, "builders": [ { "type": "amazon-ebs", "region": "us-east-1", "source_ami": "ami-6012160a", "instance_type": "c4.2xlarge", "ami_name": "pcfdev-base-v{{user `version`}}", "ami_description": "{{user `eula_url`}}", "associate_public_ip_address": false, "security_group_id": "{{user `security_group_id`}}", "subnet_id": "{{user `subnet_id`}}", "vpc_id": "{{user `vpc_id`}}", "ssh_keypair_name": "{{user `ssh_keypair_name`}}", "ssh_private_key_file": "{{user `ssh_private_key_file`}}", "ami_block_device_mappings": [{ "device_name": "/dev/sda1", "volume_type": "gp2", "volume_size": "{{user `disk_size`}}", "delete_on_termination": true }], "launch_block_device_mappings": [{ "device_name": "/dev/sda1", "volume_type": "io1", "iops": "1800", "volume_size": "{{user `disk_size`}}", "delete_on_termination": true }], "ssh_username": "ubuntu", "ssh_timeout": "20m", "tags": {"Name": "v{{user `version`}}", "License":"{{user `eula_url`}}"} }, { "type": "virtualbox-iso", "headless": true, "vm_name": "pcfdev-base-v{{user `version`}}", "guest_os_type": "Ubuntu_64", "disk_size": "{{user `disk_size`}}000", "ssh_username": "vcap", "ssh_password": "vcap", "iso_url": "https://pcfdev.s3.amazonaws.com/artifacts/ubuntu-14.04.4-server-amd64.iso", "iso_checksum": "2ac1f3e0de626e54d05065d6f549fa3a", "iso_checksum_type": "md5", "http_directory": "preseed", "ssh_timeout": "20m", "shutdown_command": "echo vcap | sudo -S shutdown -P now", "format": "ova", "boot_command": [ "", "/install/vmlinuz noapic ", "preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg ", "debian-installer=en_US auto locale=en_US kbd-chooser/method=us ", "hostname=pcfdev ", "fb=false debconf/frontend=noninteractive ", "keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA ", "keyboard-configuration/variant=USA console-setup/ask_detect=false ", "initrd=/install/initrd.gz -- " ], "vboxmanage": [ [ "modifyvm", "{{.Name}}", "--cpus", "{{user `cpus`}}" ], [ "modifyvm", "{{.Name}}", "--memory", "{{user `memory`}}" ], [ "modifyvm", "{{.Name}}", "--natdnshostresolver1", "on" ], [ "modifyvm", "{{.Name}}", "--nic1", "nat" ], [ "modifyvm", "{{.Name}}", "--paravirtprovider", "minimal" ] ] } ], "provisioners": [ { "type": "shell", "execute_command": "echo vcap | {{ .Vars }} sudo -E -S sh -c '{{ .Path }}'", "inline": [ "apt-get -y install software-properties-common", "add-apt-repository -y ppa:brightbox/ruby-ng", "echo 'deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main' > /etc/apt/sources.list.d/pgdg.list", "wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -", "apt-get -y update", "apt-get -y --force-yes dist-upgrade", "apt-get -y update", "apt-get -y upgrade sudo", "echo 'vcap ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers", "# vvv TODO: instead of doing this, use (or build) a stemcell for PCF Dev vvv", "sed -i 's/^GRUB_CMDLINE_LINUX=\"\"/GRUB_CMDLINE_LINUX=\"cgroup_enable=memory swapaccount=1\"/' /etc/default/grub", "# ^^^ TODO: instead of doing this, use (or build) a stemcell for PCF Dev ^^^" ] }, { "type": "shell", "only": ["virtualbox-iso"], "execute_command": "{{ .Vars }} sudo -E sh -c '{{ .Path }}'", "inline": [ "apt-get install -y dkms", "mount -o loop /home/vcap/VBoxGuestAdditions.iso /mnt", "sh /mnt/VBoxLinuxAdditions.run --nox11", "umount /mnt", "apt-get install -y open-vm-tools" ] }, { "type": "shell", "only": ["amazon-ebs"], "execute_command": "{{ .Vars }} sudo -E sh -c '{{ .Path }}'", "inline": [ "while [ ! -f /var/lib/cloud/instance/boot-finished ]; do sleep 1; done", "ln -sf /usr/bin/mawk /usr/bin/awk" ] }, { "type": "shell", "execute_command": "{{ .Vars }} sudo -E sh -c '{{ .Path }}'", "inline": [ "apt-get -y install curl unzip zip sysstat vim", "apt-get -y install libruby2.1 ruby2.1", "apt-get -y install linux-generic", "apt-get -y install aufs-tools", "apt-get -y install libgcrypt20 libgcrypt20-dev", "apt-get -y install postgresql-client-9.4", "apt-get -y install nginx", "service nginx stop", "update-rc.d -f nginx remove", "for version in $(ls /lib/modules); do apt-get install -y linux-image-extra-$version; done", "curl -L 'https://cli.run.pivotal.io/stable?release=linux64-binary&version=6.25.0&source=github-rel' | tar -C /usr/local/bin -xz", "curl -L 'https://github.com/cloudfoundry-incubator/routing-api-cli/releases/download/2.6.0/rtr-linux-amd64.tgz' | tar -C /usr/local/bin -xz", "mv /usr/local/bin/rtr-linux-amd64 /usr/local/bin/rtr", "curl -L 'https://storage.googleapis.com/golang/go1.6.3.linux-amd64.tar.gz' | tar -C /usr/local -xz", "ln -sf /usr/local/go/bin/go* /usr/local/bin/", "curl -o /usr/local/bin/veritas -L https://github.com/pivotal-cf-experimental/veritas/releases/download/latest/veritas", "chmod +x /usr/local/bin/veritas", "curl -o /usr/local/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64", "chmod +x /usr/local/bin/jq" ] } ], "post-processors": [ { "type": "shell-local", "only": ["virtualbox-iso"], "inline": ["ls $PWD/*/*.ova"], "keep_input_artifact": true }, { "type": "vagrant", "only": ["amazon-ebs"], "output": "pcfdev-base-{{.Provider}}-v{{user `version`}}.box", "keep_input_artifact": true } ] } ================================================ FILE: pcfdev.json ================================================ { "variables": { "source_ami": "", "source_ova_path": "", "version": "0", "distro": "pcfdev", "cpus": "4", "memory": "4096", "disk_size": "60", "dev": "false", "eula_url": "", "security_group_id": "", "subnet_id": "", "vpc_id": "", "ssh_keypair_name": "", "ssh_private_key_file": "" }, "builders": [ { "type": "amazon-ebs", "region": "us-east-1", "source_ami": "{{user `source_ami`}}", "instance_type": "c4.2xlarge", "ami_name": "{{user `distro`}}-v{{user `version`}}", "ami_description": "{{user `eula_url`}}", "associate_public_ip_address": false, "security_group_id": "{{user `security_group_id`}}", "subnet_id": "{{user `subnet_id`}}", "vpc_id": "{{user `vpc_id`}}", "ssh_keypair_name": "{{user `ssh_keypair_name`}}", "ssh_private_key_file": "{{user `ssh_private_key_file`}}", "ami_block_device_mappings": [{ "device_name": "/dev/sda1", "volume_type": "gp2", "volume_size": "{{user `disk_size`}}", "delete_on_termination": true }], "launch_block_device_mappings": [{ "device_name": "/dev/sda1", "volume_type": "io1", "iops": "1800", "volume_size": "{{user `disk_size`}}", "delete_on_termination": true }], "ssh_username": "ubuntu", "ssh_timeout": "20m", "tags": {"Name": "v{{user `version`}}", "License":"{{user `eula_url`}}"} }, { "type": "virtualbox-ovf", "source_path": "{{user `source_ova_path`}}", "ssh_username": "vcap", "ssh_password": "vcap", "headless": true, "vm_name": "packer-{{user `distro`}}-v{{user `version`}}", "http_directory": "preseed", "ssh_timeout": "20m", "shutdown_command": "echo vcap | sudo -S shutdown -P now", "format": "ova", "boot_command": [ "", "/install/vmlinuz noapic ", "preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg ", "debian-installer=en_US auto locale=en_US kbd-chooser/method=us ", "hostname=pcfdev ", "fb=false debconf/frontend=noninteractive ", "keyboard-configuration/modelcode=SKIP keyboard-configuration/layout=USA ", "keyboard-configuration/variant=USA console-setup/ask_detect=false ", "initrd=/install/initrd.gz -- " ], "vboxmanage": [ [ "modifyvm", "{{.Name}}", "--cpus", "{{user `cpus`}}" ], [ "modifyvm", "{{.Name}}", "--memory", "{{user `memory`}}" ], [ "modifyvm", "{{.Name}}", "--natdnshostresolver1", "on" ], [ "modifyvm", "{{.Name}}", "--nic1", "nat" ], [ "modifyvm", "{{.Name}}", "--paravirtprovider", "minimal" ] ] } ], "provisioners": [ { "type": "shell", "only": ["amazon-ebs"], "execute_command": "{{ .Vars }} sudo -E sh -c '{{ .Path }}'", "inline": [ "while [ ! -f /var/lib/cloud/instance/boot-finished ]; do sleep 1; done", "ln -sf /usr/bin/mawk /usr/bin/awk" ] }, { "type": "file", "only": ["virtualbox-ovf"], "source": "assets/keys/key.pem", "destination": "/tmp/key.pem" }, { "type": "file", "source": "manifest.yml", "destination": "/tmp/manifest.yml" }, { "type": "shell", "only": ["virtualbox-ovf"], "remote_path": "/home/vcap/add_key.sh", "execute_command": "{{ .Vars }} sudo -E sh -c '{{ .Path }}'", "inline": [ "mkdir -p /home/vcap/.ssh", "cp /tmp/key.pem /home/vcap/.ssh/authorized_keys" ] }, { "type": "shell", "execute_command": "{{ .Vars }} sudo -E sh -c '{{ .Path }}'", "inline": [ "echo 'UseDNS no' >> /etc/ssh/sshd_config", "echo 'PasswordAuthentication no' >> /etc/ssh/sshd_config", "mkdir -p /var/pcfdev/api", "echo local.pcfdev.io > /var/pcfdev/domain", "mv /tmp/manifest.yml /var/pcfdev/manifest.yml", "mkdir -p /var/vcap/store", "resolvconf --disable-updates", "apt-get -y install dnsmasq", "service dnsmasq stop", "update-rc.d -f dnsmasq remove", "echo IGNORE_RESOLVCONF=yes >> /etc/default/dnsmasq", "echo bind-interfaces > /etc/dnsmasq.d/pcfdev", "echo net.ipv4.ip_local_port_range = 32768 61000 > /etc/sysctl.d/60-restrict-source-ports.conf" ] }, { "type": "packer-bosh", "assets_dir": "assets", "remote_manifest_path": "/var/pcfdev/manifest.yml" }, { "type": "shell", "execute_command": "{{ .Vars }} sudo -E sh -c '{{ .Path }}'", "remote_path": "/home/vcap/start_services.sh", "override": { "amazon-ebs": { "remote_path": "/home/ubuntu/start_services.sh" } }, "inline": [ "mkdir -p /var/vcap/monit/job", "echo manual > /etc/init/runsvdir.override", "stop runsvdir", "mv /opt/bosh-provisioner/assets/scripts/* /var/pcfdev", "mv /opt/bosh-provisioner/assets/extras /var/pcfdev", "mv /opt/bosh-provisioner/assets/versions /var/pcfdev/", "case '{{build_type}}' in", "amazon-ebs) PROVIDER_TYPE=aws ;;", "*) PROVIDER_TYPE=virtualbox ;;", "esac", "/var/pcfdev/provision local.pcfdev.io $(ip route get 1 | awk '{print $NF;exit}') redis,rabbitmq '' $PROVIDER_TYPE", "/var/pcfdev/stop" ] }, { "type": "shell", "execute_command": "{{ .Vars }} sudo -E sh -c '{{ .Path }}'", "remote_path": "/home/vcap/cleanup.sh", "override": { "amazon-ebs": { "remote_path": "/home/ubuntu/cleanup.sh" } }, "inline": [ "rm -f /var/pcfdev/external-resolv.conf", "tar czf /var/pcfdev/packer-syslogs.tgz /var/vcap/sys/log", "rm -f /var/vcap/sys/log/*/*.log", "{{user `dev`}} || rm -rf /opt/bosh-provisioner", "{{user `dev`}} || rm -f /var/pcfdev/manifest.yml", "apt-get -y autoremove", "apt-get -y clean", "service dnsmasq stop", "/var/pcfdev/reset", "rm -rf $HOME/.cf", "chmod 1777 /tmp", "echo 'vcap:vcap' | chpasswd", "chown -R vcap: /var/vcap/store", "chown -R vcap: /var/pcfdev", "chown -R vcap /home/vcap/.ssh || true", "dd if=/dev/zero of=/EMPTY bs=1M 2>/dev/null || true", "rm -f /EMPTY" ] } ], "post-processors": [ { "type": "shell-local", "only": ["virtualbox-ovf"], "inline": ["ls $PWD/*/*.ova"], "keep_input_artifact": true }, { "type": "vagrant", "only": ["amazon-ebs"], "output": "{{user `distro`}}-{{.Provider}}-v{{user `version`}}.box", "keep_input_artifact": true } ] } ================================================ FILE: preseed/preseed.cfg ================================================ d-i debian-installer/locale string en_US.utf8 d-i console-setup/ask_detect boolean false d-i console-setup/layout string USA d-i netcfg/get_hostname string unassigned-hostname d-i netcfg/get_domain string unassigned-domain d-i time/zone string UTC d-i clock-setup/utc-auto boolean true d-i clock-setup/utc boolean true d-i kbd-chooser/method select American English d-i netcfg/wireless_wep string d-i base-installer/kernel/override-image string linux-server d-i debconf debconf/frontend select Noninteractive d-i pkgsel/install-language-support boolean false tasksel tasksel/first multiselect standard, ubuntu-server d-i partman-auto/method string regular d-i partman-auto/choose_recipe select atomic d-i partman-basicfilesystems/no_swap boolean false d-i partman-auto/expert_recipe string \ partman-auto/text/atomic_scheme :: \ 55000 80000 1000000 ext4 \ $primary{ } $bootable{ } \ method{ format } format{ } \ use_filesystem{ } filesystem{ ext4 } \ mountpoint{ / } \ . \ 1024 2048 8192 linux-swap \ $primary{ } \ method{ swap } format{ } \ . \ d-i partman/confirm_write_new_label boolean true d-i partman/confirm_nooverwrite boolean true d-i partman/choose_partition select finish d-i partman/confirm boolean true d-i passwd/user-fullname string vcap d-i passwd/username string vcap d-i passwd/user-password password vcap d-i passwd/user-password-again password vcap d-i user-setup/encrypt-home boolean false d-i user-setup/allow-password-weak boolean true d-i pkgsel/include string openssh-server ntp d-i pkgsel/upgrade select full-upgrade d-i grub-installer/only_debian boolean true d-i grub-installer/with_other_os boolean true d-i finish-install/reboot_in_progress note d-i pkgsel/update-policy select none choose-mirror-bin mirror/http/proxy string ================================================ FILE: src/api/main.go ================================================ package main import ( "encoding/json" "fmt" "io/ioutil" "net/http" "os" "api/usecases" ) func fileExists(path string) (bool, error) { if _, err := os.Stat(path); err != nil { if os.IsNotExist(err) { return false, nil } return false, err } return true, nil } func serverError(w http.ResponseWriter) { errorHandler(w, "Failed to replace UAA Config Credentials", http.StatusInternalServerError) } func errorHandler(w http.ResponseWriter, message string, statusCode int) { w.WriteHeader(statusCode) fmt.Fprintf(w, fmt.Sprintf(`{"error":{"message":"%s"}}`, message)) } func handlerStatus(w http.ResponseWriter, r *http.Request) { exists, err := fileExists("/run/pcfdev-healthcheck") if err != nil { fmt.Fprintf(w, fmt.Sprintf(`{"error":{"message":"%s"}}`, err)) } if exists { fmt.Fprintf(w, `{"status":"Running"}`) } else { fmt.Fprintf(w, `{"status":"Unprovisioned"}`) } } func replaceSecrets(w http.ResponseWriter, r *http.Request) { uaaFilePath := "/var/vcap/jobs/uaa/config/uaa.yml" uaaCredentialReplacement := &usecases.UaaCredentialReplacement{} uaaBytes, err := ioutil.ReadAll(r.Body) if err != nil { serverError(w) return } var request struct { Password string `json:"password"` } if err := json.Unmarshal(uaaBytes, &request); err != nil { errorHandler(w, "Failed to parse password field from request", http.StatusBadRequest) return } insecureConfig, err := ioutil.ReadFile(uaaFilePath) if err != nil { serverError(w) return } secureConfig, err := uaaCredentialReplacement.ReplaceUaaConfigAdminCredentials(string(insecureConfig), request.Password) if err != nil { serverError(w) return } ioutil.WriteFile(uaaFilePath, []byte(secureConfig), 0644) } func main() { http.HandleFunc("/replace-secrets", replaceSecrets) http.HandleFunc("/status", handlerStatus) http.ListenAndServe("localhost:8090", nil) } ================================================ FILE: src/api/main_suite_test.go ================================================ package main_test import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "testing" ) func TestPCFDevApi(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "PCF Dev Api Main Suite") } ================================================ FILE: src/api/main_test.go ================================================ package main_test import ( "github.com/onsi/gomega/gbytes" "github.com/onsi/gomega/gexec" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "os" "os/exec" "path/filepath" "strings" ) var _ = Describe("PCF Dev Api provision", func() { var ( dockerID string pwd string ) BeforeEach(func() { var err error pwd, err = os.Getwd() Expect(err).NotTo(HaveOccurred()) output, err := exec.Command("docker", "run", "--privileged", "-d", "-w", "/go/src/api", "-v", pwd+":/go/src/api", "pcfdev/provision", "bash", "-c", "mount -o size=40M -t tmpfs tmpfs /run && sleep 1000").Output() Expect(err).NotTo(HaveOccurred()) dockerID = strings.TrimSpace(string(output)) Expect(exec.Command("docker", "exec", dockerID, "go", "build", "api").Run()).To(Succeed()) Expect(exec.Command("docker", "exec", dockerID, "bash", "-c", `/go/src/api/api`).Start()) Eventually(func() error { return exec.Command("docker", "exec", dockerID, "lsof", "-i", ":8090").Run() }).Should(Succeed()) }) AfterEach(func() { os.RemoveAll(filepath.Join(pwd, "pcfdev")) os.RemoveAll(filepath.Join(pwd, "provisdion-script")) Expect(exec.Command("docker", "rm", dockerID, "-f").Run()).To(Succeed()) }) Describe("/replace-secrets", func() { It("should replace secrets on the VM", func() { session, err := gexec.Start(exec.Command("docker", "exec", dockerID, "curl", "-v", "-X", "PUT", "-d", `{"password":"some-master-password"}`, "localhost:8090/replace-secrets"), GinkgoWriter, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) Eventually(session, "10s").Should(gexec.Exit()) session, err = gexec.Start(exec.Command("docker", "exec", dockerID, "cat", "/var/vcap/jobs/uaa/config/uaa.yml"), GinkgoWriter, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) Eventually(session, "10s").Should(gexec.Exit(0)) Expect(session).To(gbytes.Say(`- admin\|some-master-password\|scim.write`)) }) }) Describe("/status", func() { Context("when the health-check is not written", func() { It("should reply 'Unprovisioned' in the /status endpoint", func() { session, err := gexec.Start(exec.Command("docker", "exec", dockerID, "curl", "localhost:8090/status"), GinkgoWriter, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) Eventually(session, "10s").Should(gexec.Exit(0)) Expect(session).To(gbytes.Say(`{"status":"Unprovisioned"}`)) }) }) Context("when the health-check is written", func() { It("should reply `Running` in the /status endpoint", func() { session, err := gexec.Start(exec.Command("docker", "exec", dockerID, "touch", "/run/pcfdev-healthcheck"), GinkgoWriter, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) Eventually(session, "10s").Should(gexec.Exit(0)) session, err = gexec.Start(exec.Command("docker", "exec", dockerID, "curl", "localhost:8090/status"), GinkgoWriter, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) Eventually(session, "10s").Should(gexec.Exit(0)) Expect(session).To(gbytes.Say(`{"status":"Running"}`)) }) }) }) }) ================================================ FILE: src/api/usecases/uaa_credential_replacement.go ================================================ package usecases import ( "errors" "fmt" "gopkg.in/yaml.v2" "regexp" "strings" ) type UaaCredentialReplacement struct{} func (u *UaaCredentialReplacement) ReplaceUaaConfigAdminCredentials(uaaConfig string, password string) (_ string, err error) { users, _ := findArray(uaaConfig, "scim.users") adminCredentialPattern := regexp.MustCompile(`admin\|admin\|`) for index, userSettingInterface := range users { userSetting := userSettingInterface.(string) if adminCredentialPattern.MatchString(userSetting) { securedUserSetting := adminCredentialPattern.ReplaceAllString(userSetting, fmt.Sprintf("admin|%s|", password)) return setAt(uaaConfig, "scim.users", index, securedUserSetting) } } return "", errors.New("failed to parse UAA config file") } type interfaceMap map[interface{}]interface{} func recoverFromInterfaceConversion(recovered interface{}) error { if recovered != nil { errorMessage := recovered.(error).Error() if strings.Contains(errorMessage, "interface conversion") { return errors.New("failed to parse yaml") } else { panic(recovered) } } return nil } func setAt(contents string, path string, arrayIndex int, value string) (string, error) { yamlContents := make(interfaceMap) if err := yaml.Unmarshal([]byte(contents), &yamlContents); err != nil { return "", errors.New("failed to parse yaml") } var currentNode interface{} = yamlContents keys := strings.Split(path, ".") for _, key := range keys { currentNode = currentNode.(interfaceMap)[key] } currentNode.([]interface{})[arrayIndex] = value replacedContents, err := yaml.Marshal(yamlContents) return string(replacedContents), err } func findArray(contents string, path string) (_ []interface{}, err error) { defer func() { err = recoverFromInterfaceConversion(recover()) }() yamlContents := make(interfaceMap) if err := yaml.Unmarshal([]byte(contents), &yamlContents); err != nil { return nil, errors.New("failed to parse yaml") } var currentNode interface{} = yamlContents keys := strings.Split(path, ".") for _, key := range keys { currentNode = currentNode.(interfaceMap)[key] } return currentNode.([]interface{}), nil } ================================================ FILE: src/api/usecases/uaa_credential_replacement_test.go ================================================ package usecases_test import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "api/usecases" ) var _ = Describe("Usecase: UAA Credential Replacement", func() { var u *usecases.UaaCredentialReplacement goodUaaConfig := ` --- name: uaa scim: some-key: true users: - admin|admin|other-value ` expectedSecuredConfig := `name: uaa scim: some-key: true users: - admin|some-password|other-value ` uaaConfigWithoutScimKey := "name: uaa" uaaConfigWithoutUsersKey := "scim: {}" uaaConfigWithoutAdminUser := ` --- scim: users: - other-user|password|other-value ` BeforeEach(func() { u = &usecases.UaaCredentialReplacement{} }) Context("when the config file is in the expected state", func() { It("replaces the admin password", func() { securedConfig, err := u.ReplaceUaaConfigAdminCredentials(goodUaaConfig, "some-password") Expect(err).NotTo(HaveOccurred()) Expect(securedConfig).To(Equal(expectedSecuredConfig)) }) }) Context("when the config file is not valid yaml", func() { It("returns an error", func() { uaaConfig := "some-bad-yaml" _, err := u.ReplaceUaaConfigAdminCredentials(uaaConfig, "some-password") Expect(err).To(MatchError("failed to parse UAA config file")) }) }) Context("When the scim key is missing", func() { It("returns an error", func() { _, err := u.ReplaceUaaConfigAdminCredentials(uaaConfigWithoutScimKey, "some-password") Expect(err).To(MatchError("failed to parse UAA config file")) }) }) Context("When the scim.users key is missing", func() { It("returns an error", func() { _, err := u.ReplaceUaaConfigAdminCredentials(uaaConfigWithoutUsersKey, "some-password") Expect(err).To(MatchError("failed to parse UAA config file")) }) }) Context("when the admin credentials are not in scim.users", func() { It("returns an error", func() { _, err := u.ReplaceUaaConfigAdminCredentials(uaaConfigWithoutAdminUser, "some-password") Expect(err).To(MatchError("failed to parse UAA config file")) }) }) }) ================================================ FILE: src/api/usecases/usecase_suite_test.go ================================================ package usecases_test import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "testing" ) func TestUsecase(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "Usecase Suite") } ================================================ FILE: src/provisioner/.envrc ================================================ export GOPATH=$(cd $PWD && cd ../.. && pwd) export PATH=$GOPATH/bin:$PATH ================================================ FILE: src/provisioner/Dockerfile ================================================ FROM golang:1.7 RUN apt-get update RUN apt-get install -y \ dnsmasq \ file \ host \ iptables \ lsof \ netcat \ nginx \ vim RUN echo "server {\n listen 443 ssl;\n ssl_certificate /var/vcap/jobs/gorouter/config/cert.pem;\n ssl_certificate_key /var/vcap/jobs/gorouter/config/key.pem;\n}" > /etc/nginx/conf.d/pcfdev.conf RUN mkdir -p /var/vcap/packages/uaa/tomcat/conf RUN echo "" > /var/vcap/packages/uaa/tomcat/conf/web.xml RUN mkdir -p /var/pcfdev/api RUN mkdir -p /var/vcap/monit/job RUN mkdir -p /var/vcap/jobs/garden/bin RUN mkdir -p /var/vcap/jobs/uaa/config RUN echo "exec /var/vcap/packages/garden-linux/bin/garden-linux \\ \n -dnsServer=some-dns-server \\ \n 1>>\$LOG_DIR/garden.stdout.log \\ \n 2>>\$LOG_DIR/garden.stderr.log" > /var/vcap/jobs/garden/bin/garden_ctl RUN echo "scim:\n users:\n - admin|admin|scim.write,scim.read,openid" > /var/vcap/jobs/uaa/config/uaa.yml RUN ln -s /bin/true /usr/local/bin/resolvconf ================================================ FILE: src/provisioner/assets/stub_server.go ================================================ package main import ( "log" "net/http" "os" ) func main() { port := os.Args[1] http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("Response from port " + port + " stub server")) }) if err := http.ListenAndServe(":" + port, nil); err != nil { log.Fatal("ListenAndServe: ", err) } } ================================================ FILE: src/provisioner/assets/tomcat-web-hsts-disabled.xml ================================================ default org.apache.catalina.servlets.DefaultServlet debug 0 listings false 1 jsp org.apache.jasper.servlet.JspServlet fork false xpoweredBy false 3 default / jsp *.jsp *.jspx httpHeaderSecurity org.apache.catalina.filters.HttpHeaderSecurityFilter hstsEnabled false true some-other-filter some-other-company some-param some-value 30 123 application/vnd.lotus-1-2-3 3dml text/vnd.in3d.3dml 3ds image/x-3ds 3g2 video/3gpp2 3gp video/3gpp 7z application/x-7z-compressed aab application/x-authorware-bin aac audio/x-aac aam application/x-authorware-map aas application/x-authorware-seg abs audio/x-mpeg abw application/x-abiword ac application/pkix-attr-cert acc application/vnd.americandynamics.acc ace application/x-ace-compressed acu application/vnd.acucobol acutc application/vnd.acucorp adp audio/adpcm aep application/vnd.audiograph afm application/x-font-type1 afp application/vnd.ibm.modcap ahead application/vnd.ahead.space ai application/postscript aif audio/x-aiff aifc audio/x-aiff aiff audio/x-aiff aim application/x-aim air application/vnd.adobe.air-application-installer-package+zip ait application/vnd.dvb.ait ami application/vnd.amiga.ami anx application/annodex apk application/vnd.android.package-archive appcache text/cache-manifest application application/x-ms-application apr application/vnd.lotus-approach arc application/x-freearc art image/x-jg asc application/pgp-signature asf video/x-ms-asf asm text/x-asm aso application/vnd.accpac.simply.aso asx video/x-ms-asf atc application/vnd.acucorp atom application/atom+xml atomcat application/atomcat+xml atomsvc application/atomsvc+xml atx application/vnd.antix.game-component au audio/basic avi video/x-msvideo avx video/x-rad-screenplay aw application/applixware axa audio/annodex axv video/annodex azf application/vnd.airzip.filesecure.azf azs application/vnd.airzip.filesecure.azs azw application/vnd.amazon.ebook bat application/x-msdownload bcpio application/x-bcpio bdf application/x-font-bdf bdm application/vnd.syncml.dm+wbxml bed application/vnd.realvnc.bed bh2 application/vnd.fujitsu.oasysprs bin application/octet-stream blb application/x-blorb blorb application/x-blorb bmi application/vnd.bmi bmp image/bmp body text/html book application/vnd.framemaker box application/vnd.previewsystems.box boz application/x-bzip2 bpk application/octet-stream btif image/prs.btif bz application/x-bzip bz2 application/x-bzip2 c text/x-c c11amc application/vnd.cluetrust.cartomobile-config c11amz application/vnd.cluetrust.cartomobile-config-pkg c4d application/vnd.clonk.c4group c4f application/vnd.clonk.c4group c4g application/vnd.clonk.c4group c4p application/vnd.clonk.c4group c4u application/vnd.clonk.c4group cab application/vnd.ms-cab-compressed caf audio/x-caf cap application/vnd.tcpdump.pcap car application/vnd.curl.car cat application/vnd.ms-pki.seccat cb7 application/x-cbr cba application/x-cbr cbr application/x-cbr cbt application/x-cbr cbz application/x-cbr cc text/x-c cct application/x-director ccxml application/ccxml+xml cdbcmsg application/vnd.contact.cmsg cdf application/x-cdf cdkey application/vnd.mediastation.cdkey cdmia application/cdmi-capability cdmic application/cdmi-container cdmid application/cdmi-domain cdmio application/cdmi-object cdmiq application/cdmi-queue cdx chemical/x-cdx cdxml application/vnd.chemdraw+xml cdy application/vnd.cinderella cer application/pkix-cert cfs application/x-cfs-compressed cgm image/cgm chat application/x-chat chm application/vnd.ms-htmlhelp chrt application/vnd.kde.kchart cif chemical/x-cif cii application/vnd.anser-web-certificate-issue-initiation cil application/vnd.ms-artgalry cla application/vnd.claymore class application/java clkk application/vnd.crick.clicker.keyboard clkp application/vnd.crick.clicker.palette clkt application/vnd.crick.clicker.template clkw application/vnd.crick.clicker.wordbank clkx application/vnd.crick.clicker clp application/x-msclip cmc application/vnd.cosmocaller cmdf chemical/x-cmdf cml chemical/x-cml cmp application/vnd.yellowriver-custom-menu cmx image/x-cmx cod application/vnd.rim.cod com application/x-msdownload conf text/plain cpio application/x-cpio cpp text/x-c cpt application/mac-compactpro crd application/x-mscardfile crl application/pkix-crl crt application/x-x509-ca-cert cryptonote application/vnd.rig.cryptonote csh application/x-csh csml chemical/x-csml csp application/vnd.commonspace css text/css cst application/x-director csv text/csv cu application/cu-seeme curl text/vnd.curl cww application/prs.cww cxt application/x-director cxx text/x-c dae model/vnd.collada+xml daf application/vnd.mobius.daf dart application/vnd.dart dataless application/vnd.fdsn.seed davmount application/davmount+xml dbk application/docbook+xml dcr application/x-director dcurl text/vnd.curl.dcurl dd2 application/vnd.oma.dd2+xml ddd application/vnd.fujixerox.ddd deb application/x-debian-package def text/plain deploy application/octet-stream der application/x-x509-ca-cert dfac application/vnd.dreamfactory dgc application/x-dgc-compressed dib image/bmp dic text/x-c dir application/x-director dis application/vnd.mobius.dis dist application/octet-stream distz application/octet-stream djv image/vnd.djvu djvu image/vnd.djvu dll application/x-msdownload dmg application/x-apple-diskimage dmp application/vnd.tcpdump.pcap dms application/octet-stream dna application/vnd.dna doc application/msword docm application/vnd.ms-word.document.macroenabled.12 docx application/vnd.openxmlformats-officedocument.wordprocessingml.document dot application/msword dotm application/vnd.ms-word.template.macroenabled.12 dotx application/vnd.openxmlformats-officedocument.wordprocessingml.template dp application/vnd.osgi.dp dpg application/vnd.dpgraph dra audio/vnd.dra dsc text/prs.lines.tag dssc application/dssc+der dtb application/x-dtbook+xml dtd application/xml-dtd dts audio/vnd.dts dtshd audio/vnd.dts.hd dump application/octet-stream dv video/x-dv dvb video/vnd.dvb.file dvi application/x-dvi dwf model/vnd.dwf dwg image/vnd.dwg dxf image/vnd.dxf dxp application/vnd.spotfire.dxp dxr application/x-director ecelp4800 audio/vnd.nuera.ecelp4800 ecelp7470 audio/vnd.nuera.ecelp7470 ecelp9600 audio/vnd.nuera.ecelp9600 ecma application/ecmascript edm application/vnd.novadigm.edm edx application/vnd.novadigm.edx efif application/vnd.picsel ei6 application/vnd.pg.osasli elc application/octet-stream emf application/x-msmetafile eml message/rfc822 emma application/emma+xml emz application/x-msmetafile eol audio/vnd.digital-winds eot application/vnd.ms-fontobject eps application/postscript epub application/epub+zip es3 application/vnd.eszigno3+xml esa application/vnd.osgi.subsystem esf application/vnd.epson.esf et3 application/vnd.eszigno3+xml etx text/x-setext eva application/x-eva evy application/x-envoy exe application/octet-stream exi application/exi ext application/vnd.novadigm.ext ez application/andrew-inset ez2 application/vnd.ezpix-album ez3 application/vnd.ezpix-package f text/x-fortran f4v video/x-f4v f77 text/x-fortran f90 text/x-fortran fbs image/vnd.fastbidsheet fcdt application/vnd.adobe.formscentral.fcdt fcs application/vnd.isac.fcs fdf application/vnd.fdf fe_launch application/vnd.denovo.fcselayout-link fg5 application/vnd.fujitsu.oasysgp fgd application/x-director fh image/x-freehand fh4 image/x-freehand fh5 image/x-freehand fh7 image/x-freehand fhc image/x-freehand fig application/x-xfig flac audio/flac fli video/x-fli flo application/vnd.micrografx.flo flv video/x-flv flw application/vnd.kde.kivio flx text/vnd.fmi.flexstor fly text/vnd.fly fm application/vnd.framemaker fnc application/vnd.frogans.fnc for text/x-fortran fpx image/vnd.fpx frame application/vnd.framemaker fsc application/vnd.fsc.weblaunch fst image/vnd.fst ftc application/vnd.fluxtime.clip fti application/vnd.anser-web-funds-transfer-initiation fvt video/vnd.fvt fxp application/vnd.adobe.fxp fxpl application/vnd.adobe.fxp fzs application/vnd.fuzzysheet g2w application/vnd.geoplan g3 image/g3fax g3w application/vnd.geospace gac application/vnd.groove-account gam application/x-tads gbr application/rpki-ghostbusters gca application/x-gca-compressed gdl model/vnd.gdl geo application/vnd.dynageo gex application/vnd.geometry-explorer ggb application/vnd.geogebra.file ggt application/vnd.geogebra.tool ghf application/vnd.groove-help gif image/gif gim application/vnd.groove-identity-message gml application/gml+xml gmx application/vnd.gmx gnumeric application/x-gnumeric gph application/vnd.flographit gpx application/gpx+xml gqf application/vnd.grafeq gqs application/vnd.grafeq gram application/srgs gramps application/x-gramps-xml gre application/vnd.geometry-explorer grv application/vnd.groove-injector grxml application/srgs+xml gsf application/x-font-ghostscript gtar application/x-gtar gtm application/vnd.groove-tool-message gtw model/vnd.gtw gv text/vnd.graphviz gxf application/gxf gxt application/vnd.geonext gz application/x-gzip h text/x-c h261 video/h261 h263 video/h263 h264 video/h264 hal application/vnd.hal+xml hbci application/vnd.hbci hdf application/x-hdf hh text/x-c hlp application/winhlp hpgl application/vnd.hp-hpgl hpid application/vnd.hp-hpid hps application/vnd.hp-hps hqx application/mac-binhex40 htc text/x-component htke application/vnd.kenameaapp htm text/html html text/html hvd application/vnd.yamaha.hv-dic hvp application/vnd.yamaha.hv-voice hvs application/vnd.yamaha.hv-script i2g application/vnd.intergeo icc application/vnd.iccprofile ice x-conference/x-cooltalk icm application/vnd.iccprofile ico image/x-icon ics text/calendar ief image/ief ifb text/calendar ifm application/vnd.shana.informed.formdata iges model/iges igl application/vnd.igloader igm application/vnd.insors.igm igs model/iges igx application/vnd.micrografx.igx iif application/vnd.shana.informed.interchange imp application/vnd.accpac.simply.imp ims application/vnd.ms-ims in text/plain ink application/inkml+xml inkml application/inkml+xml install application/x-install-instructions iota application/vnd.astraea-software.iota ipfix application/ipfix ipk application/vnd.shana.informed.package irm application/vnd.ibm.rights-management irp application/vnd.irepository.package+xml iso application/x-iso9660-image itp application/vnd.shana.informed.formtemplate ivp application/vnd.immervision-ivp ivu application/vnd.immervision-ivu jad text/vnd.sun.j2me.app-descriptor jam application/vnd.jam jar application/java-archive java text/x-java-source jisp application/vnd.jisp jlt application/vnd.hp-jlyt jnlp application/x-java-jnlp-file joda application/vnd.joost.joda-archive jpe image/jpeg jpeg image/jpeg jpg image/jpeg jpgm video/jpm jpgv video/jpeg jpm video/jpm js application/javascript jsf text/plain json application/json jsonml application/jsonml+json jspf text/plain kar audio/midi karbon application/vnd.kde.karbon kfo application/vnd.kde.kformula kia application/vnd.kidspiration kml application/vnd.google-earth.kml+xml kmz application/vnd.google-earth.kmz kne application/vnd.kinar knp application/vnd.kinar kon application/vnd.kde.kontour kpr application/vnd.kde.kpresenter kpt application/vnd.kde.kpresenter kpxx application/vnd.ds-keypoint ksp application/vnd.kde.kspread ktr application/vnd.kahootz ktx image/ktx ktz application/vnd.kahootz kwd application/vnd.kde.kword kwt application/vnd.kde.kword lasxml application/vnd.las.las+xml latex application/x-latex lbd application/vnd.llamagraphics.life-balance.desktop lbe application/vnd.llamagraphics.life-balance.exchange+xml les application/vnd.hhe.lesson-player lha application/x-lzh-compressed link66 application/vnd.route66.link66+xml list text/plain list3820 application/vnd.ibm.modcap listafp application/vnd.ibm.modcap lnk application/x-ms-shortcut log text/plain lostxml application/lost+xml lrf application/octet-stream lrm application/vnd.ms-lrm ltf application/vnd.frogans.ltf lvp audio/vnd.lucent.voice lwp application/vnd.lotus-wordpro lzh application/x-lzh-compressed m13 application/x-msmediaview m14 application/x-msmediaview m1v video/mpeg m21 application/mp21 m2a audio/mpeg m2v video/mpeg m3a audio/mpeg m3u audio/x-mpegurl m3u8 application/vnd.apple.mpegurl m4a audio/mp4 m4b audio/mp4 m4r audio/mp4 m4u video/vnd.mpegurl m4v video/mp4 ma application/mathematica mac image/x-macpaint mads application/mads+xml mag application/vnd.ecowin.chart maker application/vnd.framemaker man text/troff mar application/octet-stream mathml application/mathml+xml mb application/mathematica mbk application/vnd.mobius.mbk mbox application/mbox mc1 application/vnd.medcalcdata mcd application/vnd.mcd mcurl text/vnd.curl.mcurl mdb application/x-msaccess mdi image/vnd.ms-modi me text/troff mesh model/mesh meta4 application/metalink4+xml metalink application/metalink+xml mets application/mets+xml mfm application/vnd.mfmp mft application/rpki-manifest mgp application/vnd.osgeo.mapguide.package mgz application/vnd.proteus.magazine mid audio/midi midi audio/midi mie application/x-mie mif application/x-mif mime message/rfc822 mj2 video/mj2 mjp2 video/mj2 mk3d video/x-matroska mka audio/x-matroska mks video/x-matroska mkv video/x-matroska mlp application/vnd.dolby.mlp mmd application/vnd.chipnuts.karaoke-mmd mmf application/vnd.smaf mmr image/vnd.fujixerox.edmics-mmr mng video/x-mng mny application/x-msmoney mobi application/x-mobipocket-ebook mods application/mods+xml mov video/quicktime movie video/x-sgi-movie mp1 audio/mpeg mp2 audio/mpeg mp21 application/mp21 mp2a audio/mpeg mp3 audio/mpeg mp4 video/mp4 mp4a audio/mp4 mp4s application/mp4 mp4v video/mp4 mpa audio/mpeg mpc application/vnd.mophun.certificate mpe video/mpeg mpeg video/mpeg mpega audio/x-mpeg mpg video/mpeg mpg4 video/mp4 mpga audio/mpeg mpkg application/vnd.apple.installer+xml mpm application/vnd.blueice.multipass mpn application/vnd.mophun.application mpp application/vnd.ms-project mpt application/vnd.ms-project mpv2 video/mpeg2 mpy application/vnd.ibm.minipay mqy application/vnd.mobius.mqy mrc application/marc mrcx application/marcxml+xml ms text/troff mscml application/mediaservercontrol+xml mseed application/vnd.fdsn.mseed mseq application/vnd.mseq msf application/vnd.epson.msf msh model/mesh msi application/x-msdownload msl application/vnd.mobius.msl msty application/vnd.muvee.style mts model/vnd.mts mus application/vnd.musician musicxml application/vnd.recordare.musicxml+xml mvb application/x-msmediaview mwf application/vnd.mfer mxf application/mxf mxl application/vnd.recordare.musicxml mxml application/xv+xml mxs application/vnd.triscape.mxs mxu video/vnd.mpegurl n-gage application/vnd.nokia.n-gage.symbian.install n3 text/n3 nb application/mathematica nbp application/vnd.wolfram.player nc application/x-netcdf ncx application/x-dtbncx+xml nfo text/x-nfo ngdat application/vnd.nokia.n-gage.data nitf application/vnd.nitf nlu application/vnd.neurolanguage.nlu nml application/vnd.enliven nnd application/vnd.noblenet-directory nns application/vnd.noblenet-sealer nnw application/vnd.noblenet-web npx image/vnd.net-fpx nsc application/x-conference nsf application/vnd.lotus-notes ntf application/vnd.nitf nzb application/x-nzb oa2 application/vnd.fujitsu.oasys2 oa3 application/vnd.fujitsu.oasys3 oas application/vnd.fujitsu.oasys obd application/x-msbinder obj application/x-tgif oda application/oda odb application/vnd.oasis.opendocument.database odc application/vnd.oasis.opendocument.chart odf application/vnd.oasis.opendocument.formula odft application/vnd.oasis.opendocument.formula-template odg application/vnd.oasis.opendocument.graphics odi application/vnd.oasis.opendocument.image odm application/vnd.oasis.opendocument.text-master odp application/vnd.oasis.opendocument.presentation ods application/vnd.oasis.opendocument.spreadsheet odt application/vnd.oasis.opendocument.text oga audio/ogg ogg audio/ogg ogv video/ogg ogx application/ogg omdoc application/omdoc+xml onepkg application/onenote onetmp application/onenote onetoc application/onenote onetoc2 application/onenote opf application/oebps-package+xml opml text/x-opml oprc application/vnd.palm org application/vnd.lotus-organizer osf application/vnd.yamaha.openscoreformat osfpvg application/vnd.yamaha.openscoreformat.osfpvg+xml otc application/vnd.oasis.opendocument.chart-template otf application/x-font-otf otg application/vnd.oasis.opendocument.graphics-template oth application/vnd.oasis.opendocument.text-web oti application/vnd.oasis.opendocument.image-template otp application/vnd.oasis.opendocument.presentation-template ots application/vnd.oasis.opendocument.spreadsheet-template ott application/vnd.oasis.opendocument.text-template oxps application/oxps oxt application/vnd.openofficeorg.extension p text/x-pascal p10 application/pkcs10 p12 application/x-pkcs12 p7b application/x-pkcs7-certificates p7c application/pkcs7-mime p7m application/pkcs7-mime p7r application/x-pkcs7-certreqresp p7s application/pkcs7-signature p8 application/pkcs8 pas text/x-pascal paw application/vnd.pawaafile pbd application/vnd.powerbuilder6 pbm image/x-portable-bitmap pcap application/vnd.tcpdump.pcap pcf application/x-font-pcf pcl application/vnd.hp-pcl pclxl application/vnd.hp-pclxl pct image/pict pcurl application/vnd.curl.pcurl pcx image/x-pcx pdb application/vnd.palm pdf application/pdf pfa application/x-font-type1 pfb application/x-font-type1 pfm application/x-font-type1 pfr application/font-tdpfr pfx application/x-pkcs12 pgm image/x-portable-graymap pgn application/x-chess-pgn pgp application/pgp-encrypted pic image/pict pict image/pict pkg application/octet-stream pki application/pkixcmp pkipath application/pkix-pkipath plb application/vnd.3gpp.pic-bw-large plc application/vnd.mobius.plc plf application/vnd.pocketlearn pls audio/x-scpls pml application/vnd.ctc-posml png image/png pnm image/x-portable-anymap pnt image/x-macpaint portpkg application/vnd.macports.portpkg pot application/vnd.ms-powerpoint potm application/vnd.ms-powerpoint.template.macroenabled.12 potx application/vnd.openxmlformats-officedocument.presentationml.template ppam application/vnd.ms-powerpoint.addin.macroenabled.12 ppd application/vnd.cups-ppd ppm image/x-portable-pixmap pps application/vnd.ms-powerpoint ppsm application/vnd.ms-powerpoint.slideshow.macroenabled.12 ppsx application/vnd.openxmlformats-officedocument.presentationml.slideshow ppt application/vnd.ms-powerpoint pptm application/vnd.ms-powerpoint.presentation.macroenabled.12 pptx application/vnd.openxmlformats-officedocument.presentationml.presentation pqa application/vnd.palm prc application/x-mobipocket-ebook pre application/vnd.lotus-freelance prf application/pics-rules ps application/postscript psb application/vnd.3gpp.pic-bw-small psd image/vnd.adobe.photoshop psf application/x-font-linux-psf pskcxml application/pskc+xml ptid application/vnd.pvi.ptid1 pub application/x-mspublisher pvb application/vnd.3gpp.pic-bw-var pwn application/vnd.3m.post-it-notes pya audio/vnd.ms-playready.media.pya pyv video/vnd.ms-playready.media.pyv qam application/vnd.epson.quickanime qbo application/vnd.intu.qbo qfx application/vnd.intu.qfx qps application/vnd.publishare-delta-tree qt video/quicktime qti image/x-quicktime qtif image/x-quicktime qwd application/vnd.quark.quarkxpress qwt application/vnd.quark.quarkxpress qxb application/vnd.quark.quarkxpress qxd application/vnd.quark.quarkxpress qxl application/vnd.quark.quarkxpress qxt application/vnd.quark.quarkxpress ra audio/x-pn-realaudio ram audio/x-pn-realaudio rar application/x-rar-compressed ras image/x-cmu-raster rcprofile application/vnd.ipunplugged.rcprofile rdf application/rdf+xml rdz application/vnd.data-vision.rdz rep application/vnd.businessobjects res application/x-dtbresource+xml rgb image/x-rgb rif application/reginfo+xml rip audio/vnd.rip ris application/x-research-info-systems rl application/resource-lists+xml rlc image/vnd.fujixerox.edmics-rlc rld application/resource-lists-diff+xml rm application/vnd.rn-realmedia rmi audio/midi rmp audio/x-pn-realaudio-plugin rms application/vnd.jcp.javame.midlet-rms rmvb application/vnd.rn-realmedia-vbr rnc application/relax-ng-compact-syntax roa application/rpki-roa roff text/troff rp9 application/vnd.cloanto.rp9 rpss application/vnd.nokia.radio-presets rpst application/vnd.nokia.radio-preset rq application/sparql-query rs application/rls-services+xml rsd application/rsd+xml rss application/rss+xml rtf application/rtf rtx text/richtext s text/x-asm s3m audio/s3m saf application/vnd.yamaha.smaf-audio sbml application/sbml+xml sc application/vnd.ibm.secure-container scd application/x-msschedule scm application/vnd.lotus-screencam scq application/scvp-cv-request scs application/scvp-cv-response scurl text/vnd.curl.scurl sda application/vnd.stardivision.draw sdc application/vnd.stardivision.calc sdd application/vnd.stardivision.impress sdkd application/vnd.solent.sdkm+xml sdkm application/vnd.solent.sdkm+xml sdp application/sdp sdw application/vnd.stardivision.writer see application/vnd.seemail seed application/vnd.fdsn.seed sema application/vnd.sema semd application/vnd.semd semf application/vnd.semf ser application/java-serialized-object setpay application/set-payment-initiation setreg application/set-registration-initiation sfd-hdstx application/vnd.hydrostatix.sof-data sfs application/vnd.spotfire.sfs sfv text/x-sfv sgi image/sgi sgl application/vnd.stardivision.writer-global sgm text/sgml sgml text/sgml sh application/x-sh shar application/x-shar shf application/shf+xml sid image/x-mrsid-image sig application/pgp-signature sil audio/silk silo model/mesh sis application/vnd.symbian.install sisx application/vnd.symbian.install sit application/x-stuffit sitx application/x-stuffitx skd application/vnd.koan skm application/vnd.koan skp application/vnd.koan skt application/vnd.koan sldm application/vnd.ms-powerpoint.slide.macroenabled.12 sldx application/vnd.openxmlformats-officedocument.presentationml.slide slt application/vnd.epson.salt sm application/vnd.stepmania.stepchart smf application/vnd.stardivision.math smi application/smil+xml smil application/smil+xml smv video/x-smv smzip application/vnd.stepmania.package snd audio/basic snf application/x-font-snf so application/octet-stream spc application/x-pkcs7-certificates spf application/vnd.yamaha.smaf-phrase spl application/x-futuresplash spot text/vnd.in3d.spot spp application/scvp-vp-response spq application/scvp-vp-request spx audio/ogg sql application/x-sql src application/x-wais-source srt application/x-subrip sru application/sru+xml srx application/sparql-results+xml ssdl application/ssdl+xml sse application/vnd.kodak-descriptor ssf application/vnd.epson.ssf ssml application/ssml+xml st application/vnd.sailingtracker.track stc application/vnd.sun.xml.calc.template std application/vnd.sun.xml.draw.template stf application/vnd.wt.stf sti application/vnd.sun.xml.impress.template stk application/hyperstudio stl application/vnd.ms-pki.stl str application/vnd.pg.format stw application/vnd.sun.xml.writer.template sub text/vnd.dvb.subtitle sus application/vnd.sus-calendar susp application/vnd.sus-calendar sv4cpio application/x-sv4cpio sv4crc application/x-sv4crc svc application/vnd.dvb.service svd application/vnd.svd svg image/svg+xml svgz image/svg+xml swa application/x-director swf application/x-shockwave-flash swi application/vnd.aristanetworks.swi sxc application/vnd.sun.xml.calc sxd application/vnd.sun.xml.draw sxg application/vnd.sun.xml.writer.global sxi application/vnd.sun.xml.impress sxm application/vnd.sun.xml.math sxw application/vnd.sun.xml.writer t text/troff t3 application/x-t3vm-image taglet application/vnd.mynfc tao application/vnd.tao.intent-module-archive tar application/x-tar tcap application/vnd.3gpp2.tcap tcl application/x-tcl teacher application/vnd.smart.teacher tei application/tei+xml teicorpus application/tei+xml tex application/x-tex texi application/x-texinfo texinfo application/x-texinfo text text/plain tfi application/thraud+xml tfm application/x-tex-tfm tga image/x-tga thmx application/vnd.ms-officetheme tif image/tiff tiff image/tiff tmo application/vnd.tmobile-livetv torrent application/x-bittorrent tpl application/vnd.groove-tool-template tpt application/vnd.trid.tpt tr text/troff tra application/vnd.trueapp trm application/x-msterminal tsd application/timestamped-data tsv text/tab-separated-values ttc application/x-font-ttf ttf application/x-font-ttf ttl text/turtle twd application/vnd.simtech-mindmapper twds application/vnd.simtech-mindmapper txd application/vnd.genomatix.tuxedo txf application/vnd.mobius.txf txt text/plain u32 application/x-authorware-bin udeb application/x-debian-package ufd application/vnd.ufdl ufdl application/vnd.ufdl ulw audio/basic ulx application/x-glulx umj application/vnd.umajin unityweb application/vnd.unity uoml application/vnd.uoml+xml uri text/uri-list uris text/uri-list urls text/uri-list ustar application/x-ustar utz application/vnd.uiq.theme uu text/x-uuencode uva audio/vnd.dece.audio uvd application/vnd.dece.data uvf application/vnd.dece.data uvg image/vnd.dece.graphic uvh video/vnd.dece.hd uvi image/vnd.dece.graphic uvm video/vnd.dece.mobile uvp video/vnd.dece.pd uvs video/vnd.dece.sd uvt application/vnd.dece.ttml+xml uvu video/vnd.uvvu.mp4 uvv video/vnd.dece.video uvva audio/vnd.dece.audio uvvd application/vnd.dece.data uvvf application/vnd.dece.data uvvg image/vnd.dece.graphic uvvh video/vnd.dece.hd uvvi image/vnd.dece.graphic uvvm video/vnd.dece.mobile uvvp video/vnd.dece.pd uvvs video/vnd.dece.sd uvvt application/vnd.dece.ttml+xml uvvu video/vnd.uvvu.mp4 uvvv video/vnd.dece.video uvvx application/vnd.dece.unspecified uvvz application/vnd.dece.zip uvx application/vnd.dece.unspecified uvz application/vnd.dece.zip vcard text/vcard vcd application/x-cdlink vcf text/x-vcard vcg application/vnd.groove-vcard vcs text/x-vcalendar vcx application/vnd.vcx vis application/vnd.visionary viv video/vnd.vivo vob video/x-ms-vob vor application/vnd.stardivision.writer vox application/x-authorware-bin vrml model/vrml vsd application/vnd.visio vsf application/vnd.vsf vss application/vnd.visio vst application/vnd.visio vsw application/vnd.visio vtu model/vnd.vtu vxml application/voicexml+xml w3d application/x-director wad application/x-doom wav audio/x-wav wax audio/x-ms-wax wbmp image/vnd.wap.wbmp wbs application/vnd.criticaltools.wbs+xml wbxml application/vnd.wap.wbxml wcm application/vnd.ms-works wdb application/vnd.ms-works wdp image/vnd.ms-photo weba audio/webm webm video/webm webp image/webp wg application/vnd.pmi.widget wgt application/widget wks application/vnd.ms-works wm video/x-ms-wm wma audio/x-ms-wma wmd application/x-ms-wmd wmf application/x-msmetafile wml text/vnd.wap.wml wmlc application/vnd.wap.wmlc wmls text/vnd.wap.wmlscript wmlsc application/vnd.wap.wmlscriptc wmv video/x-ms-wmv wmx video/x-ms-wmx wmz application/x-msmetafile woff application/x-font-woff wpd application/vnd.wordperfect wpl application/vnd.ms-wpl wps application/vnd.ms-works wqd application/vnd.wqd wri application/x-mswrite wrl model/vrml wsdl application/wsdl+xml wspolicy application/wspolicy+xml wtb application/vnd.webturbo wvx video/x-ms-wvx x32 application/x-authorware-bin x3d model/x3d+xml x3db model/x3d+binary x3dbz model/x3d+binary x3dv model/x3d+vrml x3dvz model/x3d+vrml x3dz model/x3d+xml xaml application/xaml+xml xap application/x-silverlight-app xar application/vnd.xara xbap application/x-ms-xbap xbd application/vnd.fujixerox.docuworks.binder xbm image/x-xbitmap xdf application/xcap-diff+xml xdm application/vnd.syncml.dm+xml xdp application/vnd.adobe.xdp+xml xdssc application/dssc+xml xdw application/vnd.fujixerox.docuworks xenc application/xenc+xml xer application/patch-ops-error+xml xfdf application/vnd.adobe.xfdf xfdl application/vnd.xfdl xht application/xhtml+xml xhtml application/xhtml+xml xhvml application/xv+xml xif image/vnd.xiff xla application/vnd.ms-excel xlam application/vnd.ms-excel.addin.macroenabled.12 xlc application/vnd.ms-excel xlf application/x-xliff+xml xlm application/vnd.ms-excel xls application/vnd.ms-excel xlsb application/vnd.ms-excel.sheet.binary.macroenabled.12 xlsm application/vnd.ms-excel.sheet.macroenabled.12 xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlt application/vnd.ms-excel xltm application/vnd.ms-excel.template.macroenabled.12 xltx application/vnd.openxmlformats-officedocument.spreadsheetml.template xlw application/vnd.ms-excel xm audio/xm xml application/xml xo application/vnd.olpc-sugar xop application/xop+xml xpi application/x-xpinstall xpl application/xproc+xml xpm image/x-xpixmap xpr application/vnd.is-xpr xps application/vnd.ms-xpsdocument xpw application/vnd.intercon.formnet xpx application/vnd.intercon.formnet xsl application/xml xslt application/xslt+xml xsm application/vnd.syncml+xml xspf application/xspf+xml xul application/vnd.mozilla.xul+xml xvm application/xv+xml xvml application/xv+xml xwd image/x-xwindowdump xyz chemical/x-xyz xz application/x-xz yang application/yang yin application/yin+xml z application/x-compress Z application/x-compress z1 application/x-zmachine z2 application/x-zmachine z3 application/x-zmachine z4 application/x-zmachine z5 application/x-zmachine z6 application/x-zmachine z7 application/x-zmachine z8 application/x-zmachine zaz application/vnd.zzazz.deck+xml zip application/zip zir application/vnd.zul zirz application/vnd.zul zmm application/vnd.handheld-entertainment+xml index.html index.htm index.jsp ================================================ FILE: src/provisioner/assets/tomcat-web-invalid.xml ================================================ some-bad-xml ================================================ FILE: src/provisioner/assets/tomcat-web.xml ================================================ default org.apache.catalina.servlets.DefaultServlet debug 0 listings false 1 jsp org.apache.jasper.servlet.JspServlet fork false xpoweredBy false 3 default / jsp *.jsp *.jspx 30 123 application/vnd.lotus-1-2-3 3dml text/vnd.in3d.3dml index.html index.htm index.jsp ================================================ FILE: src/provisioner/bin/generate-mocks ================================================ #!/bin/bash pcfdev_dir=$(cd `dirname $0` && cd .. && pwd) mocks_dirs=$(go list -f '{{.Dir}}' provisioner/... | grep -v /vendor/ | grep '/mocks$') if [[ -n "$mocks_dirs" ]]; then find $mocks_dirs -name "*.go" -exec rm {} \; fi go install provisioner/vendor/github.com/golang/mock/mockgen go generate $(go list provisioner/... | grep -v /vendor/) ================================================ FILE: src/provisioner/bin/tests ================================================ #!/bin/bash dir=$(cd `dirname $0` && cd .. && pwd) go get github.com/onsi/ginkgo/ginkgo go get github.com/onsi/gomega ginkgo "$@" -r $dir ================================================ FILE: src/provisioner/cert/cert.go ================================================ package cert import ( "bytes" "crypto/rand" "crypto/rsa" "crypto/x509" "crypto/x509/pkix" "encoding/pem" "math/big" "time" ) type Cert struct{} func (c *Cert) GenerateCerts(domain string) ([]byte, []byte, []byte, []byte, error) { caPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, nil, nil, nil, err } encodedCAPrivateKey := new(bytes.Buffer) if err := pem.Encode(encodedCAPrivateKey, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(caPrivateKey)}); err != nil { return nil, nil, nil, nil, err } caTemplate := c.generateTemplate(domain, true) encodedCACertificate, err := c.generateCert(caTemplate, caTemplate, &caPrivateKey.PublicKey, caPrivateKey) if err != nil { return nil, nil, nil, nil, err } privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, nil, nil, nil, err } encodedPrivateKey := new(bytes.Buffer) if err := pem.Encode(encodedPrivateKey, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)}); err != nil { return nil, nil, nil, nil, err } template := c.generateTemplate(domain, false) encodedCertificate, err := c.generateCert(template, caTemplate, &privateKey.PublicKey, caPrivateKey) if err != nil { return nil, nil, nil, nil, err } return encodedCertificate, encodedPrivateKey.Bytes(), encodedCACertificate, encodedCAPrivateKey.Bytes(), nil } func (c *Cert) generateCert(template, parentTemplate *x509.Certificate, publicKey *rsa.PublicKey, privateKey *rsa.PrivateKey) ([]byte, error) { certificate, err := x509.CreateCertificate(rand.Reader, template, parentTemplate, publicKey, privateKey) if err != nil { return nil, err } encodedCertificate := new(bytes.Buffer) if err := pem.Encode(encodedCertificate, &pem.Block{Type: "CERTIFICATE", Bytes: certificate}); err != nil { return nil, err } return encodedCertificate.Bytes(), nil } func (c *Cert) generateTemplate(domain string, isCA bool) *x509.Certificate { notBefore := time.Now().Add(-24 * time.Hour) notAfter := notBefore.Add(10 * 365 * 24 * time.Hour) template := &x509.Certificate{ DNSNames: []string{ domain, "*." + domain, "*.login." + domain, "*.uaa." + domain, }, EmailAddresses: []string{"pcfdev-eng@pivotal.io"}, NotBefore: notBefore, NotAfter: notAfter, SerialNumber: big.NewInt(1), Subject: pkix.Name{ CommonName: domain + " " + time.Now().Format(time.RFC3339), Country: []string{"US"}, Locality: []string{"New York"}, Organization: []string{"Cloud Foundry"}, OrganizationalUnit: []string{"PCF Dev"}, Province: []string{"New York"}, }, } if isCA { template.Subject.Organization = []string{"Cloud Foundry CA"} template.BasicConstraintsValid = true template.IsCA = true } return template } ================================================ FILE: src/provisioner/cert/cert_suite_test.go ================================================ package cert_test import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "testing" ) func TestCert(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "Cert Suite") } ================================================ FILE: src/provisioner/cert/cert_test.go ================================================ package cert_test import ( "crypto/tls" "crypto/x509" "math/big" "provisioner/cert" "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("Cert", func() { Describe("#GenerateCert", func() { var c *cert.Cert BeforeEach(func() { c = &cert.Cert{} }) It("should generate a certificate and private key signed by the CA", func() { certificateBytes, privateKeyBytes, caCertificateBytes, caPrivateKeyBytes, err := c.GenerateCerts("some-domain") Expect(err).NotTo(HaveOccurred()) yesterday := time.Now().Add(-24 * time.Hour) tenYearsFromYesterday := yesterday.Add(10 * 365 * 24 * time.Hour) certificate := parseCertificate(certificateBytes, privateKeyBytes) caCertificate := parseCertificate(caCertificateBytes, caPrivateKeyBytes) Expect(certificate.DNSNames).To(Equal([]string{ "some-domain", "*.some-domain", "*.login.some-domain", "*.uaa.some-domain", })) Expect(certificate.EmailAddresses).To(Equal([]string{"pcfdev-eng@pivotal.io"})) Expect(certificate.Issuer).To(Equal(caCertificate.Subject)) Expect(certificate.NotBefore).To(BeTemporally("~", yesterday, time.Minute)) Expect(certificate.NotAfter).To(BeTemporally("~", tenYearsFromYesterday, time.Minute)) Expect(certificate.SerialNumber).To(Equal(big.NewInt(1))) Expect(certificate.Subject.CommonName).To(ContainSubstring("some-domain")) Expect(certificate.Subject.Country).To(Equal([]string{"US"})) Expect(certificate.Subject.Locality).To(Equal([]string{"New York"})) Expect(certificate.Subject.Organization).To(Equal([]string{"Cloud Foundry"})) Expect(certificate.Subject.OrganizationalUnit).To(Equal([]string{"PCF Dev"})) Expect(certificate.Subject.Province).To(Equal([]string{"New York"})) Expect(certificate.IsCA).To(BeFalse()) }) Context("CA Cert", func() { It("should be a CA Cert", func() { _, _, caCertificateBytes, caPrivateKeyBytes, err := c.GenerateCerts("some-domain") Expect(err).NotTo(HaveOccurred()) certificate := parseCertificate(caCertificateBytes, caPrivateKeyBytes) Expect(certificate.IsCA).To(BeTrue()) }) }) }) }) func parseCertificate(certificateBytes []byte, privateKeyBytes []byte) *x509.Certificate { certificate, err := tls.X509KeyPair(certificateBytes, privateKeyBytes) Expect(err).NotTo(HaveOccurred()) certificates, err := x509.ParseCertificates(certificate.Certificate[0]) Expect(err).NotTo(HaveOccurred()) return certificates[0] } ================================================ FILE: src/provisioner/fs/fs.go ================================================ package fs import ( "fmt" "io" "io/ioutil" "os" ) const ( FileModeRootReadWrite = 0644 FileModeRootReadWriteExecutable = 0744 ) type FS struct{} func (fs *FS) Exists(path string) (bool, error) { if _, err := os.Stat(path); err != nil { if os.IsNotExist(err) { return false, nil } return false, err } return true, nil } func (f *FS) Read(path string) ([]byte, error) { return ioutil.ReadFile(path) } func (f *FS) Mkdir(path string) error { if err := os.MkdirAll(path, 0755); err != nil { return fmt.Errorf("failed to create directory: %s", err) } return nil } func (f *FS) Write(path string, contents io.Reader, perm os.FileMode) error { file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) if err != nil { return fmt.Errorf("failed to open file: %s", err) } defer file.Close() if _, err := io.Copy(file, contents); err != nil { return fmt.Errorf("failed to copy contents to file: %s", err) } return nil } ================================================ FILE: src/provisioner/fs/fs_suite_test.go ================================================ package fs_test import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "testing" ) func TestFS(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "FS Suite") } ================================================ FILE: src/provisioner/fs/fs_test.go ================================================ package fs_test import ( "io/ioutil" "os" "path/filepath" "provisioner/fs" "strings" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("FS", func() { var ( f *fs.FS tempDir string ) BeforeEach(func() { f = &fs.FS{} var err error tempDir, err = ioutil.TempDir("", "pcfdev-fs") Expect(err).NotTo(HaveOccurred()) }) AfterEach(func() { os.RemoveAll(tempDir) }) Describe("#Mkdir", func() { Context("when the directory does not exist", func() { It("should create the directory", func() { Expect(f.Mkdir(filepath.Join(tempDir, "some-dir"))).To(Succeed()) _, err := os.Stat(filepath.Join(tempDir, "some-dir")) Expect(err).NotTo(HaveOccurred()) }) }) Context("when the directory already exists", func() { BeforeEach(func() { Expect(os.Mkdir(filepath.Join(tempDir, "some-dir"), 0755)).To(Succeed()) }) It("should do nothing", func() { Expect(f.Mkdir(filepath.Join(tempDir, "some-dir"))).To(Succeed()) _, err := os.Stat(filepath.Join(tempDir, "some-dir")) Expect(err).NotTo(HaveOccurred()) }) }) }) Describe("#Write", func() { Context("when path is valid", func() { It("should create a file with path and writes contents", func() { readCloser := ioutil.NopCloser(strings.NewReader("some-contents")) Expect(f.Write(filepath.Join(tempDir, "some-file"), readCloser, os.FileMode(fs.FileModeRootReadWrite))).To(Succeed()) data, err := ioutil.ReadFile(filepath.Join(tempDir, "some-file")) Expect(err).NotTo(HaveOccurred()) Expect(string(data)).To(Equal("some-contents")) }) }) Context("when file exists already", func() { BeforeEach(func() { Expect(f.Write(filepath.Join(tempDir, "some-file"), ioutil.NopCloser(strings.NewReader("some-content-that-is-really-long")), os.FileMode(fs.FileModeRootReadWrite))).To(Succeed()) }) It("should overwrite the file", func() { readCloser := ioutil.NopCloser(strings.NewReader("some-other-contents")) Expect(f.Write(filepath.Join(tempDir, "some-file"), readCloser, os.FileMode(fs.FileModeRootReadWrite))).To(Succeed()) data, err := ioutil.ReadFile(filepath.Join(tempDir, "some-file")) Expect(err).NotTo(HaveOccurred()) Expect(string(data)).To(Equal("some-other-contents")) }) }) Context("when path is invalid", func() { It("should return an error", func() { Expect(f.Write(filepath.Join("some-bad-dir", "some-other-file"), nil, os.FileMode(fs.FileModeRootReadWrite))).To(MatchError(ContainSubstring("failed to open file:"))) }) }) }) Describe("#Read", func() { Context("when the file exists", func() { It("should return the contents the file", func() { Expect(ioutil.WriteFile(filepath.Join(tempDir, "some-file"), []byte("some-contents"), 0644)).To(Succeed()) Expect(f.Read(filepath.Join(tempDir, "some-file"))).To(Equal([]byte("some-contents"))) }) }) }) Describe("#Exists", func() { Context("when the file exists", func() { BeforeEach(func() { _, err := os.Create(filepath.Join(tempDir, "some-file")) Expect(err).NotTo(HaveOccurred()) }) It("should return true", func() { Expect(f.Exists(filepath.Join(tempDir, "some-file"))).To(BeTrue()) }) }) Context("when the file does not exist", func() { It("should return false", func() { Expect(f.Exists(filepath.Join(tempDir, "some-bad-file"))).To(BeFalse()) }) }) }) }) ================================================ FILE: src/provisioner/main.go ================================================ package main import ( "fmt" "io/ioutil" "os" "os/exec" "provisioner/cert" "provisioner/fs" "provisioner/provisioner" "provisioner/provisioner/commands" "strconv" "syscall" "time" ) var ( provisionScriptPath = "/var/pcfdev/run" timeoutInSeconds = "3600" distro = "pcf" ) func main() { checkArgCount() provisionTimeout, err := strconv.Atoi(timeoutInSeconds) if err != nil { fmt.Printf("Error: %s.", err) os.Exit(1) } silentCommandRunner := &provisioner.ConcreteCmdRunner{ Stdout: ioutil.Discard, Stderr: ioutil.Discard, Timeout: time.Duration(provisionTimeout) * time.Second, } p := &provisioner.Provisioner{ Cert: &cert.Cert{}, CmdRunner: &provisioner.ConcreteCmdRunner{ Stdout: os.Stdout, Stderr: os.Stderr, Timeout: time.Duration(provisionTimeout) * time.Second, }, FS: &fs.FS{}, Commands: buildCommands(silentCommandRunner), Distro: distro, } if err := p.Provision(provisionScriptPath, os.Args[1:]...); err != nil { switch err.(type) { case *exec.ExitError: if exitErr, ok := err.(*exec.ExitError); ok { if status, ok := exitErr.Sys().(syscall.WaitStatus); ok { os.Exit(status.ExitStatus()) } else { os.Exit(1) } } case *provisioner.TimeoutError: fmt.Printf("Timed out after %s seconds.\n", timeoutInSeconds) os.Exit(1) default: os.Exit(1) } } } func checkArgCount() { if len(os.Args) < 6 { fmt.Println("Need 5 arguments, Usage: ./provision ") os.Exit(1) } } func buildCommands(commandRunner provisioner.CmdRunner) []provisioner.Command { providerAgnostic := []provisioner.Command{ &commands.DisableUAAHSTS{ WebXMLPath: "/var/vcap/packages/uaa/tomcat/conf/web.xml", }, &commands.ConfigureDnsmasq{ Domain: os.Args[1], ExternalIP: os.Args[2], FS: &fs.FS{}, CmdRunner: commandRunner, }, &commands.ConfigureGardenDNS{ FS: &fs.FS{}, CmdRunner: commandRunner, }, &commands.SetupApi{ CmdRunner: commandRunner, FS: &fs.FS{}, }, &commands.ReplaceDomain{ CmdRunner: commandRunner, FS: &fs.FS{}, NewDomain: os.Args[1], }, &commands.SetupCFDot{ CmdRunner: commandRunner, FS: &fs.FS{}, }, } const ( httpPort = "80" httpsPort = "443" sshPort = "22" sshProxyPort = "2222" tcpPortLower = 61001 tcpPortHigher = 61100 ) forAwsProvider := []provisioner.Command{ &commands.CloseAllPorts{ CmdRunner: commandRunner, }, &commands.OpenPort{ CmdRunner: commandRunner, Port: httpPort, }, &commands.OpenPort{ CmdRunner: commandRunner, Port: httpsPort, }, &commands.OpenPort{ CmdRunner: commandRunner, Port: sshPort, }, &commands.OpenPort{ CmdRunner: commandRunner, Port: sshProxyPort, }, } for p := tcpPortLower; p <= tcpPortHigher; p++ { forAwsProvider = append(forAwsProvider, &commands.OpenPort{ CmdRunner: commandRunner, Port: strconv.Itoa(p), }) } if isAwsProvisioner() { return append(providerAgnostic, forAwsProvider...) } else { return providerAgnostic } } func isAwsProvisioner() bool { return os.Args[5] == "aws" } ================================================ FILE: src/provisioner/main_suite_test.go ================================================ package main_test import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "testing" ) func TestPCFDev(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "PCF Dev Main Suite") } ================================================ FILE: src/provisioner/main_test.go ================================================ package main_test import ( "os" "os/exec" "strings" "regexp" "path/filepath" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/onsi/gomega/gbytes" "github.com/onsi/gomega/gexec" "math/rand" "net" "strconv" "time" ) var _ = Describe("PCF Dev provision", func() { var ( dockerID string pwd string dockerExecTimeout string = "5s" randomTcpPort string ) var portsForwarded struct { Port80 string Port8060 string Port443 string Port22 string Port2222 string Port61001 string Port61100 string RandomTcpPort string } BeforeEach(func() { portsForwarded.Port80 = randomOpenPort() portsForwarded.Port8060 = randomOpenPort() portsForwarded.Port443 = randomOpenPort() portsForwarded.Port22 = randomOpenPort() portsForwarded.Port2222 = randomOpenPort() portsForwarded.Port61001 = randomOpenPort() portsForwarded.Port61100 = randomOpenPort() portsForwarded.RandomTcpPort = randomOpenPort() var err error pwd, err = os.Getwd() Expect(err).NotTo(HaveOccurred()) randomTcpPort = randomPortInRange("61001", "61100") output, err := exec.Command( "docker", "run", "-p", portsForwarded.Port80+":80", "-p", portsForwarded.Port8060+":8060", "-p", portsForwarded.Port443+":443", "-p", portsForwarded.Port22+":22", "-p", portsForwarded.Port2222+":2222", "-p", portsForwarded.Port61001+":61001", "-p", portsForwarded.Port61100+":61100", "-p", portsForwarded.RandomTcpPort+":"+randomTcpPort, "--privileged", "-d", "-v", pwd+":/go/src/provisioner", "-w", "/go/src/provisioner", "pcfdev/provision", "bash", "-c", "umount /etc/resolv.conf && sleep 1000", ).Output() Expect(err).NotTo(HaveOccurred()) dockerID = strings.TrimSpace(string(output)) Expect(exec.Command("bash", "-c", "echo \"#!/bin/bash\necho 'Waiting for services to start...'\necho \\$@\" > "+pwd+"/provision-script").Run()).To(Succeed()) Expect(exec.Command("docker", "exec", dockerID, "chmod", "+x", "/go/src/provisioner/provision-script").Run()).To(Succeed()) Expect(exec.Command("docker", "exec", dockerID, "go", "build", "-ldflags", "-X main.provisionScriptPath=/go/src/provisioner/provision-script", "-o", "provision", "provisioner").Run()).To(Succeed()) runSuccessfully(exec.Command("docker", "exec", dockerID, "mkdir", "-p", "/var/pcfdev"), "10s") runSuccessfully(exec.Command("docker", "exec", dockerID, "bash", "-c", "echo original-domain.pcfdev.io > /var/pcfdev/domain"), "10s") runSuccessfully(exec.Command("docker", "exec", dockerID, "mkdir", "-p", "/var/vcap/jobs/cfdot/bin"), "10s") runSuccessfully(exec.Command("docker", "exec", dockerID, "bash", "-c", "echo 'echo setting up cfdot' > /var/vcap/jobs/cfdot/bin/setup"), "10s") }) AfterEach(func() { os.RemoveAll(filepath.Join(pwd, "provision")) os.RemoveAll(filepath.Join(pwd, "provision-script")) Expect(exec.Command("docker", "rm", dockerID, "-f").Run()).To(Succeed()) }) It("should provision PCF Dev", func() { session := provisionForVirtualBox(dockerID) Expect(session).To(gbytes.Say("Waiting for services to start...")) session = runSuccessfully(exec.Command("docker", "exec", dockerID, "file", "/run/pcfdev-healthcheck"), dockerExecTimeout) Expect(session).NotTo(gbytes.Say("No such file or directory")) }) It("should set up the monitrc files for an HTTP server and an root executable _ctl script running on the box", func() { provisionForVirtualBox(dockerID) session := runSuccessfully(exec.Command("docker", "exec", dockerID, "cat", "/var/vcap/monit/job/1001_pcfdev_api.monitrc"), dockerExecTimeout) Expect(session).To(gbytes.Say("check process pcfdev-api")) Expect(session).To(gbytes.Say("with pidfile /var/vcap/sys/run/pcfdev-api/api.pid")) Expect(session).To(gbytes.Say(`start program "/var/pcfdev/api/api_ctl start"`)) Expect(session).To(gbytes.Say(`stop program "/var/pcfdev/api/api_ctl stop"`)) Expect(session).To(gbytes.Say("group vcap")) Expect(session).To(gbytes.Say("mode manual")) session = runSuccessfully(exec.Command("docker", "exec", dockerID, "ls", "-l", "/var/pcfdev/api/api_ctl"), dockerExecTimeout) Expect(session).To(gbytes.Say("-rwxr--r--")) }) XIt("should create certificates", func() { provisionForVirtualBox(dockerID) runSuccessfully(exec.Command("docker", "exec", dockerID, "bash", "-c", "echo 127.0.0.1 local.pcfdev.io >> /etc/hosts"), dockerExecTimeout) runSuccessfully(exec.Command("docker", "exec", "-d", dockerID, "service", "nginx", "start"), dockerExecTimeout) runSuccessfully(exec.Command("docker", "exec", dockerID, "curl", "--cacert", "/var/pcfdev/openssl/ca_cert.pem", "https://local.pcfdev.io:443"), dockerExecTimeout) }) It("should disable HSTS in UAA", func() { provisionForVirtualBox(dockerID) session := runSuccessfully(exec.Command("docker", "exec", dockerID, "grep", "-A", "1", "hstsEnabled", "/var/vcap/packages/uaa/tomcat/conf/web.xml"), dockerExecTimeout) Eventually(session).Should(gbytes.Say("false")) }) It("should directly insert the internal-ip into the dns_server flag of garden", func() { provisionForVirtualBox(dockerID) output, err := exec.Command("docker", "exec", dockerID, "ip", "route", "get", "1").Output() Expect(err).NotTo(HaveOccurred()) regex := regexp.MustCompile(`\s{2}src\s(.*)`) internalIP := regex.FindStringSubmatch(string(output))[1] session := runSuccessfully(exec.Command("docker", "exec", dockerID, "grep", internalIP, "/var/vcap/jobs/garden/bin/garden_ctl"), dockerExecTimeout) Eventually(session).Should(gbytes.Say("-dnsServer=" + internalIP)) }) It("should copy cfdot setup script to /etc/profile.d", func() { provisionForVirtualBox(dockerID) output, err := exec.Command("docker", "exec", dockerID, "bash", "-c", "cat /etc/profile.d/cfdot.sh").Output() Expect(err).NotTo(HaveOccurred()) Expect(string(output)).To(Equal("echo setting up cfdot\n")) }) Describe("Network access", func() { Context("on AWS", func() { It("does not allow connections by default", func() { Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", "8060").Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.Port8060, 5*time.Second) provisionForAws(dockerID) runFailure(exec.Command("curl", "localhost:"+portsForwarded.Port8060), "5s") }) It("allows external access to http cf router", func() { Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", "80").Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.Port80, 5*time.Second) provisionForAws(dockerID) session := runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.Port80), "5s") Expect(session).To(gbytes.Say("Response from port 80 stub server")) }) It("allows external access to https cf router", func() { Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", "443").Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.Port443, 5*time.Second) provisionForAws(dockerID) session := runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.Port443), "5s") Expect(session).To(gbytes.Say("Response from port 443 stub server")) }) It("allows external access to ssh", func() { Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", "22").Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.Port22, 5*time.Second) provisionForAws(dockerID) session := runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.Port22), "5s") Expect(session).To(gbytes.Say("Response from port 22 stub server")) }) It("allows external access to the ssh proxy", func() { Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", "2222").Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.Port2222, 5*time.Second) provisionForAws(dockerID) session := runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.Port2222), "5s") Expect(session).To(gbytes.Say("Response from port 2222 stub server")) }) It("allow external access to tcp router port for lowest port in range", func() { Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", "61001").Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.Port61001, 5*time.Second) provisionForAws(dockerID) session := runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.Port61001), "5s") Expect(session).To(gbytes.Say("Response from port 61001 stub server")) }) It("allow external access to tcp router port for highest port in range", func() { Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", "61100").Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.Port61100, 5*time.Second) provisionForAws(dockerID) session := runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.Port61100), "5s") Expect(session).To(gbytes.Say("Response from port 61100 stub server")) }) It("allow external access to tcp router port for random port in range", func() { Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", randomTcpPort).Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.RandomTcpPort, 5*time.Second) provisionForAws(dockerID) session := runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.RandomTcpPort), "5s") Expect(session).To(gbytes.Say("Response from port " + randomTcpPort + " stub server")) }) }) Context("on Virtualbox", func() { It("allows connections by default", func() { Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", "8060").Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.Port8060, 5*time.Second) Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", "80").Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.Port80, 5*time.Second) Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", "443").Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.Port443, 5*time.Second) Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", "22").Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.Port22, 5*time.Second) Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", "2222").Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.Port2222, 5*time.Second) Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", "61001").Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.Port61001, 5*time.Second) Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", "61100").Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.Port61100, 5*time.Second) Expect(exec.Command("docker", "exec", "-d", dockerID, "go", "run", "assets/stub_server.go", randomTcpPort).Run()).To(Succeed()) waitForServer("localhost:"+portsForwarded.RandomTcpPort, 5*time.Second) provisionForVirtualBox(dockerID) Expect(runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.Port80), "5s")).To(gbytes.Say("Response from port 80 stub server")) Expect(runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.Port8060), "5s")).To(gbytes.Say("Response from port 8060 stub server")) Expect(runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.Port443), "5s")).To(gbytes.Say("Response from port 443 stub server")) Expect(runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.Port22), "5s")).To(gbytes.Say("Response from port 22 stub server")) Expect(runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.Port2222), "5s")).To(gbytes.Say("Response from port 2222 stub server")) Expect(runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.Port61001), "5s")).To(gbytes.Say("Response from port 61001 stub server")) Expect(runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.Port61100), "5s")).To(gbytes.Say("Response from port 61100 stub server")) Expect(runSuccessfully(exec.Command("curl", "localhost:"+portsForwarded.RandomTcpPort), "5s")).To(gbytes.Say("Response from port " + randomTcpPort + " stub server")) }) }) }) It("should resolve *.cf.internal to localhost using Dnsmasq", func() { provisionForVirtualBox(dockerID) session := runSuccessfully(exec.Command("docker", "exec", dockerID, "host", "bbs.service.cf.internal"), "3s") Eventually(session).Should(gbytes.Say(`bbs.service.cf.internal has address 127.0.0.1`)) }) It("should replace the old domain with the new domain in job files recursively without following symlinks", func() { runSuccessfully(exec.Command("docker", "exec", dockerID, "mkdir", "-p", "/var/vcap/jobs/some-job/config"), "10s") runSuccessfully(exec.Command("docker", "exec", dockerID, "bash", "-c", "echo 'domain: original-domain.pcfdev.io' > /var/vcap/jobs/some-job/config/some-file"), "10s") runSuccessfully(exec.Command("docker", "exec", dockerID, "mkdir", "-p", "/var/vcap/jobs/some-other-job/config/some-nested-dir"), "10s") runSuccessfully(exec.Command("docker", "exec", dockerID, "bash", "-c", "echo 'api: api.original-domain.pcfdev.io:443' > /var/vcap/jobs/some-other-job/config/some-nested-dir/some-file"), "10s") runSuccessfully(exec.Command("docker", "exec", dockerID, "mkdir", "-p", "/tmp/some-symlinked-dir"), "10s") runSuccessfully(exec.Command("docker", "exec", dockerID, "bash", "-c", "echo 'domain: original-domain.pcfdev.io' > /tmp/some-symlinked-dir/some-file"), "10s") runSuccessfully(exec.Command("docker", "exec", dockerID, "mkdir", "-p", "/var/vcap/jobs/some-job-with-symlink/config"), "10s") runSuccessfully(exec.Command("docker", "exec", dockerID, "ln", "-s", "/tmp/some-symlinked-dir", "/var/vcap/jobs/some-job-with-symlink/config"), "10s") runSuccessfully(exec.Command("docker", "exec", dockerID, "/go/src/provisioner/provision", "new-domain.pcfdev.io", "192.168.11.11", "", "", "virtualbox"), "100000s") Expect(runSuccessfully(exec.Command("docker", "exec", dockerID, "cat", "/var/vcap/jobs/some-job/config/some-file"), "10s")).To(gbytes.Say("domain: new-domain.pcfdev.io")) Expect(runSuccessfully(exec.Command("docker", "exec", dockerID, "cat", "/var/vcap/jobs/some-other-job/config/some-nested-dir/some-file"), "10s")).To(gbytes.Say("api: api.new-domain.pcfdev.io:443")) Expect(runSuccessfully(exec.Command("docker", "exec", dockerID, "cat", "/var/vcap/jobs/some-job-with-symlink/config/some-symlinked-dir/some-file"), "10s")).To(gbytes.Say("domain: original-domain.pcfdev.io")) }) Context("when the distribution is not 'pcf'", func() { BeforeEach(func() { Expect(exec.Command("docker", "exec", dockerID, "go", "build", "-ldflags", "-X main.distro=oss -X main.provisionScriptPath=/go/src/provisioner/provision-script", "-o", "provision", "provisioner").Run()).To(Succeed()) }) It("should not disable HSTS in UAA", func() { provisionForVirtualBox(dockerID) session, err := gexec.Start(exec.Command("docker", "exec", dockerID, "grep", "hstsEnabled", "/var/vcap/packages/uaa/tomcat/conf/web.xml"), GinkgoWriter, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) Eventually(session).Should(gexec.Exit(1)) }) }) Context("when provisioning does not have the required number of args", func() { It("should exit with an error", func() { runFailure(exec.Command("docker", "exec", dockerID, "/go/src/provisioner/provision", "local.pcfdev.io", "192.168.11.11", "", ""), "10s") }) }) Context("when provisioning fails", func() { BeforeEach(func() { Expect(exec.Command("bash", "-c", "echo \"#!/bin/bash\nexit 42\" > "+pwd+"/provision-script").Run()).To(Succeed()) }) It("should exit with the exit status of the provision script", func() { session, _ := gexec.Start(exec.Command("docker", "exec", dockerID, "/go/src/provisioner/provision", "local.pcfdev.io", "192.168.11.11", "", "", "virtualbox"), GinkgoWriter, GinkgoWriter) Eventually(session, "10s").Should(gexec.Exit(42)) }) }) Context("when provisioning takes too long", func() { BeforeEach(func() { Expect(exec.Command("bash", "-c", "echo \"#!/bin/bash\nsleep 20\" > "+pwd+"/provision-script").Run()).To(Succeed()) Expect(exec.Command("docker", "exec", dockerID, "go", "build", "-ldflags", "-X main.provisionScriptPath=/go/src/provisioner/provision-script -X main.timeoutInSeconds=2", "-o", "provision", "provisioner").Run()).To(Succeed()) }) It("exit with an exit status of 1 and tell why it is exiting...", func() { session, err := gexec.Start(exec.Command("docker", "exec", dockerID, "/go/src/provisioner/provision", "local.pcfdev.io", "192.168.11.11", "", "", "virtualbox"), GinkgoWriter, GinkgoWriter) Expect(err).NotTo(HaveOccurred()) Eventually(session, "15s").Should(gexec.Exit(1)) Expect(session).To(gbytes.Say("Timed out after 2 seconds.")) }) }) }) func provisionForVirtualBox(dockerID string) *gexec.Session { return runSuccessfully(exec.Command("docker", "exec", dockerID, "/go/src/provisioner/provision", "local.pcfdev.io", "192.168.11.11", "", "", "virtualbox"), "10s") } func provisionForAws(dockerID string) *gexec.Session { return runSuccessfully(exec.Command("docker", "exec", dockerID, "/go/src/provisioner/provision", "local.pcfdev.io", "192.168.11.11", "", "", "aws"), "10s") } func runSuccessfully(command *exec.Cmd, timeout string) *gexec.Session { session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter) ExpectWithOffset(1, err).NotTo(HaveOccurred()) EventuallyWithOffset(1, session, timeout).Should(gexec.Exit(0)) return session } func runFailure(command *exec.Cmd, timeout string) *gexec.Session { session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter) ExpectWithOffset(1, err).NotTo(HaveOccurred()) ConsistentlyWithOffset(1, session, timeout).ShouldNot(gexec.Exit(0)) return session } func randomOpenPort() string { conn, err := net.Listen("tcp", "127.0.0.1:0") Expect(err).NotTo(HaveOccurred()) defer conn.Close() address := strings.Split(conn.Addr().String(), ":") return address[1] } func waitForServer(host string, timeout time.Duration) { currentWait := 0 * time.Second serverOpen := false for !serverOpen && currentWait < timeout { exec.Command("curl", host) session, _ := gexec.Start(exec.Command("curl", host), GinkgoWriter, GinkgoWriter) Eventually(session, "1s").Should(gexec.Exit()) if session.ExitCode() == 0 { serverOpen = true } currentWait += time.Second * 1 time.Sleep(time.Second) } Expect(serverOpen).To(BeTrue()) } func randomPortInRange(lowerPort string, higherPort string) string { higherPortNumber, err := strconv.Atoi(higherPort) Expect(err).NotTo(HaveOccurred()) lowerPortNumber, err := strconv.Atoi(lowerPort) Expect(err).NotTo(HaveOccurred()) return strconv.Itoa(rand.Intn(higherPortNumber-lowerPortNumber) + lowerPortNumber) } ================================================ FILE: src/provisioner/provisioner/commands/close_all_ports.go ================================================ package commands import ( "provisioner/provisioner" ) type CloseAllPorts struct { CmdRunner provisioner.CmdRunner } func (c *CloseAllPorts) Run() error { if err := c.dropNewConnections("eth0"); err != nil { return err } if err := c.dropNewConnections("eth1"); err != nil { return err } return c.CmdRunner.Run("iptables", "-I", "INPUT", "-i", "lo", "-j", "ACCEPT") } func (c *CloseAllPorts) dropNewConnections(interfaceName string) error { if err := c.CmdRunner.Run("iptables", "-I", "INPUT", "-i", interfaceName, "-p", "tcp", "-j", "DROP"); err != nil { return err } return c.CmdRunner.Run("iptables", "-I", "INPUT", "-i", interfaceName, "-m", "conntrack", "--ctstate", "ESTABLISHED,RELATED", "-j", "ACCEPT") } func (*CloseAllPorts) Distro() string { return provisioner.DistributionOSS } ================================================ FILE: src/provisioner/provisioner/commands/commands_suite_test.go ================================================ package commands_test import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "testing" ) func TestCommands(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "Commands Suite") } ================================================ FILE: src/provisioner/provisioner/commands/configure_dnsmasq.go ================================================ package commands import ( "fmt" "provisioner/provisioner" "regexp" "strings" "provisioner/fs" ) type ConfigureDnsmasq struct { FS provisioner.FS CmdRunner provisioner.CmdRunner Domain string ExternalIP string } func (c *ConfigureDnsmasq) Run() error { if err := c.CmdRunner.Run("resolvconf", "--disable-updates"); err != nil { return err } if err := c.CmdRunner.Run("service", "dnsmasq", "stop"); err != nil { return err } output, err := c.CmdRunner.Output("ip", "route", "get", "1") if err != nil { return err } var internalIP string regex := regexp.MustCompile(`\s{2}src\s(.*)`) if matches := regex.FindStringSubmatch(string(output)); len(matches) > 1 { internalIP = matches[1] } else { return fmt.Errorf("internal ip could not be parsed from output: %s", string(output)) } if err := c.FS.Write("/etc/dnsmasq.d/domain", strings.NewReader(fmt.Sprintf("address=/.%s/%s\naddress=/.cf.internal/127.0.0.1", c.Domain, c.ExternalIP)), fs.FileModeRootReadWrite); err != nil { return err } if err := c.FS.Write("/etc/dnsmasq.d/interface", strings.NewReader(fmt.Sprintf("listen-address=%s", internalIP)), fs.FileModeRootReadWrite); err != nil { return err } if err := c.FS.Write("/etc/dnsmasq.conf", strings.NewReader("resolv-file=/var/pcfdev/external-resolv.conf"), fs.FileModeRootReadWrite); err != nil { return err } exists, err := c.FS.Exists("/var/pcfdev/external-resolv.conf") if err != nil { return err } if !exists { data, err := c.FS.Read("/etc/resolv.conf") if err != nil { return err } nameservers := []string{} for _, nameserver := range strings.Split(string(data), "\n") { if strings.HasPrefix(nameserver, "nameserver") && !strings.Contains(nameserver, "127.0.0.1") { nameservers = append(nameservers, nameserver) } } if err := c.FS.Write("/var/pcfdev/external-resolv.conf", strings.NewReader(strings.Join(nameservers, "\n")), fs.FileModeRootReadWrite); err != nil { return err } } if err := c.CmdRunner.Run("service", "dnsmasq", "start"); err != nil { return err } return c.FS.Write("/etc/resolv.conf", strings.NewReader(fmt.Sprintf("nameserver %s", internalIP)), fs.FileModeRootReadWrite) } func (*ConfigureDnsmasq) Distro() string { return provisioner.DistributionOSS } ================================================ FILE: src/provisioner/provisioner/commands/configure_dnsmasq_test.go ================================================ package commands_test import ( "errors" "provisioner/provisioner" "provisioner/provisioner/commands" "provisioner/provisioner/mocks" "strings" "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "os" "provisioner/fs" ) var _ = Describe("ConfigureDnsmasq", func() { var ( mockCtrl *gomock.Controller mockFS *mocks.MockFS mockCmdRunner *mocks.MockCmdRunner cDnsmasq *commands.ConfigureDnsmasq ) BeforeEach(func() { mockCtrl = gomock.NewController(GinkgoT()) mockFS = mocks.NewMockFS(mockCtrl) mockCmdRunner = mocks.NewMockCmdRunner(mockCtrl) cDnsmasq = &commands.ConfigureDnsmasq{ FS: mockFS, CmdRunner: mockCmdRunner, Domain: "some-domain", ExternalIP: "some-external-ip", } }) AfterEach(func() { mockCtrl.Finish() }) Describe("#Run", func() { Context("when there are external nameservers in /etc/resolv.conf", func() { It("should write dns resolutions for consul and domain into the dnsmasq config and save external nameservers", func() { gomock.InOrder( mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates"), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "stop"), mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Write("/etc/dnsmasq.d/domain", strings.NewReader("address=/.some-domain/some-external-ip\naddress=/.cf.internal/127.0.0.1"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.d/interface", strings.NewReader("listen-address=some-internal-ip"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.conf", strings.NewReader("resolv-file=/var/pcfdev/external-resolv.conf"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Exists("/var/pcfdev/external-resolv.conf").Return(false, nil), mockFS.EXPECT().Read("/etc/resolv.conf").Return([]byte("nameserver 127.0.0.1\nnameserver some-external-nameserver\n# Generated by bosh-agent\nnameserver some-other-external-nameserver"), nil), mockFS.EXPECT().Write("/var/pcfdev/external-resolv.conf", strings.NewReader("nameserver some-external-nameserver\nnameserver some-other-external-nameserver"), os.FileMode(fs.FileModeRootReadWrite)), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "start"), mockFS.EXPECT().Write("/etc/resolv.conf", strings.NewReader("nameserver some-internal-ip"), os.FileMode(fs.FileModeRootReadWrite)), ) Expect(cDnsmasq.Run()).To(Succeed()) }) }) Context("when there are no external nameservers in /etc/resolv.conf", func() { It("should write dns resolutions for consul and domain into the dnsmasq config and save external nameservers", func() { gomock.InOrder( mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates"), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "stop"), mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Write("/etc/dnsmasq.d/domain", strings.NewReader("address=/.some-domain/some-external-ip\naddress=/.cf.internal/127.0.0.1"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.d/interface", strings.NewReader("listen-address=some-internal-ip"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.conf", strings.NewReader("resolv-file=/var/pcfdev/external-resolv.conf"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Exists("/var/pcfdev/external-resolv.conf").Return(false, nil), mockFS.EXPECT().Read("/etc/resolv.conf").Return([]byte("nameserver 127.0.0.1"), nil), mockFS.EXPECT().Write("/var/pcfdev/external-resolv.conf", strings.NewReader(""), os.FileMode(fs.FileModeRootReadWrite)), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "start"), mockFS.EXPECT().Write("/etc/resolv.conf", strings.NewReader("nameserver some-internal-ip"), os.FileMode(fs.FileModeRootReadWrite)), ) Expect(cDnsmasq.Run()).To(Succeed()) }) }) Context("when external-resolv.conf already exists", func() { It("should not overwrite the file", func() { gomock.InOrder( mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates"), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "stop"), mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Write("/etc/dnsmasq.d/domain", strings.NewReader("address=/.some-domain/some-external-ip\naddress=/.cf.internal/127.0.0.1"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.d/interface", strings.NewReader("listen-address=some-internal-ip"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.conf", strings.NewReader("resolv-file=/var/pcfdev/external-resolv.conf"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Exists("/var/pcfdev/external-resolv.conf").Return(true, nil), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "start"), mockFS.EXPECT().Write("/etc/resolv.conf", strings.NewReader("nameserver some-internal-ip"), os.FileMode(fs.FileModeRootReadWrite)), ) Expect(cDnsmasq.Run()).To(Succeed()) }) }) Context("when there is an error disabling resolvconf updates", func() { It("should return the error", func() { mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates").Return(errors.New("some-error")) Expect(cDnsmasq.Run()).To(MatchError("some-error")) }) }) Context("when there is an error stopping dnsmasq", func() { It("should return the error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates"), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "stop").Return(errors.New("some-error")), ) Expect(cDnsmasq.Run()).To(MatchError("some-error")) }) }) Context("when there is an error writing the dnsmasq conf", func() { It("should return the error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates"), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "stop"), mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Write("/etc/dnsmasq.d/domain", strings.NewReader("address=/.some-domain/some-external-ip\naddress=/.cf.internal/127.0.0.1"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.d/interface", strings.NewReader("listen-address=some-internal-ip"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.conf", strings.NewReader("resolv-file=/var/pcfdev/external-resolv.conf"), os.FileMode(fs.FileModeRootReadWrite)).Return(errors.New("some-error")), ) Expect(cDnsmasq.Run()).To(MatchError("some-error")) }) }) Context("when there is an error checking the resolv conf", func() { It("should return the error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates"), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "stop"), mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Write("/etc/dnsmasq.d/domain", strings.NewReader("address=/.some-domain/some-external-ip\naddress=/.cf.internal/127.0.0.1"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.d/interface", strings.NewReader("listen-address=some-internal-ip"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.conf", strings.NewReader("resolv-file=/var/pcfdev/external-resolv.conf"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Exists("/var/pcfdev/external-resolv.conf").Return(false, errors.New("some-error")), ) Expect(cDnsmasq.Run()).To(MatchError("some-error")) }) }) Context("when there is an error reading the resolv conf", func() { It("should return the error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates"), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "stop"), mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Write("/etc/dnsmasq.d/domain", strings.NewReader("address=/.some-domain/some-external-ip\naddress=/.cf.internal/127.0.0.1"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.d/interface", strings.NewReader("listen-address=some-internal-ip"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.conf", strings.NewReader("resolv-file=/var/pcfdev/external-resolv.conf"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Exists("/var/pcfdev/external-resolv.conf").Return(false, nil), mockFS.EXPECT().Read("/etc/resolv.conf").Return(nil, errors.New("some-error")), ) Expect(cDnsmasq.Run()).To(MatchError("some-error")) }) }) Context("when there is an error writing the pcfdev external resolv.conf", func() { It("should return the error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates"), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "stop"), mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Write("/etc/dnsmasq.d/domain", strings.NewReader("address=/.some-domain/some-external-ip\naddress=/.cf.internal/127.0.0.1"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.d/interface", strings.NewReader("listen-address=some-internal-ip"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.conf", strings.NewReader("resolv-file=/var/pcfdev/external-resolv.conf"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Exists("/var/pcfdev/external-resolv.conf").Return(false, nil), mockFS.EXPECT().Read("/etc/resolv.conf").Return([]byte("nameserver 127.0.0.1\nnameserver some-external-nameserver\nnameserver some-other-external-nameserver"), nil), mockFS.EXPECT().Write("/var/pcfdev/external-resolv.conf", strings.NewReader("nameserver some-external-nameserver\nnameserver some-other-external-nameserver"), os.FileMode(fs.FileModeRootReadWrite)).Return(errors.New("some-error")), ) Expect(cDnsmasq.Run()).To(MatchError("some-error")) }) }) Context("when there is an error starting dnsmasq", func() { It("should return the error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates"), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "stop"), mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Write("/etc/dnsmasq.d/domain", strings.NewReader("address=/.some-domain/some-external-ip\naddress=/.cf.internal/127.0.0.1"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.d/interface", strings.NewReader("listen-address=some-internal-ip"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.conf", strings.NewReader("resolv-file=/var/pcfdev/external-resolv.conf"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Exists("/var/pcfdev/external-resolv.conf").Return(false, nil), mockFS.EXPECT().Read("/etc/resolv.conf").Return([]byte("nameserver 127.0.0.1\nnameserver some-external-nameserver\nnameserver some-other-external-nameserver"), nil), mockFS.EXPECT().Write("/var/pcfdev/external-resolv.conf", strings.NewReader("nameserver some-external-nameserver\nnameserver some-other-external-nameserver"), os.FileMode(fs.FileModeRootReadWrite)), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "start").Return(errors.New("some-error")), ) Expect(cDnsmasq.Run()).To(MatchError("some-error")) }) }) Context("when there is an error writing to the /etc/resolv.conf", func() { It("should return the error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates"), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "stop"), mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Write("/etc/dnsmasq.d/domain", strings.NewReader("address=/.some-domain/some-external-ip\naddress=/.cf.internal/127.0.0.1"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.d/interface", strings.NewReader("listen-address=some-internal-ip"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.conf", strings.NewReader("resolv-file=/var/pcfdev/external-resolv.conf"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Exists("/var/pcfdev/external-resolv.conf").Return(false, nil), mockFS.EXPECT().Read("/etc/resolv.conf").Return([]byte("nameserver 127.0.0.1\nnameserver some-external-nameserver\nnameserver some-other-external-nameserver"), nil), mockFS.EXPECT().Write("/var/pcfdev/external-resolv.conf", strings.NewReader("nameserver some-external-nameserver\nnameserver some-other-external-nameserver"), os.FileMode(fs.FileModeRootReadWrite)), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "start"), mockFS.EXPECT().Write("/etc/resolv.conf", strings.NewReader("nameserver some-internal-ip"), os.FileMode(fs.FileModeRootReadWrite)).Return(errors.New("some-error")), ) Expect(cDnsmasq.Run()).To(MatchError("some-error")) }) }) Context("when the internal ip is not returned from the output", func() { It("should return an error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates"), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "stop"), mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-bad-output"), nil), ) Expect(cDnsmasq.Run()).To(MatchError("internal ip could not be parsed from output: some-bad-output")) }) }) Context("when there is an error retrieving the internal ip", func() { It("should return an error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates"), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "stop"), mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return(nil, errors.New("some-error")), ) Expect(cDnsmasq.Run()).To(MatchError("some-error")) }) }) Context("when there is an error writing the dnsmasq configuration", func() { It("should return an error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates"), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "stop"), mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Write("/etc/dnsmasq.d/domain", strings.NewReader("address=/.some-domain/some-external-ip\naddress=/.cf.internal/127.0.0.1"), os.FileMode(fs.FileModeRootReadWrite)).Return(errors.New("some-error")), ) Expect(cDnsmasq.Run()).To(MatchError("some-error")) }) }) Context("when there is an error writing the dnsmasq interface configuration", func() { It("should return an error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Run("resolvconf", "--disable-updates"), mockCmdRunner.EXPECT().Run("service", "dnsmasq", "stop"), mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Write("/etc/dnsmasq.d/domain", strings.NewReader("address=/.some-domain/some-external-ip\naddress=/.cf.internal/127.0.0.1"), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/etc/dnsmasq.d/interface", strings.NewReader("listen-address=some-internal-ip"), os.FileMode(fs.FileModeRootReadWrite)).Return(errors.New("some-error")), ) Expect(cDnsmasq.Run()).To(MatchError("some-error")) }) }) }) Describe("#Distro", func() { It("should return 'oss'", func() { Expect(cDnsmasq.Distro()).To(Equal(provisioner.DistributionOSS)) }) }) }) ================================================ FILE: src/provisioner/provisioner/commands/configure_garden_dns.go ================================================ package commands import ( "fmt" "provisioner/provisioner" "regexp" "strings" "provisioner/fs" ) type ConfigureGardenDNS struct { FS provisioner.FS CmdRunner provisioner.CmdRunner } func (c *ConfigureGardenDNS) Run() error { output, err := c.CmdRunner.Output("ip", "route", "get", "1") if err != nil { return err } var internalIP string regex := regexp.MustCompile(`\s{2}src\s(.*)`) if matches := regex.FindStringSubmatch(string(output)); len(matches) > 1 { internalIP = matches[1] } else { return fmt.Errorf("internal ip could not be parsed from output: %s", string(output)) } gardenBytes, err := c.FS.Read("/var/vcap/jobs/garden/bin/garden_ctl") if err != nil { return err } cleanedGardenCtl := []string{} for _, line := range strings.Split(string(gardenBytes), "\n") { if !strings.Contains(line, "-dnsServer=") { cleanedGardenCtl = append(cleanedGardenCtl, line) } } dnsInsertString := strings.Replace(strings.Join(cleanedGardenCtl, "\n"), `1>>$LOG_DIR/garden.stdout.log \`, fmt.Sprintf("-dnsServer=%s \\\n 1>>$LOG_DIR/garden.stdout.log \\", internalIP), fs.FileModeRootReadWrite) return c.FS.Write("/var/vcap/jobs/garden/bin/garden_ctl", strings.NewReader(dnsInsertString), fs.FileModeRootReadWrite) } func (*ConfigureGardenDNS) Distro() string { return provisioner.DistributionOSS } ================================================ FILE: src/provisioner/provisioner/commands/configure_garden_dns_test.go ================================================ package commands_test import ( "provisioner/provisioner/commands" "provisioner/provisioner/mocks" "strings" "github.com/cppforlife/packer-bosh/bosh-provisioner/Godeps/_workspace/src/github.com/cloudfoundry/bosh-agent/errors" "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "os" "provisioner/fs" "provisioner/provisioner" ) var _ = Describe("ConfigureGardenDNS", func() { var ( mockCtrl *gomock.Controller mockFS *mocks.MockFS mockCmdRunner *mocks.MockCmdRunner cmd *commands.ConfigureGardenDNS ) BeforeEach(func() { mockCtrl = gomock.NewController(GinkgoT()) mockFS = mocks.NewMockFS(mockCtrl) mockCmdRunner = mocks.NewMockCmdRunner(mockCtrl) cmd = &commands.ConfigureGardenDNS{ FS: mockFS, CmdRunner: mockCmdRunner, } }) AfterEach(func() { mockCtrl.Finish() }) Describe("#Run", func() { Context("when there are no dnsServers", func() { It("should use the internal IP as a DNS server in garden", func() { gomock.InOrder( mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Read("/var/vcap/jobs/garden/bin/garden_ctl").Return([]byte("some-executable \\\n -someProperty=some-value \\\n 1>>$LOG_DIR/garden.stdout.log \\"), nil), mockFS.EXPECT().Write("/var/vcap/jobs/garden/bin/garden_ctl", strings.NewReader("some-executable \\\n -someProperty=some-value \\\n -dnsServer=some-internal-ip \\\n 1>>$LOG_DIR/garden.stdout.log \\"), os.FileMode(fs.FileModeRootReadWrite)), ) Expect(cmd.Run()).To(Succeed()) }) }) Context("when there are dnsServers", func() { It("should use the internal IP as a DNS server in garden", func() { gomock.InOrder( mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Read("/var/vcap/jobs/garden/bin/garden_ctl").Return([]byte("some-executable \\\n -someProperty=some-value \\\n -dnsServer=some-ip \\\n -dnsServer=some-other-ip \\\n 1>>$LOG_DIR/garden.stdout.log \\"), nil), mockFS.EXPECT().Write("/var/vcap/jobs/garden/bin/garden_ctl", strings.NewReader("some-executable \\\n -someProperty=some-value \\\n -dnsServer=some-internal-ip \\\n 1>>$LOG_DIR/garden.stdout.log \\"), os.FileMode(fs.FileModeRootReadWrite)), ) Expect(cmd.Run()).To(Succeed()) }) }) Context("when there is an error gettting the internal ip", func() { It("return the error", func() { mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return(nil, errors.New("some-error")) Expect(cmd.Run()).To(MatchError("some-error")) }) }) Context("when the internal ip cannot be parsed", func() { It("return an error", func() { mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-bad-output"), nil) Expect(cmd.Run()).To(MatchError("internal ip could not be parsed from output: some-bad-output")) }) }) Context("when there is an error reading the garden ctl", func() { It("return the error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Read("/var/vcap/jobs/garden/bin/garden_ctl").Return(nil, errors.New("some-error")), ) Expect(cmd.Run()).To(MatchError("some-error")) }) }) Context("when there is an error rewriting the garden ctl", func() { It("return the error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Output("ip", "route", "get", "1").Return([]byte("some-ip via some-other-ip dev eth0 src some-internal-ip\n cache"), nil), mockFS.EXPECT().Read("/var/vcap/jobs/garden/bin/garden_ctl").Return([]byte("some-executable \\\n -someProperty=some-value \\\n -dnsServer=some-ip \\\n -dnsServer=some-other-ip \\\n 1>>$LOG_DIR/garden.stdout.log \\"), nil), mockFS.EXPECT().Write("/var/vcap/jobs/garden/bin/garden_ctl", strings.NewReader("some-executable \\\n -someProperty=some-value \\\n -dnsServer=some-internal-ip \\\n 1>>$LOG_DIR/garden.stdout.log \\"), os.FileMode(fs.FileModeRootReadWrite)).Return(errors.New("some-error")), ) Expect(cmd.Run()).To(MatchError("some-error")) }) }) }) Describe("#Distro", func() { It("should return 'oss'", func() { Expect(cmd.Distro()).To(Equal(provisioner.DistributionOSS)) }) }) }) ================================================ FILE: src/provisioner/provisioner/commands/disable_uaa_hsts.go ================================================ package commands import ( "bytes" "encoding/xml" "io/ioutil" "os" "strings" "golang.org/x/net/html/charset" "provisioner/provisioner" ) type DisableUAAHSTS struct { WebXMLPath string } func (d *DisableUAAHSTS) Run() error { var webXMLData WebApp webXMLContents, err := ioutil.ReadFile(d.WebXMLPath) if err != nil { return err } decoder := xml.NewDecoder(bytes.NewReader(webXMLContents)) decoder.CharsetReader = charset.NewReaderLabel if err := decoder.Decode(&webXMLData); err != nil { return err } hstsFilter := Filter{ FilterName: "httpHeaderSecurity", FilterClass: "org.apache.catalina.filters.HttpHeaderSecurityFilter", InitParam: InitParam{ ParamName: "hstsEnabled", ParamValue: "false", }, AsyncSupported: true, } hstsFilterExists := false for _, filter := range webXMLData.Filters { if strings.TrimSpace(filter.FilterName) == strings.TrimSpace(hstsFilter.FilterName) && strings.TrimSpace(filter.FilterClass) == strings.TrimSpace(hstsFilter.FilterClass) && strings.TrimSpace(filter.InitParam.ParamName) == strings.TrimSpace(hstsFilter.InitParam.ParamName) { hstsFilterExists = true } } if hstsFilterExists { webXMLData.Filters = nil } else { webXMLData.Filters = []Filter{hstsFilter} } webXMLFile, err := os.OpenFile(d.WebXMLPath, os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { panic(err) } defer webXMLFile.Close() encoder := xml.NewEncoder(webXMLFile) encoder.Indent("", " ") if err := encoder.Encode(&webXMLData); err != nil { panic(err) } return nil } func (*DisableUAAHSTS) Distro() string { return provisioner.DistributionPCF } type WebApp struct { XMLName xml.Name `xml:"web-app"` Filters []Filter `xml:"filter"` AllXML string `xml:",innerxml"` } type Filter struct { FilterName string `xml:"filter-name"` FilterClass string `xml:"filter-class"` InitParam InitParam `xml:"init-param"` AsyncSupported bool `xml:"async-supported"` } type InitParam struct { ParamName string `xml:"param-name"` ParamValue string `xml:"param-value"` } ================================================ FILE: src/provisioner/provisioner/commands/disable_uaa_hsts_test.go ================================================ package commands_test import ( "encoding/xml" "io/ioutil" "os" "path/filepath" "provisioner/provisioner/commands" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "golang.org/x/net/html/charset" "provisioner/provisioner" ) var ( tempDir string webXMLPath string ) var _ = Describe("DisableUAAHSTS", func() { var cmd *commands.DisableUAAHSTS Describe("#Run", func() { BeforeEach(func() { var err error tempDir, err = ioutil.TempDir("", "pcfdev-commands") Expect(err).NotTo(HaveOccurred()) }) AfterEach(func() { os.RemoveAll(tempDir) }) Context("when HSTS is not disabled in tomcat's web.xml", func() { BeforeEach(func() { templateXMLpath := filepath.Join("..", "..", "assets", "tomcat-web.xml") writeTomcatXML(templateXMLpath) cmd = &commands.DisableUAAHSTS{ WebXMLPath: webXMLPath, } }) It("should edit tomcat's web.xml to disable HSTS", func() { webXMLData := decodeWebXML(webXMLPath) Expect(len(webXMLData.Filters)).To(Equal(0)) Expect(cmd.Run()).To(Succeed()) webXMLData = decodeWebXML(webXMLPath) Expect(len(webXMLData.Filters)).To(Equal(1)) Expect(webXMLData.Filters[0].FilterName).To(Equal("httpHeaderSecurity")) Expect(webXMLData.Filters[0].FilterClass).To(Equal("org.apache.catalina.filters.HttpHeaderSecurityFilter")) Expect(webXMLData.Filters[0].InitParam.ParamName).To(Equal("hstsEnabled")) Expect(webXMLData.Filters[0].InitParam.ParamValue).To(Equal("false")) Expect(webXMLData.Filters[0].AsyncSupported).To(BeTrue()) }) }) Context("when HSTS is already disabled in tomcat's web.xml", func() { BeforeEach(func() { templateXMLpath := filepath.Join("..", "..", "assets", "tomcat-web-hsts-disabled.xml") writeTomcatXML(templateXMLpath) cmd = &commands.DisableUAAHSTS{ WebXMLPath: webXMLPath, } }) It("should not add another filter and keep the other filters", func() { webXMLData := decodeWebXML(webXMLPath) Expect(len(webXMLData.Filters)).To(Equal(2)) Expect(webXMLData.Filters[0].FilterName).To(Equal("httpHeaderSecurity")) Expect(webXMLData.Filters[0].FilterClass).To(Equal("org.apache.catalina.filters.HttpHeaderSecurityFilter")) Expect(webXMLData.Filters[0].InitParam.ParamName).To(Equal("hstsEnabled")) Expect(webXMLData.Filters[0].InitParam.ParamValue).To(Equal("false")) Expect(webXMLData.Filters[0].AsyncSupported).To(BeTrue()) Expect(webXMLData.Filters[1].FilterName).To(Equal("some-other-filter")) Expect(webXMLData.Filters[1].FilterClass).To(Equal("some-other-company")) Expect(webXMLData.Filters[1].InitParam.ParamName).To(Equal("some-param")) Expect(webXMLData.Filters[1].InitParam.ParamValue).To(Equal("some-value")) Expect(cmd.Run()).To(Succeed()) webXMLData = decodeWebXML(webXMLPath) Expect(len(webXMLData.Filters)).To(Equal(2)) Expect(webXMLData.Filters[0].FilterName).To(Equal("httpHeaderSecurity")) Expect(webXMLData.Filters[0].FilterClass).To(Equal("org.apache.catalina.filters.HttpHeaderSecurityFilter")) Expect(webXMLData.Filters[0].InitParam.ParamName).To(Equal("hstsEnabled")) Expect(webXMLData.Filters[0].InitParam.ParamValue).To(Equal("false")) Expect(webXMLData.Filters[0].AsyncSupported).To(BeTrue()) Expect(webXMLData.Filters[1].FilterName).To(Equal("some-other-filter")) Expect(webXMLData.Filters[1].FilterClass).To(Equal("some-other-company")) Expect(webXMLData.Filters[1].InitParam.ParamName).To(Equal("some-param")) Expect(webXMLData.Filters[1].InitParam.ParamValue).To(Equal("some-value")) }) }) Context("when the path to the web.xml does not exist", func() { BeforeEach(func() { cmd = &commands.DisableUAAHSTS{ WebXMLPath: "/some/bad/path", } }) It("should return an error", func() { Expect(cmd.Run()).To(MatchError(ContainSubstring("no such file or directory"))) }) }) Context("when the XML being parsed is invalid", func() { BeforeEach(func() { templateXMLpath := filepath.Join("..", "..", "assets", "tomcat-web-invalid.xml") writeTomcatXML(templateXMLpath) cmd = &commands.DisableUAAHSTS{ WebXMLPath: webXMLPath, } }) It("should return an error", func() { Expect(cmd.Run()).To(MatchError(ContainSubstring("EOF"))) }) }) }) Describe("#Distro", func() { It("should return 'pcf'", func() { Expect(cmd.Distro()).To(Equal(provisioner.DistributionPCF)) }) }) }) func writeTomcatXML(path string) { webXMLContents, err := ioutil.ReadFile(path) Expect(err).NotTo(HaveOccurred()) webXMLPath = filepath.Join(tempDir, "web.xml") Expect(ioutil.WriteFile(webXMLPath, webXMLContents, 0644)).To(Succeed()) } func decodeWebXML(webXMLPath string) *commands.WebApp { var webXMLData commands.WebApp webXMLReader, err := os.Open(webXMLPath) defer webXMLReader.Close() Expect(err).NotTo(HaveOccurred()) decoder := xml.NewDecoder(webXMLReader) decoder.CharsetReader = charset.NewReaderLabel Expect(decoder.Decode(&webXMLData)).To(Succeed()) return &webXMLData } ================================================ FILE: src/provisioner/provisioner/commands/open_port.go ================================================ package commands import ( "provisioner/provisioner" ) type OpenPort struct { CmdRunner provisioner.CmdRunner Port string } func (o *OpenPort) Run() error { return o.CmdRunner.Run("iptables", "-I", "INPUT", "-p", "tcp", "--dport", o.Port, "-j", "ACCEPT") } func (*OpenPort) Distro() string { return provisioner.DistributionOSS } ================================================ FILE: src/provisioner/provisioner/commands/replace_domain.go ================================================ package commands import ( "fmt" "provisioner/fs" "provisioner/provisioner" "strings" ) type ReplaceDomain struct { CmdRunner provisioner.CmdRunner FS provisioner.FS NewDomain string } func (r *ReplaceDomain) Run() error { files, err := r.CmdRunner.Output("bash", "-c", "find /var/vcap/jobs/*/ -type f") if err != nil { return err } oldDomain, err := r.FS.Read("/var/pcfdev/domain") if err != nil { return err } err = r.CmdRunner.Run("bash", "-c", fmt.Sprintf(`perl -p -i -e s/\\Q%s\\E/%s/g %s`, strings.TrimSpace(string(oldDomain)), r.NewDomain, strings.Replace(string(files), "\n", " ", -1))) if err != nil { return err } return r.FS.Write("/var/pcfdev/domain", strings.NewReader(r.NewDomain), fs.FileModeRootReadWrite) } func (r *ReplaceDomain) Distro() string { return provisioner.DistributionOSS } ================================================ FILE: src/provisioner/provisioner/commands/replace_domain_test.go ================================================ package commands_test import ( "github.com/golang/mock/gomock" "strings" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "errors" "os" "provisioner/fs" "provisioner/provisioner" "provisioner/provisioner/commands" "provisioner/provisioner/mocks" ) var _ = Describe("ReplaceDomain", func() { var ( mockCtrl *gomock.Controller mockFS *mocks.MockFS mockCmdRunner *mocks.MockCmdRunner cmd *commands.ReplaceDomain ) BeforeEach(func() { mockCtrl = gomock.NewController(GinkgoT()) mockFS = mocks.NewMockFS(mockCtrl) mockCmdRunner = mocks.NewMockCmdRunner(mockCtrl) cmd = &commands.ReplaceDomain{ FS: mockFS, CmdRunner: mockCmdRunner, NewDomain: "some-new-domain", } }) AfterEach(func() { mockCtrl.Finish() }) Describe("#Run", func() { It("should replace the old domain with the new domain in all files (without following symlinks) in /var/vcap/jobs", func() { gomock.InOrder( mockCmdRunner.EXPECT().Output("bash", "-c", "find /var/vcap/jobs/*/ -type f").Return([]byte("/var/vcap/jobs/some-job/some-file\n/var/vcap/jobs/some-job/some-other-file"), nil), mockFS.EXPECT().Read("/var/pcfdev/domain").Return([]byte("some-old-domain\n"), nil), mockCmdRunner.EXPECT().Run("bash", "-c", `perl -p -i -e s/\\Qsome-old-domain\\E/some-new-domain/g /var/vcap/jobs/some-job/some-file /var/vcap/jobs/some-job/some-other-file`), mockFS.EXPECT().Write("/var/pcfdev/domain", strings.NewReader("some-new-domain"), os.FileMode(fs.FileModeRootReadWrite)), ) Expect(cmd.Run()).To(Succeed()) }) Context("when finding job files fails", func() { It("should return an error", func() { mockCmdRunner.EXPECT().Output("bash", "-c", "find /var/vcap/jobs/*/ -type f").Return(nil, errors.New("some-error")) Expect(cmd.Run()).To(MatchError("some-error")) }) }) Context("when reading domain file fails", func() { It("should return an error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Output("bash", "-c", "find /var/vcap/jobs/*/ -type f").Return([]byte("/var/vcap/jobs/some-job/some-file\n/var/vcap/jobs/some-job/some-other-file"), nil), mockFS.EXPECT().Read("/var/pcfdev/domain").Return(nil, errors.New("some-error")), ) Expect(cmd.Run()).To(MatchError("some-error")) }) }) Context("when replacing the domain in the job files fails", func() { It("should return an error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Output("bash", "-c", "find /var/vcap/jobs/*/ -type f").Return([]byte("/var/vcap/jobs/some-job/some-file\n/var/vcap/jobs/some-job/some-other-file"), nil), mockFS.EXPECT().Read("/var/pcfdev/domain").Return([]byte("some-old-domain\n"), nil), mockCmdRunner.EXPECT().Run("bash", "-c", `perl -p -i -e s/\\Qsome-old-domain\\E/some-new-domain/g /var/vcap/jobs/some-job/some-file /var/vcap/jobs/some-job/some-other-file`).Return(errors.New("some-error")), ) Expect(cmd.Run()).To(MatchError("some-error")) }) }) Context("when writing the new domain fails", func() { It("should return an error", func() { gomock.InOrder( mockCmdRunner.EXPECT().Output("bash", "-c", "find /var/vcap/jobs/*/ -type f").Return([]byte("/var/vcap/jobs/some-job/some-file\n/var/vcap/jobs/some-job/some-other-file"), nil), mockFS.EXPECT().Read("/var/pcfdev/domain").Return([]byte("some-old-domain\n"), nil), mockCmdRunner.EXPECT().Run("bash", "-c", `perl -p -i -e s/\\Qsome-old-domain\\E/some-new-domain/g /var/vcap/jobs/some-job/some-file /var/vcap/jobs/some-job/some-other-file`), mockFS.EXPECT().Write("/var/pcfdev/domain", strings.NewReader("some-new-domain"), os.FileMode(fs.FileModeRootReadWrite)).Return(errors.New("some-error")), ) Expect(cmd.Run()).To(MatchError("some-error")) }) }) }) Describe("#Distro", func() { It("should return 'oss'", func() { Expect(cmd.Distro()).To(Equal(provisioner.DistributionOSS)) }) }) }) ================================================ FILE: src/provisioner/provisioner/commands/setup_api.go ================================================ package commands import ( "provisioner/provisioner" "strings" "provisioner/fs" ) type SetupApi struct { CmdRunner provisioner.CmdRunner FS provisioner.FS } func (s *SetupApi) Run() error { monitrcContents := `check process pcfdev-api with pidfile /var/vcap/sys/run/pcfdev-api/api.pid start program "/var/pcfdev/api/api_ctl start" stop program "/var/pcfdev/api/api_ctl stop" group vcap mode manual` apiCtlContents := `#!/bin/bash set -ex PIDFILE=/var/vcap/sys/run/pcfdev-api/api.pid case $1 in start) mkdir -p /var/vcap/sys/run/pcfdev-api /var/pcfdev/api/api & echo $! > ${PIDFILE} ;; stop) kill $(cat $PIDFILE) ;; *) echo "Usage: pcfdev_api_ctl {start|stop}" ;; esac` err := s.FS.Write("/var/vcap/monit/job/1001_pcfdev_api.monitrc", strings.NewReader(monitrcContents), fs.FileModeRootReadWrite) if err != nil { return err } return s.FS.Write("/var/pcfdev/api/api_ctl", strings.NewReader(apiCtlContents), fs.FileModeRootReadWriteExecutable) } func(s *SetupApi) Distro() string { return provisioner.DistributionOSS } ================================================ FILE: src/provisioner/provisioner/commands/setup_api_test.go ================================================ package commands_test import ( "github.com/golang/mock/gomock" "strings" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "errors" "os" "provisioner/fs" "provisioner/provisioner" "provisioner/provisioner/commands" "provisioner/provisioner/mocks" ) var _ = Describe("SetupApi", func() { var ( mockCtrl *gomock.Controller mockFS *mocks.MockFS mockCmdRunner *mocks.MockCmdRunner cmd *commands.SetupApi ) BeforeEach(func() { mockCtrl = gomock.NewController(GinkgoT()) mockFS = mocks.NewMockFS(mockCtrl) mockCmdRunner = mocks.NewMockCmdRunner(mockCtrl) cmd = &commands.SetupApi{ FS: mockFS, CmdRunner: mockCmdRunner, } }) AfterEach(func() { mockCtrl.Finish() }) Describe("#Run", func() { Context("When the file system is in a bad state", func() { It("returns the error from failing to write the monitrc", func() { mockFS.EXPECT().Write("/var/pcfdev/api/api_ctl", gomock.Any(), os.FileMode(fs.FileModeRootReadWriteExecutable)).AnyTimes() mockFS.EXPECT().Write("/var/vcap/monit/job/1001_pcfdev_api.monitrc", gomock.Any(), os.FileMode(fs.FileModeRootReadWrite)).Return(errors.New("some-error")) Expect(cmd.Run()).To(MatchError("some-error")) }) It("returns the error from failing to write the api_ctl", func() { mockFS.EXPECT().Write("/var/vcap/monit/job/1001_pcfdev_api.monitrc", gomock.Any(), os.FileMode(fs.FileModeRootReadWrite)).AnyTimes() mockFS.EXPECT().Write("/var/pcfdev/api/api_ctl", gomock.Any(), os.FileMode(fs.FileModeRootReadWriteExecutable)).Return(errors.New("some-error")) Expect(cmd.Run()).To(MatchError("some-error")) }) }) It("write a monit file to the /var/vcap/monit/job", func() { monitrc := `check process pcfdev-api with pidfile /var/vcap/sys/run/pcfdev-api/api.pid start program "/var/pcfdev/api/api_ctl start" stop program "/var/pcfdev/api/api_ctl stop" group vcap mode manual` monit_ctl := `#!/bin/bash set -ex PIDFILE=/var/vcap/sys/run/pcfdev-api/api.pid case $1 in start) mkdir -p /var/vcap/sys/run/pcfdev-api /var/pcfdev/api/api & echo $! > ${PIDFILE} ;; stop) kill $(cat $PIDFILE) ;; *) echo "Usage: pcfdev_api_ctl {start|stop}" ;; esac` gomock.InOrder( mockFS.EXPECT().Write("/var/vcap/monit/job/1001_pcfdev_api.monitrc", strings.NewReader(monitrc), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/var/pcfdev/api/api_ctl", strings.NewReader(monit_ctl), os.FileMode(fs.FileModeRootReadWriteExecutable)), ) Expect(cmd.Run()).To(Succeed()) }) }) Describe("#Distro", func() { It("should return 'oss'", func() { Expect(cmd.Distro()).To(Equal(provisioner.DistributionOSS)) }) }) }) ================================================ FILE: src/provisioner/provisioner/commands/setup_cfdot.go ================================================ package commands import ( "provisioner/provisioner" "strings" "provisioner/fs" ) type SetupCFDot struct { CmdRunner provisioner.CmdRunner FS provisioner.FS } func (s *SetupCFDot) Run() error { setupFileContentsBytes, err := s.FS.Read("/var/vcap/jobs/cfdot/bin/setup") if err != nil { return err } return s.FS.Write("/etc/profile.d/cfdot.sh", strings.NewReader(string(setupFileContentsBytes)), fs.FileModeRootReadWrite) } func (s *SetupCFDot) Distro() string { return provisioner.DistributionOSS } ================================================ FILE: src/provisioner/provisioner/commands/setup_cfdot_test.go ================================================ package commands_test import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/golang/mock/gomock" "provisioner/fs" "provisioner/provisioner" "provisioner/provisioner/mocks" "provisioner/provisioner/commands" "strings" "os" ) var _ = Describe("SetupCFDot", func() { var ( mockCtrl *gomock.Controller mockFS *mocks.MockFS mockCmdRunner *mocks.MockCmdRunner cmd *commands.SetupCFDot ) BeforeEach(func() { mockCtrl = gomock.NewController(GinkgoT()) mockFS = mocks.NewMockFS(mockCtrl) mockCmdRunner = mocks.NewMockCmdRunner(mockCtrl) cmd = &commands.SetupCFDot{ FS: mockFS, CmdRunner: mockCmdRunner, } }) AfterEach(func() { mockCtrl.Finish() }) Describe("#Run", func() { It("should create a new file with content copied from /var/vcap/jobs/cfdot/bin/setup", func() { mockFS.EXPECT().Read("/var/vcap/jobs/cfdot/bin/setup").Return([]byte("cf-dot-setup-stuff-here\n"), nil) mockFS.EXPECT().Write("/etc/profile.d/cfdot.sh", strings.NewReader("cf-dot-setup-stuff-here\n"), os.FileMode(fs.FileModeRootReadWrite)) Expect(cmd.Run()).To(Succeed()) }) }) Describe("#Distro", func() { It("should return 'oss'", func() { Expect(cmd.Distro()).To(Equal(provisioner.DistributionOSS)) }) }) }) ================================================ FILE: src/provisioner/provisioner/concrete_cmd_runner.go ================================================ package provisioner import ( "io" "os/exec" "syscall" "time" ) type ConcreteCmdRunner struct { Stdout io.Writer Stderr io.Writer Timeout time.Duration } func (r *ConcreteCmdRunner) Run(command string, args ...string) error { cmd := exec.Command(command, args...) cmd.Stdout = r.Stdout cmd.Stderr = r.Stderr cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true} if err := cmd.Start(); err != nil { return err } timer := time.AfterFunc(r.Timeout, func() { pgid, err := syscall.Getpgid(cmd.Process.Pid) if err == nil { syscall.Kill(-pgid, 15) } }) err := cmd.Wait() if !timer.Stop() { return &TimeoutError{} } return err } func (r *ConcreteCmdRunner) Output(command string, args ...string) ([]byte, error) { return exec.Command(command, args...).CombinedOutput() } ================================================ FILE: src/provisioner/provisioner/concrete_cmd_runner_test.go ================================================ package provisioner_test import ( "provisioner/provisioner" "time" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/onsi/gomega/gbytes" ) var _ = Describe("ConcreteCmdRunner", func() { var r *provisioner.ConcreteCmdRunner Describe("#Run", func() { var ( stdout *gbytes.Buffer stderr *gbytes.Buffer ) BeforeEach(func() { stdout = gbytes.NewBuffer() stderr = gbytes.NewBuffer() r = &provisioner.ConcreteCmdRunner{ Stdout: stdout, Stderr: stderr, Timeout: 2 * time.Second, } }) It("should run commands", func() { Expect(r.Run("echo", "-n", "some output")).To(Succeed()) Eventually(stdout).Should(gbytes.Say("some output")) Expect(r.Run("bash", "-c", ">&2 echo -n some output")).To(Succeed()) Eventually(stderr).Should(gbytes.Say("some output")) }) It("should respects timeouts", func() { Expect(r.Run("bash", "-c", "sleep 5")).To(MatchError("timeout error")) }) Context("when there is an error", func() { It("should return the error and the output", func() { Expect(r.Run("/some/bad/binary")).To(MatchError(ContainSubstring("no such file or directory"))) }) }) }) Describe("#Output", func() { BeforeEach(func() { r = &provisioner.ConcreteCmdRunner{ Timeout: 2 * time.Second, } }) It("should run commands and return combined output", func() { output, err := r.Output("bash", "-c", "echo some-output; >&2 echo -n some-more-output") Expect(err).NotTo(HaveOccurred()) Expect(output).To(Equal([]byte("some-output\nsome-more-output"))) }) Context("when there is an error", func() { It("should return the error and the output", func() { _, err := r.Output("/some/bad/binary") Expect(err).To(MatchError(ContainSubstring("no such file or directory"))) }) }) }) }) ================================================ FILE: src/provisioner/provisioner/errors.go ================================================ package provisioner type TimeoutError struct{} func (t *TimeoutError) Error() string { return "timeout error" } ================================================ FILE: src/provisioner/provisioner/mocks/cert.go ================================================ // Automatically generated by MockGen. DO NOT EDIT! // Source: provisioner/provisioner (interfaces: Cert) package mocks import ( gomock "github.com/golang/mock/gomock" ) // Mock of Cert interface type MockCert struct { ctrl *gomock.Controller recorder *_MockCertRecorder } // Recorder for MockCert (not exported) type _MockCertRecorder struct { mock *MockCert } func NewMockCert(ctrl *gomock.Controller) *MockCert { mock := &MockCert{ctrl: ctrl} mock.recorder = &_MockCertRecorder{mock} return mock } func (_m *MockCert) EXPECT() *_MockCertRecorder { return _m.recorder } func (_m *MockCert) GenerateCerts(_param0 string) ([]byte, []byte, []byte, []byte, error) { ret := _m.ctrl.Call(_m, "GenerateCerts", _param0) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].([]byte) ret2, _ := ret[2].([]byte) ret3, _ := ret[3].([]byte) ret4, _ := ret[4].(error) return ret0, ret1, ret2, ret3, ret4 } func (_mr *_MockCertRecorder) GenerateCerts(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCall(_mr.mock, "GenerateCerts", arg0) } ================================================ FILE: src/provisioner/provisioner/mocks/cmd_runner.go ================================================ // Automatically generated by MockGen. DO NOT EDIT! // Source: provisioner/provisioner (interfaces: CmdRunner) package mocks import ( gomock "github.com/golang/mock/gomock" ) // Mock of CmdRunner interface type MockCmdRunner struct { ctrl *gomock.Controller recorder *_MockCmdRunnerRecorder } // Recorder for MockCmdRunner (not exported) type _MockCmdRunnerRecorder struct { mock *MockCmdRunner } func NewMockCmdRunner(ctrl *gomock.Controller) *MockCmdRunner { mock := &MockCmdRunner{ctrl: ctrl} mock.recorder = &_MockCmdRunnerRecorder{mock} return mock } func (_m *MockCmdRunner) EXPECT() *_MockCmdRunnerRecorder { return _m.recorder } func (_m *MockCmdRunner) Output(_param0 string, _param1 ...string) ([]byte, error) { _s := []interface{}{_param0} for _, _x := range _param1 { _s = append(_s, _x) } ret := _m.ctrl.Call(_m, "Output", _s...) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } func (_mr *_MockCmdRunnerRecorder) Output(arg0 interface{}, arg1 ...interface{}) *gomock.Call { _s := append([]interface{}{arg0}, arg1...) return _mr.mock.ctrl.RecordCall(_mr.mock, "Output", _s...) } func (_m *MockCmdRunner) Run(_param0 string, _param1 ...string) error { _s := []interface{}{_param0} for _, _x := range _param1 { _s = append(_s, _x) } ret := _m.ctrl.Call(_m, "Run", _s...) ret0, _ := ret[0].(error) return ret0 } func (_mr *_MockCmdRunnerRecorder) Run(arg0 interface{}, arg1 ...interface{}) *gomock.Call { _s := append([]interface{}{arg0}, arg1...) return _mr.mock.ctrl.RecordCall(_mr.mock, "Run", _s...) } ================================================ FILE: src/provisioner/provisioner/mocks/command.go ================================================ // Automatically generated by MockGen. DO NOT EDIT! // Source: provisioner/provisioner (interfaces: Command) package mocks import ( gomock "github.com/golang/mock/gomock" ) // Mock of Command interface type MockCommand struct { ctrl *gomock.Controller recorder *_MockCommandRecorder } // Recorder for MockCommand (not exported) type _MockCommandRecorder struct { mock *MockCommand } func NewMockCommand(ctrl *gomock.Controller) *MockCommand { mock := &MockCommand{ctrl: ctrl} mock.recorder = &_MockCommandRecorder{mock} return mock } func (_m *MockCommand) EXPECT() *_MockCommandRecorder { return _m.recorder } func (_m *MockCommand) Distro() string { ret := _m.ctrl.Call(_m, "Distro") ret0, _ := ret[0].(string) return ret0 } func (_mr *_MockCommandRecorder) Distro() *gomock.Call { return _mr.mock.ctrl.RecordCall(_mr.mock, "Distro") } func (_m *MockCommand) Run() error { ret := _m.ctrl.Call(_m, "Run") ret0, _ := ret[0].(error) return ret0 } func (_mr *_MockCommandRecorder) Run() *gomock.Call { return _mr.mock.ctrl.RecordCall(_mr.mock, "Run") } ================================================ FILE: src/provisioner/provisioner/mocks/fs.go ================================================ // Automatically generated by MockGen. DO NOT EDIT! // Source: provisioner/provisioner (interfaces: FS) package mocks import ( gomock "github.com/golang/mock/gomock" io "io" os "os" ) // Mock of FS interface type MockFS struct { ctrl *gomock.Controller recorder *_MockFSRecorder } // Recorder for MockFS (not exported) type _MockFSRecorder struct { mock *MockFS } func NewMockFS(ctrl *gomock.Controller) *MockFS { mock := &MockFS{ctrl: ctrl} mock.recorder = &_MockFSRecorder{mock} return mock } func (_m *MockFS) EXPECT() *_MockFSRecorder { return _m.recorder } func (_m *MockFS) Exists(_param0 string) (bool, error) { ret := _m.ctrl.Call(_m, "Exists", _param0) ret0, _ := ret[0].(bool) ret1, _ := ret[1].(error) return ret0, ret1 } func (_mr *_MockFSRecorder) Exists(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCall(_mr.mock, "Exists", arg0) } func (_m *MockFS) Mkdir(_param0 string) error { ret := _m.ctrl.Call(_m, "Mkdir", _param0) ret0, _ := ret[0].(error) return ret0 } func (_mr *_MockFSRecorder) Mkdir(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCall(_mr.mock, "Mkdir", arg0) } func (_m *MockFS) Read(_param0 string) ([]byte, error) { ret := _m.ctrl.Call(_m, "Read", _param0) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } func (_mr *_MockFSRecorder) Read(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCall(_mr.mock, "Read", arg0) } func (_m *MockFS) Write(_param0 string, _param1 io.Reader, _param2 os.FileMode) error { ret := _m.ctrl.Call(_m, "Write", _param0, _param1, _param2) ret0, _ := ret[0].(error) return ret0 } func (_mr *_MockFSRecorder) Write(arg0, arg1, arg2 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCall(_mr.mock, "Write", arg0, arg1, arg2) } ================================================ FILE: src/provisioner/provisioner/mocks/ui.go ================================================ // Automatically generated by MockGen. DO NOT EDIT! // Source: provisioner/provisioner (interfaces: UI) package mocks import ( gomock "github.com/golang/mock/gomock" ) // Mock of UI interface type MockUI struct { ctrl *gomock.Controller recorder *_MockUIRecorder } // Recorder for MockUI (not exported) type _MockUIRecorder struct { mock *MockUI } func NewMockUI(ctrl *gomock.Controller) *MockUI { mock := &MockUI{ctrl: ctrl} mock.recorder = &_MockUIRecorder{mock} return mock } func (_m *MockUI) EXPECT() *_MockUIRecorder { return _m.recorder } func (_m *MockUI) PrintHelpText(_param0 string) error { ret := _m.ctrl.Call(_m, "PrintHelpText", _param0) ret0, _ := ret[0].(error) return ret0 } func (_mr *_MockUIRecorder) PrintHelpText(arg0 interface{}) *gomock.Call { return _mr.mock.ctrl.RecordCall(_mr.mock, "PrintHelpText", arg0) } ================================================ FILE: src/provisioner/provisioner/provisioner.go ================================================ package provisioner import ( "bytes" "io" "os" "provisioner/fs" ) //go:generate mockgen -package mocks -destination mocks/cert.go provisioner/provisioner Cert type Cert interface { GenerateCerts(domain string) (certificate []byte, privateKey []byte, caCertificate []byte, caPrivateKey []byte, err error) } //go:generate mockgen -package mocks -destination mocks/cmd_runner.go provisioner/provisioner CmdRunner type CmdRunner interface { Run(command string, args ...string) error Output(command string, args ...string) (output []byte, err error) } //go:generate mockgen -package mocks -destination mocks/fs.go provisioner/provisioner FS type FS interface { Mkdir(directory string) error Write(path string, contents io.Reader, perm os.FileMode) error Read(path string) (contents []byte, err error) Exists(path string) (bool, error) } //go:generate mockgen -package mocks -destination mocks/ui.go provisioner/provisioner UI type UI interface { PrintHelpText(domain string) error } //go:generate mockgen -package mocks -destination mocks/command.go provisioner/provisioner Command type Command interface { Run() error Distro() string } type Provisioner struct { Cert Cert CmdRunner CmdRunner FS FS UI UI DisableUAAHSTS Command ConfigureDnsmasq Command Commands []Command Distro string } const ( DistributionOSS = "oss" DistributionPCF = "pcf" ) func (p *Provisioner) Provision(provisionScriptPath string, args ...string) error { domain := args[0] cert, key, caCert, _, err := p.Cert.GenerateCerts(domain) if err != nil { return err } if err := p.FS.Mkdir("/var/vcap/jobs/gorouter/config"); err != nil { return err } if err := p.FS.Write("/var/vcap/jobs/gorouter/config/cert.pem", bytes.NewReader(cert), fs.FileModeRootReadWrite); err != nil { return err } if err := p.FS.Write("/var/vcap/jobs/gorouter/config/key.pem", bytes.NewReader(key), fs.FileModeRootReadWrite); err != nil { return err } if err := p.FS.Mkdir("/var/pcfdev/openssl"); err != nil { return err } if err := p.FS.Write("/var/pcfdev/openssl/ca_cert.pem", bytes.NewReader(caCert), fs.FileModeRootReadWrite); err != nil { return err } for _, command := range p.Commands { if p.Distro == DistributionOSS && command.Distro() == DistributionPCF { continue } if err := command.Run(); err != nil { return err } } if err := p.CmdRunner.Run(provisionScriptPath, args...); err != nil { return err } return p.FS.Write("/run/pcfdev-healthcheck", bytes.NewReader([]byte("")), fs.FileModeRootReadWrite) } ================================================ FILE: src/provisioner/provisioner/provisioner_suite_test.go ================================================ package provisioner_test import ( . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "testing" ) func TestProvisioner(t *testing.T) { RegisterFailHandler(Fail) RunSpecs(t, "Provisioner Suite") } ================================================ FILE: src/provisioner/provisioner/provisioner_test.go ================================================ package provisioner_test import ( "bytes" "errors" "provisioner/provisioner" "provisioner/provisioner/mocks" "github.com/golang/mock/gomock" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "os" "provisioner/fs" ) var _ = Describe("Provisioner", func() { Describe("#Provision", func() { var ( p *provisioner.Provisioner mockCtrl *gomock.Controller mockCert *mocks.MockCert mockCmdRunner *mocks.MockCmdRunner mockFS *mocks.MockFS mockUI *mocks.MockUI firstCommand *mocks.MockCommand secondCommand *mocks.MockCommand ) BeforeEach(func() { mockCtrl = gomock.NewController(GinkgoT()) mockCert = mocks.NewMockCert(mockCtrl) mockCmdRunner = mocks.NewMockCmdRunner(mockCtrl) mockFS = mocks.NewMockFS(mockCtrl) mockUI = mocks.NewMockUI(mockCtrl) firstCommand = mocks.NewMockCommand(mockCtrl) secondCommand = mocks.NewMockCommand(mockCtrl) p = &provisioner.Provisioner{ Cert: mockCert, CmdRunner: mockCmdRunner, FS: mockFS, UI: mockUI, Commands: []provisioner.Command{ firstCommand, secondCommand, }, Distro: provisioner.DistributionPCF, } }) AfterEach(func() { mockCtrl.Finish() }) It("should provision a VM", func() { gomock.InOrder( mockCert.EXPECT().GenerateCerts("some-domain").Return([]byte("some-cert"), []byte("some-key"), []byte("some-ca-cert"), []byte("some-ca-key"), nil), mockFS.EXPECT().Mkdir("/var/vcap/jobs/gorouter/config"), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/cert.pem", bytes.NewReader([]byte("some-cert")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/key.pem", bytes.NewReader([]byte("some-key")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Mkdir("/var/pcfdev/openssl"), mockFS.EXPECT().Write("/var/pcfdev/openssl/ca_cert.pem", bytes.NewReader([]byte("some-ca-cert")), os.FileMode(fs.FileModeRootReadWrite)), firstCommand.EXPECT().Run(), secondCommand.EXPECT().Run(), mockCmdRunner.EXPECT().Run("some-provision-script-path", "some-domain"), mockFS.EXPECT().Write("/run/pcfdev-healthcheck", bytes.NewReader([]byte("")), os.FileMode(fs.FileModeRootReadWrite)), ) Expect(p.Provision("some-provision-script-path", "some-domain")).To(Succeed()) }) Context("when the distribution is oss", func() { It("should not run pcf 'Commands'", func() { p.Distro = provisioner.DistributionOSS gomock.InOrder( mockCert.EXPECT().GenerateCerts("some-domain").Return([]byte("some-cert"), []byte("some-key"), []byte("some-ca-cert"), []byte("some-ca-key"), nil), mockFS.EXPECT().Mkdir("/var/vcap/jobs/gorouter/config"), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/cert.pem", bytes.NewReader([]byte("some-cert")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/key.pem", bytes.NewReader([]byte("some-key")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Mkdir("/var/pcfdev/openssl"), mockFS.EXPECT().Write("/var/pcfdev/openssl/ca_cert.pem", bytes.NewReader([]byte("some-ca-cert")), os.FileMode(fs.FileModeRootReadWrite)), firstCommand.EXPECT().Distro().Return(provisioner.DistributionPCF), secondCommand.EXPECT().Distro().Return(provisioner.DistributionOSS), secondCommand.EXPECT().Run(), mockCmdRunner.EXPECT().Run("some-provision-script-path", "some-domain"), mockFS.EXPECT().Write("/run/pcfdev-healthcheck", bytes.NewReader([]byte("")), os.FileMode(fs.FileModeRootReadWrite)), ) Expect(p.Provision("some-provision-script-path", "some-domain")).To(Succeed()) }) }) Context("when there is an error generating certificate", func() { It("should return the error", func() { mockCert.EXPECT().GenerateCerts("some-domain").Return(nil, nil, nil, nil, errors.New("some-error")) Expect(p.Provision("some-provision-script-path", "some-domain")).To(MatchError("some-error")) }) }) Context("when there is an error creating the gorouter config directory", func() { It("should return the error", func() { gomock.InOrder( mockCert.EXPECT().GenerateCerts("some-domain").Return([]byte("some-cert"), []byte("some-key"), []byte("some-ca-cert"), []byte("some-ca-key"), nil), mockFS.EXPECT().Mkdir("/var/vcap/jobs/gorouter/config").Return(errors.New("some-error")), ) Expect(p.Provision("some-provision-script-path", "some-domain")).To(MatchError("some-error")) }) }) Context("when there is an error writing the certificate", func() { It("should return the error", func() { gomock.InOrder( mockCert.EXPECT().GenerateCerts("some-domain").Return([]byte("some-cert"), []byte("some-key"), []byte("some-ca-cert"), []byte("some-ca-key"), nil), mockFS.EXPECT().Mkdir("/var/vcap/jobs/gorouter/config"), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/cert.pem", bytes.NewReader([]byte("some-cert")), os.FileMode(fs.FileModeRootReadWrite)).Return(errors.New("some-error")), ) Expect(p.Provision("some-provision-script-path", "some-domain")).To(MatchError("some-error")) }) }) Context("when there is an error writing the private key", func() { It("should return the error", func() { gomock.InOrder( mockCert.EXPECT().GenerateCerts("some-domain").Return([]byte("some-cert"), []byte("some-key"), []byte("some-ca-cert"), []byte("some-ca-key"), nil), mockFS.EXPECT().Mkdir("/var/vcap/jobs/gorouter/config"), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/cert.pem", bytes.NewReader([]byte("some-cert")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/key.pem", bytes.NewReader([]byte("some-key")), os.FileMode(fs.FileModeRootReadWrite)).Return(errors.New("some-error")), ) Expect(p.Provision("some-provision-script-path", "some-domain")).To(MatchError("some-error")) }) }) Context("when there is an error creating the openssl directory", func() { It("should return the error", func() { gomock.InOrder( mockCert.EXPECT().GenerateCerts("some-domain").Return([]byte("some-cert"), []byte("some-key"), []byte("some-ca-cert"), []byte("some-ca-key"), nil), mockFS.EXPECT().Mkdir("/var/vcap/jobs/gorouter/config"), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/cert.pem", bytes.NewReader([]byte("some-cert")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/key.pem", bytes.NewReader([]byte("some-key")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Mkdir("/var/pcfdev/openssl").Return(errors.New("some-error")), ) Expect(p.Provision("some-provision-script-path", "some-domain")).To(MatchError("some-error")) }) }) Context("when there is an error writing the CA certificate", func() { It("should return the error", func() { gomock.InOrder( mockCert.EXPECT().GenerateCerts("some-domain").Return([]byte("some-cert"), []byte("some-key"), []byte("some-ca-cert"), []byte("some-ca-key"), nil), mockFS.EXPECT().Mkdir("/var/vcap/jobs/gorouter/config"), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/cert.pem", bytes.NewReader([]byte("some-cert")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/key.pem", bytes.NewReader([]byte("some-key")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Mkdir("/var/pcfdev/openssl"), mockFS.EXPECT().Write("/var/pcfdev/openssl/ca_cert.pem", bytes.NewReader([]byte("some-ca-cert")), os.FileMode(fs.FileModeRootReadWrite)).Return(errors.New("some-error")), ) Expect(p.Provision("some-provision-script-path", "some-domain")).To(MatchError("some-error")) }) }) Context("when a command fails", func() { It("should return an error", func() { gomock.InOrder( mockCert.EXPECT().GenerateCerts("some-domain").Return([]byte("some-cert"), []byte("some-key"), []byte("some-ca-cert"), []byte("some-ca-key"), nil), mockFS.EXPECT().Mkdir("/var/vcap/jobs/gorouter/config"), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/cert.pem", bytes.NewReader([]byte("some-cert")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/key.pem", bytes.NewReader([]byte("some-key")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Mkdir("/var/pcfdev/openssl"), mockFS.EXPECT().Write("/var/pcfdev/openssl/ca_cert.pem", bytes.NewReader([]byte("some-ca-cert")), os.FileMode(fs.FileModeRootReadWrite)), firstCommand.EXPECT().Run().Return(errors.New("some-error")), ) Expect(p.Provision("some-provision-script-path", "some-domain")).To(MatchError("some-error")) }) }) Context("when there is an error running the provision script", func() { It("should return the error", func() { gomock.InOrder( mockCert.EXPECT().GenerateCerts("some-domain").Return([]byte("some-cert"), []byte("some-key"), []byte("some-ca-cert"), []byte("some-ca-key"), nil), mockFS.EXPECT().Mkdir("/var/vcap/jobs/gorouter/config"), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/cert.pem", bytes.NewReader([]byte("some-cert")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/key.pem", bytes.NewReader([]byte("some-key")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Mkdir("/var/pcfdev/openssl"), mockFS.EXPECT().Write("/var/pcfdev/openssl/ca_cert.pem", bytes.NewReader([]byte("some-ca-cert")), os.FileMode(fs.FileModeRootReadWrite)), firstCommand.EXPECT().Run(), secondCommand.EXPECT().Run(), mockCmdRunner.EXPECT().Run("some-provision-script-path", "some-domain").Return(errors.New("some-error")), ) Expect(p.Provision("some-provision-script-path", "some-domain")).To(MatchError("some-error")) }) }) Context("when there is an error writing the healthcheck file", func() { It("should return the error", func() { gomock.InOrder( mockCert.EXPECT().GenerateCerts("some-domain").Return([]byte("some-cert"), []byte("some-key"), []byte("some-ca-cert"), []byte("some-ca-key"), nil), mockFS.EXPECT().Mkdir("/var/vcap/jobs/gorouter/config"), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/cert.pem", bytes.NewReader([]byte("some-cert")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Write("/var/vcap/jobs/gorouter/config/key.pem", bytes.NewReader([]byte("some-key")), os.FileMode(fs.FileModeRootReadWrite)), mockFS.EXPECT().Mkdir("/var/pcfdev/openssl"), mockFS.EXPECT().Write("/var/pcfdev/openssl/ca_cert.pem", bytes.NewReader([]byte("some-ca-cert")), os.FileMode(fs.FileModeRootReadWrite)), firstCommand.EXPECT().Run(), secondCommand.EXPECT().Run(), mockCmdRunner.EXPECT().Run("some-provision-script-path", "some-domain"), mockFS.EXPECT().Write("/run/pcfdev-healthcheck", bytes.NewReader([]byte("")), os.FileMode(fs.FileModeRootReadWrite)).Return(errors.New("some-error")), ) Expect(p.Provision("some-provision-script-path", "some-domain")).To(MatchError("some-error")) }) }) }) }) ================================================ FILE: versions.json ================================================ { "releases": { "binary-buildpack" : { "version": "1.0.11", "sha1": "897826f41d17ddc82967e8ced549c8f8565715b7", "source_location": "https://github.com/cloudfoundry/binary-buildpack-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/binary-buildpack-1.0.11-1496755011.tgz" }, "capi" : { "version": "1.27.0-2-gc89eb61", "sha1": "8e03eea2c64b3baf9de092fef13f71e3f17e460e", "source_location": "https://github.com/cloudfoundry/capi-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/capi-1.27.0-2-gc89eb61-1501026707.tgz" }, "cf" : { "version": "v259-1-g51ea620b", "sha1": "45eee862a3f5aabe1b18b95929afd163899d3ecc", "source_location": "https://github.com/cloudfoundry/cf-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/cf-v259-1-g51ea620b-1500397980.tgz" }, "cf-mysql" : { "version": "v35-1-g2ff76af5", "sha1": "b2407a1dff3389ffdf18f1dd2d90ddce20e331d6", "source_location": "https://github.com/cloudfoundry/cf-mysql-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/cf-mysql-v35-1-g2ff76af5-1501012547.tgz" }, "cflinuxfs2-rootfs" : { "version": "v1.116.0", "sha1": "fecbd6a141cd0956d319122d05ff210a096186ac", "source_location": "https://github.com/cloudfoundry/cflinuxfs2-rootfs-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/cflinuxfs2-v1.116.0-1497451333.tgz" }, "cf-networking" : { "version": "v0.25.0-2-gc862e46", "sha1": "3fb5c16ceb63be4edfd81309631fe1dc89f69aab", "source_location": "https://github.com/cloudfoundry-incubator/cf-networking-release", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/cf-networking-v0.25.0-2-gc862e46-1501024622.tgz" }, "consul" : { "version": "v152", "sha1": "96ef889efa01087f0495f55853e12ef37e114746", "source_location": "https://github.com/cloudfoundry-incubator/consul-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/consul-v152-1499709321.tgz" }, "diego" : { "version": "v1.15.0-2-gf3b6fd7a", "sha1": "15bd67d178791403469ceae62329ac8b29fbe5f6", "source_location": "https://github.com/cloudfoundry/diego-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/diego-v1.15.0-2-gf3b6fd7a-1501016603.tgz" }, "etcd" : { "version": "v104", "sha1": "d07f31e9e12b5f9d9c224411aac013afed1cf658", "source_location": "https://github.com/cloudfoundry-incubator/etcd-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/etcd-v104-1499707363.tgz" }, "garden-runc" : { "version": "v1.5.0", "sha1": "2d14be094a078047bfadf443ceb2f9799d5d3024", "source_location": "https://github.com/cloudfoundry/garden-runc-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/garden-runc-v1.5.0-1501067825.tgz" }, "go-buildpack" : { "version": "1.8.1", "sha1": "5a1ec163a70fc2f4602c2b76ab20f61a08730b60", "source_location": "https://github.com/cloudfoundry/go-buildpack-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/go-buildpack-1.8.1-1498226718.tgz" }, "java-offline-buildpack" : { "version": "3.16", "sha1": "ef9469f31363d55bbe327e899288be7f37f17e66", "source_location": "https://github.com/cloudfoundry/java-offline-buildpack-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/java-offline-buildpack-3.16-1496353415.tgz" }, "local-volume" : { "version": "brokerapi2.9-97-g54cd13f", "sha1": "846a49f3bec78c5d53cf1f69c2cfe9b4c491f21d", "source_location": "https://github.com/cloudfoundry-incubator/local-volume-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/local-volume-brokerapi2.9-97-g54cd13f-1498517156.tgz" }, "loggregator" : { "version": "v85-1-g331bf230", "sha1": "819e301ee0660702d531bb3fc322188b3dfe5164", "source_location": "https://github.com/cloudfoundry/loggregator.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/loggregator-v85-1-g331bf230-1501013779.tgz" }, "nats" : { "version": "v14-1-gd95b4d6", "sha1": "d35ef533b13a0cd2c8a2304a508388ede7305d02", "source_location": "https://github.com/cloudfoundry/nats-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/nats-v14-1-gd95b4d6-1500502388.tgz" }, "nodejs-buildpack" : { "version": "1.5.31", "sha1": "1f6b6305f794105ceb3b0a2c5989159fb3466b34", "source_location": "https://github.com/cloudfoundry/nodejs-buildpack-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/nodejs-buildpack-1.5.31-1501018153.tgz" }, "php-buildpack" : { "version": "4.3.31", "sha1": "f202386505ded742bf554e6d3cfbb4daca0b68d9", "source_location": "https://github.com/cloudfoundry/php-buildpack-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/php-buildpack-4.3.31-1500050473.tgz" }, "python-buildpack" : { "version": "1.5.18", "sha1": "d700feeb6930e88a7f4a7e0c33f90eee0eeaa2a6", "source_location": "https://github.com/cloudfoundry/python-buildpack-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/python-buildpack-1.5.18-1501018679.tgz" }, "routing" : { "version": "0.152.0-4-gc4e8657", "sha1": "f42a7ef39fbcfc90d7ea4c8619d6071d51d7f911", "source_location": "https://github.com/cloudfoundry-incubator/routing-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/routing-0.152.0-4-gc4e8657-1501020545.tgz" }, "ruby-buildpack" : { "version": "1.6.37", "sha1": "d8f25677a29088adc737088b1a395c6bacb16e1f", "source_location": "https://github.com/cloudfoundry/ruby-buildpack-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/ruby-buildpack-1.6.37-1501017963.tgz" }, "staticfile-buildpack" : { "version": "1.4.5", "sha1": "44091b829ca732703002f69b93151b29c2d05c9f", "source_location": "https://github.com/cloudfoundry/staticfile-buildpack-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/staticfile-buildpack-1.4.5-1500050172.tgz" }, "uaa" : { "version": "v34-1-g2b93080", "sha1": "c4bb8f6b925dbc5d32a0e15c4d88f5f6ef1e7b30", "source_location": "https://github.com/cloudfoundry/uaa-release.git", "compiled_release_url": "https://s3.amazonaws.com/pcfdev/compiled-releases/uaa-v34-1-g2b93080-1501014327.tgz" } } }