Skip to content

Commit

Permalink
daemon(status): add shields.io badge endpoint (#655)
Browse files Browse the repository at this point in the history
adds a new URL parameter on `/status`, `badge=true`, that requests the daemon to return a shields.io-compatible payload for generating a badge: see https://shields.io/endpoint

For example:

    ![inertia status](https://my.inertia.instance:4303/status?badge=true)
  • Loading branch information
bobheadxi committed Mar 19, 2020
1 parent c7235d1 commit 55aa5d9
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 1 deletion.
51 changes: 50 additions & 1 deletion daemon/inertiad/daemon/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,61 @@ import (
"github.com/ubclaunchpad/inertia/daemon/inertiad/res"
)

type shieldsIOData struct {
SchemaVersion int `json:"schemaVersion"` // always 1

Label string `json:"label"` // left text
LabelColor string `json:"labelColor"` // left color

Message string `json:"message"` // right text
Color string `json:"color"` // right color

IsError bool `json:"isError"`
}

// statusHandler returns a formatted string about the status of the
// deployment and lists currently active project containers
func (s *Server) statusHandler(w http.ResponseWriter, r *http.Request) {
status, err := s.deployment.GetStatus(s.docker)
status.InertiaVersion = s.version

// badge generator for https://shields.io/endpoint
if r.URL.Query().Get("badge") == "true" {
badge := shieldsIOData{1, "inertia", "blue", "deployed", "green", false}
if err != nil {
badge.Message = "errored"
badge.Color = "red"
badge.IsError = true
render.JSON(w, r, badge)
return
} else if status.BuildContainerActive {
// build in progress
badge.Message = "deploying"
badge.Color = "yellow"
render.JSON(w, r, badge)
return
} else if status.CommitHash == "" {
// no project
badge.Message = "no project"
badge.Color = "lightgrey"
badge.IsError = true
render.JSON(w, r, badge)
return
} else if len(status.Containers) == 0 {
// deployment offline
badge.Message = "project offline"
badge.Color = "grey"
badge.IsError = true
render.JSON(w, r, badge)
return
}

// deployed
render.JSON(w, r, badge)
return
}

// standard responses
if status.CommitHash == "" {
status.Containers = make([]string, 0)
render.Render(w, r, res.MsgOK("status retrieved",
Expand All @@ -23,7 +73,6 @@ func (s *Server) statusHandler(w http.ResponseWriter, r *http.Request) {
render.Render(w, r, res.ErrInternalServer("failed to get status", err))
return
}

render.Render(w, r, res.MsgOK("status retrieved",
"status", status))
}
55 changes: 55 additions & 0 deletions daemon/inertiad/daemon/status_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package daemon

import (
"bytes"
"encoding/json"
"errors"
"io"
"net/http"
"net/http/httptest"
"testing"
Expand All @@ -12,6 +15,14 @@ import (
"github.com/ubclaunchpad/inertia/daemon/inertiad/project/mocks"
)

func readBadge(body io.Reader) (*shieldsIOData, error) {
buf := new(bytes.Buffer)
buf.ReadFrom(body)
bytes := buf.Bytes()
var data shieldsIOData
return &data, json.Unmarshal(bytes, &data)
}

func TestStatusHandlerBuildInProgress(t *testing.T) {
var s = &Server{
deployment: &mocks.FakeDeployer{
Expand All @@ -37,6 +48,17 @@ func TestStatusHandlerBuildInProgress(t *testing.T) {

handler.ServeHTTP(recorder, req)
assert.Equal(t, recorder.Code, http.StatusOK)

// check badge
recorder = httptest.NewRecorder()
req, err = http.NewRequest("GET", "/status?badge=true", nil)
assert.NoError(t, err)
handler.ServeHTTP(recorder, req)
assert.Equal(t, recorder.Code, http.StatusOK)
badge, err := readBadge(recorder.Result().Body)
assert.NoError(t, err)
assert.Equal(t, "deploying", badge.Message)
assert.False(t, badge.IsError)
}

func TestStatusHandlerNoContainers(t *testing.T) {
Expand Down Expand Up @@ -64,6 +86,17 @@ func TestStatusHandlerNoContainers(t *testing.T) {

handler.ServeHTTP(recorder, req)
assert.Equal(t, recorder.Code, http.StatusOK)

// check badge
recorder = httptest.NewRecorder()
req, err = http.NewRequest("GET", "/status?badge=true", nil)
assert.NoError(t, err)
handler.ServeHTTP(recorder, req)
assert.Equal(t, recorder.Code, http.StatusOK)
badge, err := readBadge(recorder.Result().Body)
assert.NoError(t, err)
assert.Equal(t, "project offline", badge.Message)
assert.True(t, badge.IsError)
}

func TestStatusHandlerActiveContainers(t *testing.T) {
Expand Down Expand Up @@ -93,6 +126,17 @@ func TestStatusHandlerActiveContainers(t *testing.T) {
assert.Equal(t, recorder.Code, http.StatusOK)
assert.Contains(t, recorder.Body.String(), "mycontainer_1")
assert.Contains(t, recorder.Body.String(), "yourcontainer_2")

// check badge
recorder = httptest.NewRecorder()
req, err = http.NewRequest("GET", "/status?badge=true", nil)
assert.NoError(t, err)
handler.ServeHTTP(recorder, req)
assert.Equal(t, recorder.Code, http.StatusOK)
badge, err := readBadge(recorder.Result().Body)
assert.NoError(t, err)
assert.Equal(t, "deployed", badge.Message)
assert.False(t, badge.IsError)
}

func TestStatusHandlerStatusError(t *testing.T) {
Expand All @@ -114,4 +158,15 @@ func TestStatusHandlerStatusError(t *testing.T) {

handler.ServeHTTP(recorder, req)
assert.Equal(t, recorder.Code, http.StatusInternalServerError)

// check badge
recorder = httptest.NewRecorder()
req, err = http.NewRequest("GET", "/status?badge=true", nil)
assert.NoError(t, err)
handler.ServeHTTP(recorder, req)
assert.Equal(t, recorder.Code, http.StatusOK)
badge, err := readBadge(recorder.Result().Body)
assert.NoError(t, err)
assert.Equal(t, "errored", badge.Message)
assert.True(t, badge.IsError)
}

0 comments on commit 55aa5d9

Please sign in to comment.