1
0
Fork 0

add example app code

trunk
Thomas 2 years ago
parent b8173f110b
commit 3bdb4657ff

3
.gitignore vendored

@ -0,0 +1,3 @@
infra/.terraform*
infra/terraform-gcp-service-account.json
infra/terraform.tfstate*

@ -0,0 +1,20 @@
#!/bin/bash
KUBE_FEATURE_BRANCHES=`kubectl get po -n ${APP_NAME} -l "app.kubernetes.io/name=${APP_NAME}" -o jsonpath="{.items[*].metadata.labels['app\.kubernetes\.io/instance']}"`
GIT_BRANCHES=`git fetch origin && git branch --list --remote | sed 's/ origin\///g'`
for kube_branch in $KUBE_FEATURE_BRANCHES; do
echo "Checking branch ${kube_branch}"
git_branch_still_exists=false
for git_branch in $GIT_BRANCHES; do
if [ "${git_branch}" == "feature/${kube_branch}" ]; then
git_branch_still_exists=true
echo "Git branch ${git_branch} still exists, instance ${kube_branch} will not be deleted."
fi
done
if [ "${git_branch_still_exists}" = false ]; then
echo "Git branch corresponding to instance ${kube_branch} has been deleted, deleting instance..."
kubectl delete all,ingressroute,pvc,pv -n ${APP_NAME} -l app.kubernetes.io/instance=${kube_branch}
fi
done

@ -0,0 +1,72 @@
---
apiVersion: v1
kind: Service
metadata:
namespace: ${APP_NAME}
name: ${APP_NAME}-${INSTANCE_NAME}
labels:
app.kubernetes.io/name: ${APP_NAME}
app.kubernetes.io/instance: ${INSTANCE_NAME}
spec:
selector:
app.kubernetes.io/name: ${APP_NAME}
app.kubernetes.io/instance: ${INSTANCE_NAME}
ports:
- protocol: TCP
name: http
port: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: ${APP_NAME}
name: ${APP_NAME}-${INSTANCE_NAME}
labels:
app.kubernetes.io/name: ${APP_NAME}
app.kubernetes.io/instance: ${INSTANCE_NAME}
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ${APP_NAME}
app.kubernetes.io/instance: ${INSTANCE_NAME}
template:
metadata:
labels:
app.kubernetes.io/name: ${APP_NAME}
app.kubernetes.io/instance: ${INSTANCE_NAME}
spec:
terminationGracePeriodSeconds: 20
containers:
- name: ${APP_NAME}
image: ${IMAGE}
imagePullPolicy: "Always"
ports:
- name: http
containerPort: 8080
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: ${APP_NAME}
name: ${APP_NAME}-${INSTANCE_NAME}
labels:
app.kubernetes.io/name: ${APP_NAME}
app.kubernetes.io/instance: ${INSTANCE_NAME}
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
entryPoints:
- https
routes:
- match: Host(`${INSTANCE_NAME}-${APP_NAME}.${APP_DOMAIN}`)
kind: Rule
services:
- namespace: ${APP_NAME}
name: ${APP_NAME}-${INSTANCE_NAME}
port: 8080
tls:
certResolver: letsencrypt
domains:
- main: "*.${APP_DOMAIN}"

@ -0,0 +1,12 @@
#!/bin/bash +x
BASTION_STATE=`gcloud compute instances describe $GCP_KUBE_CLUSTER-bastion --zone $GCP_REGION-a --format=json | jq ".status"`
TERMINATED_STATE="\"TERMINATED\""
if [[ $BASTION_STATE == $TERMINATED_STATE ]]; then
echo "Start bastion"
gcloud compute instances start $GCP_KUBE_CLUSTER-bastion --zone $GCP_REGION-a
sleep 10
else
echo "Bastion started already"
fi

