diff --git a/README.md b/README.md index ac8918b..af0e8a3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,14 @@ # capi-sidecar-samples Sample apps demonstrating how to use [sidecar processes](http://v3-apidocs.cloudfoundry.org/version/release-candidate/#sidecars) in Cloud Foundry. + +## Apps +This repository currently contains the following sample apps and sidecars. + +You can quickly deploy both apps by targeting your Cloud Foundry api using the `cf cli` and running the `push_sample_app_with_sidecar.sh` script. + +### config-server-sidecar +A simple Golang binary that emulates a "configuration server" for the parent app to call out to. + +### sidecar-dependent-app +A simple Sinatra app that calls out to the `config-server-sidecar` binary and echoes back its response. diff --git a/config-server-sidecar/.gitignore b/config-server-sidecar/.gitignore new file mode 100644 index 0000000..211cf7f --- /dev/null +++ b/config-server-sidecar/.gitignore @@ -0,0 +1 @@ +config-server diff --git a/config-server-sidecar/README.md b/config-server-sidecar/README.md new file mode 100644 index 0000000..ed573dd --- /dev/null +++ b/config-server-sidecar/README.md @@ -0,0 +1,15 @@ +# Sample "Config Server" Sidecar Process + +This is a simple Golang "config server" designed to be used along with the sample `sidecar-dependent-app`. +It listens on `localhost:$CONFIG_SERVER_PORT/config/` and returns some hard coded "configuration" for the parent app to consume. + + +## Building the binary +``` +GOOS=linux GOARCH=amd64 go build -o config-server . +``` + +## Running the config server +``` +CONFIG_SERVER_PORT=8082 ./config-server +``` diff --git a/config-server-sidecar/config_server.go b/config-server-sidecar/config_server.go new file mode 100644 index 0000000..aefb23a --- /dev/null +++ b/config-server-sidecar/config_server.go @@ -0,0 +1,35 @@ +package main + +import ( + "encoding/json" + "fmt" + "net/http" + "os" +) + +func main() { + // Emulate an external configuration service + http.HandleFunc("/config/", config) + fmt.Println("listening...") + err := http.ListenAndServe(":"+os.Getenv("CONFIG_SERVER_PORT"), nil) + if err != nil { + panic(err) + } +} + +type Config struct { + Scope string + Password string +} + +func config(res http.ResponseWriter, req *http.Request) { + config := Config{"some-service.admin", "not-a-real-p4$$w0rd"} + + js, err := json.Marshal(config) + if err != nil { + panic(err) + } + + fmt.Println("Received a request for config.") + fmt.Fprintln(res, string(js)) +} diff --git a/config-server-sidecar/manifest.yml b/config-server-sidecar/manifest.yml new file mode 100644 index 0000000..f67a93e --- /dev/null +++ b/config-server-sidecar/manifest.yml @@ -0,0 +1,4 @@ +--- +applications: +- env: + GOPACKAGENAME: config-server diff --git a/push_sample_app_with_sidecar.sh b/push_sample_app_with_sidecar.sh new file mode 100755 index 0000000..1d5d9c1 --- /dev/null +++ b/push_sample_app_with_sidecar.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +SAMPLE_APP_PATH="sidecar-dependent-app" +CONFIG_SERVER_SIDECAR_PATH="config-server-sidecar" + +function clean() { + rm "${SAMPLE_APP_PATH}/config-server" + rm "${CONFIG_SERVER_SIDECAR_PATH}/config-server" +} + +function build_config_server() { + pushd ${CONFIG_SERVER_SIDECAR_PATH} > /dev/null + GOOS=linux GOARCH=amd64 go build -o config-server . + popd > /dev/null + cp "${CONFIG_SERVER_SIDECAR_PATH}/config-server" ${SAMPLE_APP_PATH} +} + +function push_app_with_sidecars() { + pushd ${SAMPLE_APP_PATH} > /dev/null + cf v3-create-app sidecar-dependent-app + cf v3-apply-manifest -f manifest.yml + cf v3-push sidecar-dependent-app + popd > /dev/null +} + +function main() { + clean + build_config_server + push_app_with_sidecars +} + +main diff --git a/sidecar-dependent-app/.gitignore b/sidecar-dependent-app/.gitignore new file mode 100644 index 0000000..211cf7f --- /dev/null +++ b/sidecar-dependent-app/.gitignore @@ -0,0 +1 @@ +config-server diff --git a/sidecar-dependent-app/Gemfile b/sidecar-dependent-app/Gemfile new file mode 100644 index 0000000..4ef3816 --- /dev/null +++ b/sidecar-dependent-app/Gemfile @@ -0,0 +1,10 @@ +source "http://rubygems.org" + +gem "sinatra" +gem "json" +gem "typhoeus" + +group :test, :development do + gem "rspec" + gem "rack-test" +end diff --git a/sidecar-dependent-app/Gemfile.lock b/sidecar-dependent-app/Gemfile.lock new file mode 100644 index 0000000..7da8d19 --- /dev/null +++ b/sidecar-dependent-app/Gemfile.lock @@ -0,0 +1,48 @@ +GEM + remote: http://rubygems.org/ + specs: + diff-lcs (1.3) + ethon (0.12.0) + ffi (>= 1.3.0) + ffi (1.10.0) + json (2.1.0) + mustermann (1.0.3) + rack (2.0.6) + rack-protection (2.0.4) + rack + rack-test (0.8.3) + rack (>= 1.0, < 3) + rspec (3.7.0) + rspec-core (~> 3.7.0) + rspec-expectations (~> 3.7.0) + rspec-mocks (~> 3.7.0) + rspec-core (3.7.1) + rspec-support (~> 3.7.0) + rspec-expectations (3.7.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.7.0) + rspec-mocks (3.7.0) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.7.0) + rspec-support (3.7.1) + sinatra (2.0.4) + mustermann (~> 1.0) + rack (~> 2.0) + rack-protection (= 2.0.4) + tilt (~> 2.0) + tilt (2.0.9) + typhoeus (1.3.1) + ethon (>= 0.9.0) + +PLATFORMS + ruby + +DEPENDENCIES + json + rack-test + rspec + sinatra + typhoeus + +BUNDLED WITH + 1.17.3 diff --git a/sidecar-dependent-app/Procfile b/sidecar-dependent-app/Procfile new file mode 100644 index 0000000..8c99558 --- /dev/null +++ b/sidecar-dependent-app/Procfile @@ -0,0 +1 @@ +web: bundle exec rackup config.ru -p $PORT diff --git a/sidecar-dependent-app/README.md b/sidecar-dependent-app/README.md new file mode 100644 index 0000000..f032f64 --- /dev/null +++ b/sidecar-dependent-app/README.md @@ -0,0 +1,6 @@ +# Sample Sidecar-Dependent App + +This is a simple Sinatra-based Ruby app that calls out to a co-located `config-server` sidecar process to retrieve its "configuration." + +## Endpoints +* `GET /config` will echo back any configuration retrieved from the `config-server` sidecar diff --git a/sidecar-dependent-app/app_server.rb b/sidecar-dependent-app/app_server.rb new file mode 100644 index 0000000..f9690f2 --- /dev/null +++ b/sidecar-dependent-app/app_server.rb @@ -0,0 +1,23 @@ +ENV['RACK_ENV'] ||= 'development' + +require 'rubygems' +require 'sinatra/base' +require 'json' +require 'typhoeus' + +Bundler.require :default, ENV['RACK_ENV'].to_sym + +class AppServer < Sinatra::Base + get '/' do + "Hi, I'm an app with a sidecar!" + end + + get '/config' do + puts "Sending a request to the config-server sidecar at localhost:#{ENV['CONFIG_SERVER_PORT']}/config/" + response = Typhoeus.get("localhost:#{ENV['CONFIG_SERVER_PORT']}/config/") + puts "Received #{response.body} from the config-server sidecar" + response.body + end + + run! if app_file == $0 +end diff --git a/sidecar-dependent-app/config.ru b/sidecar-dependent-app/config.ru new file mode 100644 index 0000000..1fcf8b5 --- /dev/null +++ b/sidecar-dependent-app/config.ru @@ -0,0 +1,4 @@ +$: << File.expand_path("../.", __FILE__) + +require "app_server" +run AppServer diff --git a/sidecar-dependent-app/manifest.yml b/sidecar-dependent-app/manifest.yml new file mode 100644 index 0000000..9a8a224 --- /dev/null +++ b/sidecar-dependent-app/manifest.yml @@ -0,0 +1,13 @@ +applications: +- name: sidecar-dependent-app + disk_quota: 1G + instances: 1 + memory: 256M + env: + CONFIG_SERVER_PORT: 8082 + stack: cflinuxfs3 + sidecars: + - name: config-server + process_types: + - web + command: './config-server'