pidgin/carrier

Initial import
draft
2019-05-12, Gary Kramlich
d67b5771ee54
Parents
Children a78bd0a5531e
Initial import
  • +3 -0
    .hgignore
  • +14 -0
    Dockerfile
  • +34 -0
    config/config.go
  • +41 -0
    convey.yml
  • +6 -0
    go.mod
  • +11 -0
    go.sum
  • +59 -0
    main.go
  • +53 -0
    server/server.go
  • +14 -0
    server/uptimerobot.go
  • --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/.hgignore Sun May 12 05:00:08 2019 -0500
    @@ -0,0 +1,3 @@
    +syntax: glob
    +carrier
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/Dockerfile Sun May 12 05:00:08 2019 -0500
    @@ -0,0 +1,14 @@
    +FROM golang:stretch as build
    +
    +WORKDIR /app
    +
    +COPY . .
    +
    +RUN CGO_ENABLED=0 GOOS=linux go build -o carrier -a -ldflags '-extldflags "-static" -s' .
    +
    +FROM scratch
    +
    +CMD ["/carrier"]
    +
    +COPY --from=build /app/carrier /carrier
    +
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/config/config.go Sun May 12 05:00:08 2019 -0500
    @@ -0,0 +1,34 @@
    +package config
    +
    +import (
    + "github.com/kelseyhightower/envconfig"
    +)
    +
    +type Config struct {
    + ListenAddr string `envconfig:"LISTEN_ADDR" default:":3333"`
    +
    + UptimeRobotToken string `envconfig:"UPTIME_ROBOT_TOKEN" required:"true"`
    +
    + TwilioAccountSID string `envconfig:"TWILIO_ACCOUNT_SID" required:"true"`
    + TwilioAuthToken string `envconfig:"TWILIO_AUTH_TOKEN" required:"true"`
    +}
    +
    +var (
    + config Config
    + loaded = false
    +)
    +
    +func Get() Config {
    + if loaded {
    + return config
    + }
    +
    + err := envconfig.Process("CARRIER", &config)
    + if err != nil {
    + panic(err)
    + }
    +
    + loaded = true
    +
    + return config
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/convey.yml Sun May 12 05:00:08 2019 -0500
    @@ -0,0 +1,41 @@
    +environment:
    + - REPO=pidgin/carrier
    + - TAG=latest
    + - REGISTRY=docker.io
    + - REGISTRY_USERNAME
    + - REGISTRY_PASSWORD
    +
    +tasks:
    + import:
    + type: docker/import
    + files: .:.
    +
    + build:
    + type: docker/build
    + dockerfile: Dockerfile
    + tag: ${REGISTRY}/${REPO}:${TAG}
    + files: .:.
    +
    + login:
    + type: docker/login
    + username: ${REGISTRY_USERNAME}
    + password: ${REGISTRY_PASSWORD}
    + server: ${REGISTRY}
    +
    + logout:
    + type: docker/logout
    + server: ${REGISTRY}
    +
    + push:
    + type: docker/push
    + images: ${REGISTRY}/${REPO}:${TAG}
    +
    +plans:
    + default:
    + stages:
    + - tasks: [import, build]
    + ci:
    + stages:
    + - tasks: [import, build, login, push]
    + - tasks: [logout]
    + run: always
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/go.mod Sun May 12 05:00:08 2019 -0500
    @@ -0,0 +1,6 @@
    +module bitbucket.org/pidgin/carrier
    +
    +require (
    + github.com/kelseyhightower/envconfig v1.3.0
    + github.com/sirupsen/logrus v1.4.1
    +)
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/go.sum Sun May 12 05:00:08 2019 -0500
    @@ -0,0 +1,11 @@
    +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
    +github.com/kelseyhightower/envconfig v1.3.0 h1:IvRS4f2VcIQy6j4ORGIf9145T/AsUB+oY8LyvN8BXNM=
    +github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
    +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
    +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
    +github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
    +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
    +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
    +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
    +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
    +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/main.go Sun May 12 05:00:08 2019 -0500
    @@ -0,0 +1,59 @@
    +package main
    +
    +import (
    + "os"
    + "os/signal"
    + "syscall"
    +
    + log "github.com/sirupsen/logrus"
    +
    + "bitbucket.org/pidgin/carrier/config"
    + "bitbucket.org/pidgin/carrier/server"
    +)
    +
    +func init() {
    + log.SetOutput(os.Stdout)
    + log.SetLevel(log.DebugLevel)
    +
    + formatter := &log.TextFormatter{
    + FullTimestamp: true,
    + }
    +
    + switch os.Getenv("TERM") {
    + case "win":
    + fallthrough
    + case "dumb":
    + formatter.DisableColors = true
    + }
    +
    + log.SetFormatter(formatter)
    +}
    +
    +func main() {
    + // create a signal channel for catching os signals
    + signalChan := make(chan os.Signal, 1)
    + signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)
    +
    + // create an error channel to catch fatal errors
    + errChan := make(chan error, 1)
    +
    + // create the http sever and run it in a go routine
    + go func() {
    + server := server.NewServer(config.Get().ListenAddr, errChan)
    + defer server.Stop()
    + server.Start()
    + }()
    +
    + for {
    + select {
    + case err := <-errChan:
    + if err != nil {
    + log.Fatalf("error: %s", err)
    + return
    + }
    + case s := <-signalChan:
    + log.Warnf("captured %v, exiting...", s)
    + return
    + }
    + }
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/server/server.go Sun May 12 05:00:08 2019 -0500
    @@ -0,0 +1,53 @@
    +package server
    +
    +import (
    + "net/http"
    +
    + log "github.com/sirupsen/logrus"
    +)
    +
    +type Server struct {
    + server *http.Server
    + errChan chan error
    +}
    +
    +func healthzHandler(w http.ResponseWriter, r *http.Request) {
    + status := http.StatusMethodNotAllowed
    +
    + if r.Method == http.MethodGet {
    + status = http.StatusOK
    + }
    +
    + w.WriteHeader(status)
    +}
    +
    +func httpLogger(handler http.Handler) http.Handler {
    + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    + log.Infof("%s %s %s\n", r.RemoteAddr, r.Method, r.URL)
    + handler.ServeHTTP(w, r)
    + })
    +}
    +
    +func NewServer(addr string, errChan chan error) *Server {
    + mux := http.NewServeMux()
    +
    + mux.HandleFunc("/healthz", healthzHandler)
    + mux.HandleFunc("/uptime-robot", uptimeRobotHandler)
    +
    + return &Server{
    + errChan: errChan,
    + server: &http.Server{
    + Addr: addr,
    + Handler: httpLogger(mux),
    + },
    + }
    +}
    +
    +func (s *Server) Start() {
    + log.Infof("http server started")
    + s.errChan <- s.server.ListenAndServe()
    +}
    +
    +func (s *Server) Stop() {
    + s.server.Close()
    +}
    --- /dev/null Thu Jan 01 00:00:00 1970 +0000
    +++ b/server/uptimerobot.go Sun May 12 05:00:08 2019 -0500
    @@ -0,0 +1,14 @@
    +package server
    +
    +import (
    + "net/http"
    +)
    +
    +// monitorID=*monitorID*&monitorURL=*monitorURL*&monitorFriendlyName=*monitorFriendlyName*&alertType=*alertType*&alertTypeFriendlyName=*alertTypeFriendlyName*&alertDetails=*alertDetails*&alertDuration=*alertDuration*&monitorAlertContacts=*monitorAlertContacts*
    +
    +func uptimeRobotHandler(w http.ResponseWriter, r *http.Request) {
    + if r.Method != http.MethodPost {
    + w.WriteHeader(http.StatusMethodNotAllowed)
    + return
    + }
    +}