@ -0,0 +1,142 @@
kind: pipeline
type: docker
name: default
environment:
APP_NAME: example-app
GCP_PROJECT: <GCP_PROJECT_ID>
GCP_REGISTRY: <GCP_REGISTRY_URL>
GCP_REGION: <GCP_REGION>
GCP_KUBE_CLUSTER: <GCP_GKE_CLUSTER_NAME>
GCP_DOMAIN: <GCP_DOMAIN_NAME>
steps:
- name: google authentication & bastion
image: google/cloud-sdk
environment:
GCP_CREDENTIALS:
from_secret: gcp-credentials
commands:
- mkdir .credentials
- echo -n "$GCP_CREDENTIALS" > .credentials/gcp-key.json
- gcloud auth activate-service-account --key-file .credentials/gcp-key.json
- gcloud --quiet config set project $GCP_PROJECT
- gcloud config set compute/region $GCP_REGION
- gcloud --quiet container clusters get-credentials $GCP_KUBE_CLUSTER
- apt-get install -y jq
- bash .drone-kube/start_bastion.sh
when:
branch:
- feature/*
- fix/*
- refactor/*
- intg/*
- trunk
event:
- push
- name: build image
image: docker:dind
volumes:
- name: dockersock
path: /var/run/docker.sock
environment:
DOCKER_HOST: unix:///var/run/docker.sock
commands:
- export VERSION=$(echo $DRONE_BRANCH | sed "s/\\//-/g"):latest
- export VERSION_SHA=$(echo $DRONE_BRANCH | sed "s/\\//-/g"):$DRONE_COMMIT_SHA
- docker build . -t $GCP_REGISTRY/$APP_NAME/$VERSION
- docker tag $GCP_REGISTRY/$APP_NAME/$VERSION $GCP_REGISTRY/$APP_NAME/$VERSION_SHA
when:
branch:
- feature/*
- fix/*
- refactor/*
- intg/*
- trunk
event:
- push
- name: push to GCP Artifact registry
image: google/cloud-sdk
volumes:
- name: dockersock
path: /var/run/docker.sock
environment:
DOCKER_HOST: unix:///var/run/docker.sock
commands:
- gcloud auth activate-service-account --key-file .credentials/gcp-key.json
- gcloud auth print-access-token | docker login -u oauth2accesstoken --password-stdin https://$GCP_REGION-docker.pkg.dev
- export VERSION=$(echo $DRONE_BRANCH | sed "s/\\//-/g"):latest
- export VERSION_SHA=$(echo $DRONE_BRANCH | sed "s/\\//-/g"):$DRONE_COMMIT_SHA
- docker push $GCP_REGISTRY/$APP_NAME/$VERSION
- docker push $GCP_REGISTRY/$APP_NAME/$VERSION_SHA
when:
branch:
- feature/*
- fix/*
- refactor/*
- intg/*
- trunk
event:
- push
- name: deploy review to gke cluster
image: google/cloud-sdk
commands:
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- apt-get update && apt-get install gettext-base -y
- gcloud auth activate-service-account --key-file .credentials/gcp-key.json
- gcloud config set project $GCP_PROJECT
- gcloud container clusters get-credentials $GCP_KUBE_CLUSTER --region=$GCP_REGION
- gcloud compute ssh bob@$GCP_KUBE_CLUSTER-bastion --zone $GCP_REGION-a -- -4 -L8888:127.0.0.1:8888 -fN -f /dev/null
- export INSTANCE_NAME=$(echo $DRONE_BRANCH | sed "s/\\//-/g" | sed "s/feature-//g" | sed "s/^fix-//g" | sed "s/^refactor-//g" | sed "s/^intg-//g")
- export IMAGE=$GCP_REGISTRY/$APP_NAME/feature-$INSTANCE_NAME:$DRONE_COMMIT_SHA
- export HTTPS_PROXY=127.0.0.1:8888
- echo $IMAGE
- kubectl create namespace $APP_NAME || echo "Namespace $APP_NAME exists"
- envsubst < .drone-kube/deployment.yml > deployment.yml
- kubectl apply -f deployment.yml
- echo "The application is available at https://$INSTANCE_NAME-$APP_NAME.$GCP_DOMAIN"
when:
branch:
- feature/*
- fix/*
- refactor/*
- intg/*
event: push
- name: destroy review app in gke cluster
image: google/cloud-sdk
commands:
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- apt-get update && apt-get install gettext-base -y
- gcloud config set project $GCP_PROJECT
- gcloud auth activate-service-account --key-file .credentials/gcp-key.json
- gcloud container clusters get-credentials $GCP_KUBE_CLUSTER --region=$GCP_REGION
- gcloud compute ssh bob@$GCP_KUBE_CLUSTER-bastion --zone $GCP_REGION-a -- -4 -L8888:127.0.0.1:8888 -fN -f /dev/null
- export HTTPS_PROXY=127.0.0.1:8888
- bash .drone-kube/cleanup.sh
when:
branch:
- trunk
event:
- push
volumes:
- name: cache
host:
path: /tmp/drone/cache/bundle
- name: cache-deploy
host:
path: /tmp/drone/cache-deploy/bundle
- name: dockersock
host:
path: /var/run/docker.sock
---
kind: secret
name: gcp-credentials
data: <GCP_ENCRYPTED_CREDENTIALS>

@ -0,0 +1,32 @@
FROM ruby:2.7.5-slim
RUN apt-get update \
&& apt-get install -y \
build-essential \
libffi-dev \
libgdbm-dev \
libncurses5-dev \
libreadline-dev \
libssl-dev \
libyaml-dev \
zlib1g-dev \
curl \
libyaml-0-2 \
libxml2-dev \
libxslt-dev \
libpq-dev
# Set environment variables.
ENV HOME /var/app
ENV RACK_ENV production
# Define working directory.
ADD . /var/app
RUN bundle config set deployment 'true' \
&& bundle config set without 'development test'
RUN cd /var/app; bundle install
WORKDIR /var/app
EXPOSE 8080
CMD ["/bin/sh", "/var/app/bin/http"]

@ -0,0 +1,7 @@
source 'https://rubygems.org'
gem 'sinatra'
gem 'sinatra-contrib'
gem 'haml'
gem 'puma'
gem 'sidekiq'
gem 'pg'

@ -0,0 +1,53 @@
GEM
remote: https://rubygems.org/
specs:
backports (3.21.0)
connection_pool (2.2.2)
haml (5.1.2)
temple (>= 0.8.0)
tilt
multi_json (1.15.0)
mustermann (1.1.1)
ruby2_keywords (~> 0.0.1)
nio4r (2.5.2)
pg (1.2.3)
puma (4.3.5)
nio4r (~> 2.0)
rack (2.2.2)
rack-protection (2.0.8.1)
rack
redis (4.1.4)
ruby2_keywords (0.0.2)
sidekiq (6.0.7)
connection_pool (>= 2.2.2)
rack (~> 2.0)
rack-protection (>= 2.0.0)
redis (>= 4.1.0)
sinatra (2.0.8.1)
mustermann (~> 1.0)
rack (~> 2.0)
rack-protection (= 2.0.8.1)
tilt (~> 2.0)
sinatra-contrib (2.0.8.1)
backports (>= 2.8.2)
multi_json
mustermann (~> 1.0)
rack-protection (= 2.0.8.1)
sinatra (= 2.0.8.1)
tilt (~> 2.0)
temple (0.8.2)
tilt (2.0.10)
PLATFORMS
ruby
DEPENDENCIES
haml
pg
puma
sidekiq
sinatra
sinatra-contrib
BUNDLED WITH
2.1.4

@ -0,0 +1,7 @@
# README
[![Build Status](https://git2.imfiny.com/api/badges/OpenSource/sinatra_hello/status.svg)](https://git2.imfiny.com/OpenSource/sinatra_hello)
A simple, hello world ruby (sinatra) application.
You can also find it on [Docker hub](https://hub.docker.com/repository/docker/mcansky/sinatra_hello).

@ -0,0 +1,3 @@
#!/bin/sh
echo "the port is : ${PORT}"
bundle exec puma -t 5:5 -p ${PORT:-8080} -e ${RACK_ENV:-development}

@ -0,0 +1,2 @@
require './hello'
run Rack::URLMap.new('/' => SimpleApp)

@ -0,0 +1,85 @@
require 'sinatra'
require 'sinatra/custom_logger'
require 'logger'
require 'sidekiq'
require 'redis'
require 'sidekiq/api'
require 'haml'
require 'pg'
# postgres://postgres:testpassword@pg-${APP_NAME}-${INSTANCE_NAME}/example?sslmode=disable
module Db
class Client
def initialize
db_url = ENV['DATABASE_URL'].gsub('postgres://', '')
auth, host_db = db_url.split('@')
@user, @password = auth.split(':')
@host, db = host_db.split('/')
@db = db.split('?')[0]
end
def create_db
conn.exec("CREATE DATABASE #{@db};")
end
def create_table
conn(@db).exec("CREATE TABLE entries (
did SERIAL,
name varchar(40) NOT NULL check (name <> '')
);")
end
def select_all
conn(@db).exec("SELECT * from entries;")
end
def insert_value
conn(@db).exec("INSERT INTO entries (name) VALUES
('bob'), ('mary')
;")
end
private
def conn(db = nil)
if db
@conn ||= ::PG.connect(user: @user, password: @password, host: @host, dbname: db)
else
@conn ||= ::PG.connect(user: @user, password: @password, host: @host)
end
end
end
end
class SimpleApp < Sinatra::Base
set :logger, Logger.new(STDOUT)
get '/' do
haml "%h3 Hello Cat!"
end
get '/db' do
db_url = ENV['DATABASE_URL']
auth, host_db = db_url.split('@')
@user, @password = auth.split(':')
@host, db = host_db.split('/')
@db = db.split('?')[0]
client = Db::Client.new
begin
client.create_db
rescue PG::DuplicateDatabase
end
client.create_table
haml "%h2 Db created"
end
get '/all' do
client = Db::Client.new
client.insert_value
values = client.select_all
haml :all, locals: { data: values }
end
end
Loading…
Cancel
Save