Last active
August 3, 2018 14:06
-
-
Save mhrivnak/624e75fce1dadf93ea5c5bb27955a05b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
/* | |
Run this service, then make http requests to the unix socket at path /events/ | |
Each request must: | |
- use method POST | |
- include a JSON body | |
The request body will be printed for human inspection. | |
*/ | |
import ( | |
"encoding/json" | |
"fmt" | |
"io/ioutil" | |
"net" | |
"net/http" | |
"os" | |
"os/signal" | |
"strings" | |
"syscall" | |
"time" | |
) | |
// EventTime - time to unmarshal nano time. | |
type EventTime struct { | |
time.Time | |
} | |
// UnmarshalJSON - override unmarshal json. | |
func (e *EventTime) UnmarshalJSON(b []byte) (err error) { | |
e.Time, err = time.Parse("2006-01-02T15:04:05.999999999", strings.Trim(string(b[:]), "\"\\")) | |
if err != nil { | |
return err | |
} | |
return nil | |
} | |
// JobEvent - event of an ansible run. | |
type JobEvent struct { | |
UUID string `json:"uuid"` | |
Counter int `json:"counter"` | |
StdOut string `json:"stdout"` | |
StartLine int `json:"start_line"` | |
EndLine int `json:"EndLine"` | |
Event string `json:"event"` | |
EventData map[string]interface{} `json:"event_data"` | |
PID int `json:"pid"` | |
Created EventTime `json:"created"` | |
} | |
func main() { | |
if len(os.Args) != 2 { | |
fmt.Fprintln(os.Stderr, "Usage:", os.Args[0], "/path/to/new/socket") | |
os.Exit(1) | |
} | |
path := os.Args[1] | |
listener, err := net.Listen("unix", path) | |
if err != nil { | |
fmt.Println(err.Error()) | |
os.Exit(1) | |
} | |
defer listener.Close() | |
mux := http.NewServeMux() | |
mux.HandleFunc("events/", handleEvents) | |
go http.Serve(listener, mux) | |
// give the listener a chance to close before exiting | |
c := make(chan os.Signal) | |
signal.Notify(c, os.Interrupt, syscall.SIGTERM) | |
<-c | |
} | |
func handleEvents(w http.ResponseWriter, r *http.Request) { | |
if r.URL.Path != "/" { | |
http.NotFound(w, r) | |
return | |
} | |
if r.Method != http.MethodPost { | |
w.WriteHeader(http.StatusMethodNotAllowed) | |
return | |
} | |
ct := r.Header.Get("content-type") | |
if strings.Split(ct, ";")[0] != "application/json" { | |
w.WriteHeader(http.StatusUnsupportedMediaType) | |
w.Write([]byte("The content-type must be \"application/json\"")) | |
return | |
} | |
body, err := ioutil.ReadAll(r.Body) | |
if err != nil { | |
w.WriteHeader(http.StatusInternalServerError) | |
return | |
} | |
fmt.Println(string(body)) | |
event := JobEvent{} | |
err = json.Unmarshal(body, &event) | |
if err != nil { | |
fmt.Println(err.Error()) | |
w.WriteHeader(http.StatusBadRequest) | |
w.Write([]byte("Could not deserialize body as JSON")) | |
return | |
} | |
w.WriteHeader(http.StatusNoContent) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment