Skip to content

Commit

Permalink
Merge pull request #8 from ckaznocha/multiple-response-codes
Browse files Browse the repository at this point in the history
Multiple response codes
  • Loading branch information
Jeff DeCola committed Sep 25, 2016
2 parents 1be5080 + 82f2cc2 commit 4233ab8
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 79 deletions.
47 changes: 47 additions & 0 deletions cmd/marathon-resource/actions/actions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package actions

//Params holds the values supported in by the concourse `params` array
type Params struct {
AppJSON string `json:"app_json"`
Replacements []Metadata `json:"replacements"`
}

//AuthCreds will be used for HTTP basic auth
type AuthCreds struct {
UserName string `json:"user_name"`
Password string `json:"password"`
}

//Source holds the values supported in by the concourse `source` array
type Source struct {
AppID string `json:"app_id"`
URI string `json:"uri"`
BasicAuth *AuthCreds `json:"basic_auth"`
}

//Version maps to a concousre version
type Version struct {
Ref string `json:"ref"`
}

//InputJSON is what all concourse actions will pass to us
type InputJSON struct {
Params Params `json:"params"`
Source Source `json:"source"`
Version Version `json:"version"`
}

//CheckOutput is what concourse expects as the result of a `check`
type CheckOutput []Version

//Metadata holds a concourse metadata entry
type Metadata struct {
Name string `json:"name"`
Value string `json:"value"`
}

//IOOutput is the return concourse expects from an `in` or and `out`
type IOOutput struct {
Version Version `json:"version"`
Metadata []Metadata `json:"metadata"`
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
package main
package actions

import (
"errors"
"sort"
"time"
)

type dates []time.Time
//Dates is sa sortable slice of times
type Dates []time.Time

func (d dates) Len() int { return len(d) }
func (d dates) Less(i, j int) bool { return d[i].Before(d[j]) }
func (d dates) Swap(i, j int) { d[i], d[j] = d[j], d[i] }
func (d Dates) Len() int { return len(d) }
func (d Dates) Less(i, j int) bool { return d[i].Before(d[j]) }
func (d Dates) Swap(i, j int) { d[i], d[j] = d[j], d[i] }

func newerTimestamps(
//NewerTimestamps returns all timestamps in a list nwer than a given timestamps
func NewerTimestamps(
timestampStrings []string,
currentTimestampString string,
) ([]string, error) {
var (
currentTimestampIndex int
timestamps = make(dates, len(timestampStrings))
timestamps = make(Dates, len(timestampStrings))
)
for i, v := range timestampStrings {
t, err := time.Parse(time.RFC3339Nano, v)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package actions

import (
"reflect"
Expand Down Expand Up @@ -48,13 +48,13 @@ func Test_maxDateString(t *testing.T) {
},
}
for _, tt := range tests {
got, err := newerTimestamps(tt.args.stringSlice, tt.args.needle)
got, err := NewerTimestamps(tt.args.stringSlice, tt.args.needle)
if (err != nil) != tt.wantErr {
t.Errorf("%q. maxDateString(%v) error = %v, wantErr %v", tt.name, tt.args.stringSlice, err, tt.wantErr)
t.Errorf("%q. NewerTimestamps(%v) error = %v, wantErr %v", tt.name, tt.args.stringSlice, err, tt.wantErr)
continue
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("%q. maxDateString(%v) = %v, want %v", tt.name, tt.args.stringSlice, got, tt.want)
t.Errorf("%q. NewerTimestamps(%v) = %v, want %v", tt.name, tt.args.stringSlice, got, tt.want)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package actions

import (
"bytes"
Expand All @@ -8,7 +8,7 @@ import (
"github.com/aymerick/raymond"
)

func parsePayload(p params, path string) (io.Reader, error) {
func parsePayload(p Params, path string) (io.Reader, error) {
var (
replacments = map[string]string{}
buf = bytes.NewBuffer([]byte{})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package actions

import (
"io/ioutil"
Expand All @@ -8,7 +8,7 @@ import (

func Test_parsePayload(t *testing.T) {
type args struct {
p params
p Params
path string
}
tests := []struct {
Expand All @@ -17,9 +17,9 @@ func Test_parsePayload(t *testing.T) {
want []byte
wantErr bool
}{
{"Reads file with no replacements", args{params{AppJSON: "app.json"}, "fixtures"}, []byte{123, 10, 32, 32, 32, 32, 34, 102, 111, 111, 34, 58, 32, 34, 98, 97, 114, 34, 10, 125, 10}, false},
{"Reads file with replacements", args{params{AppJSON: "app_template.json", Replacements: []metadata{{"foo", "bar"}}}, "fixtures"}, []byte{123, 10, 32, 32, 32, 32, 34, 102, 111, 111, 34, 58, 32, 34, 98, 97, 114, 34, 10, 125, 10}, false},
{"Reads file with bad tmpl", args{params{AppJSON: "app_template_bad.json", Replacements: []metadata{{"foo", "bar"}}}, "fixtures"}, nil, true},
{"Reads file with no replacements", args{Params{AppJSON: "app.json"}, "../fixtures"}, []byte{123, 10, 32, 32, 32, 32, 34, 102, 111, 111, 34, 58, 32, 34, 98, 97, 114, 34, 10, 125, 10}, false},
{"Reads file with replacements", args{Params{AppJSON: "app_template.json", Replacements: []Metadata{{"foo", "bar"}}}, "../fixtures"}, []byte{123, 10, 32, 32, 32, 32, 34, 102, 111, 111, 34, 58, 32, 34, 98, 97, 114, 34, 10, 125, 10}, false},
{"Reads file with bad tmpl", args{Params{AppJSON: "app_template_bad.json", Replacements: []Metadata{{"foo", "bar"}}}, "../fixtures"}, nil, true},
}
for _, tt := range tests {
got, err := parsePayload(tt.args.p, tt.args.path)
Expand Down
38 changes: 3 additions & 35 deletions cmd/marathon-resource/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"

"github.com/Sirupsen/logrus"
"github.com/ckaznocha/marathon-resource/cmd/marathon-resource/actions"
)

const (
Expand All @@ -14,44 +15,11 @@ const (
out = "out"
)

type (
params struct {
AppJSON string `json:"app_json"`
Replacements []metadata `json:"replacements"`
}
authCreds struct {
UserName string `json:"user_name"`
Password string `json:"password"`
}
source struct {
AppID string `json:"app_id"`
URI string `json:"uri"`
BasicAuth *authCreds `json:"basic_auth"`
}
version struct {
Ref string `json:"ref"`
}
inputJSON struct {
Params params `json:"params"`
Source source `json:"source"`
Version version `json:"version"`
}
checkOut []version
metadata struct {
Name string `json:"name"`
Value string `json:"value"`
}
ioOut struct {
Version version `json:"version"`
Metadata []metadata `json:"metadata"`
}
)

var logger = logrus.New()

func main() {
var (
input inputJSON
input actions.InputJSON
decoder = json.NewDecoder(os.Stdin)
/*encoder*/ _ = json.NewEncoder(os.Stdout)
)
Expand All @@ -69,7 +37,7 @@ func main() {
logger.WithError(err).Fatalf("Malformed URI %s", input.Source.URI)
}

// m := newMarathoner(&http.Client{}, uri, source.BasicAuth)
//m := marathon.NewMarathoner(&http.Client{}, uri, source.BasicAuth)

switch os.Args[1] {
case check:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package marathon

import (
"bytes"
Expand All @@ -8,6 +8,7 @@ import (
"net/http"
"net/url"

"github.com/ckaznocha/marathon-resource/cmd/marathon-resource/actions"
gomarathon "github.com/gambol99/go-marathon"
)

Expand All @@ -26,7 +27,7 @@ type (
Do(req *http.Request) (*http.Response, error)
}
//Marathoner is an interface to interact with marathon
marathoner interface {
Marathoner interface {
LatestVersions(appID string, version string) ([]string, error)
GetApp(appID, version string) (gomarathon.Application, error)
UpdateApp(gomarathon.Application) (gomarathon.DeploymentID, error)
Expand All @@ -36,19 +37,20 @@ type (
marathon struct {
client doer
url *url.URL
auth *authCreds
auth *actions.AuthCreds
}
)

func newMarathoner(client doer, uri *url.URL, auth *authCreds) marathoner {
//NewMarathoner returns a new marathoner
func NewMarathoner(client doer, uri *url.URL, auth *actions.AuthCreds) Marathoner {
return &marathon{client: client, url: uri}
}

func (m *marathon) handleReq(
method string,
path string,
payload io.Reader,
wantCode int,
wantCodes []int,
resObj interface{},
) error {
u := *m.url
Expand All @@ -67,9 +69,22 @@ func (m *marathon) handleReq(
}
defer res.Body.Close()

if res.StatusCode != wantCode {
return fmt.Errorf("Expected %d response code but got %d", wantCode, res.StatusCode)
gotWantCode := false
for _, wantCode := range wantCodes {
if res.StatusCode == wantCode {
gotWantCode = true
break
}
}

if !gotWantCode {
return fmt.Errorf(
"Expected one of %v responses code but got %d",
wantCodes,
res.StatusCode,
)
}

if err = json.NewDecoder(res.Body).Decode(resObj); err != nil && err != io.EOF {
return err
}
Expand All @@ -82,12 +97,12 @@ func (m *marathon) LatestVersions(appID, version string) ([]string, error) {
http.MethodGet,
fmt.Sprintf(pathAppVersions, appID),
nil,
http.StatusOK,
[]int{http.StatusOK},
&v,
); err != nil {
return nil, err
}
return newerTimestamps(v.Versions, version)
return actions.NewerTimestamps(v.Versions, version)
}

func (m *marathon) GetApp(appID, version string) (gomarathon.Application, error) {
Expand All @@ -96,7 +111,7 @@ func (m *marathon) GetApp(appID, version string) (gomarathon.Application, error)
http.MethodGet,
fmt.Sprintf(pathAppAtVersion, appID, version),
nil,
http.StatusOK,
[]int{http.StatusOK},
&app,
)
return app, err
Expand All @@ -111,7 +126,7 @@ func (m *marathon) UpdateApp(inApp gomarathon.Application) (gomarathon.Deploymen
http.MethodPut,
fmt.Sprintf(pathApp, inApp.ID),
bytes.NewReader(payload),
http.StatusOK,
[]int{http.StatusOK, http.StatusCreated},
&deployment,
)
return deployment, err
Expand All @@ -125,7 +140,7 @@ func (m *marathon) CheckDeployment(deploymentID string) (bool, error) {
http.MethodGet,
pathDeployments,
nil,
http.StatusOK,
[]int{http.StatusOK},
&deployments,
)

Expand All @@ -142,7 +157,7 @@ func (m *marathon) DeleteDeployment(deploymentID string) error {
http.MethodDelete,
fmt.Sprintf(pathDeployment, deploymentID),
nil,
http.StatusOK,
[]int{http.StatusOK},
nil,
)
}
Loading

0 comments on commit 4233ab8

Please sign in to comment.