Skip to content

Commit

Permalink
Merge pull request #34 from rusenask/feature/fix_pubsub_tag_parsing
Browse files Browse the repository at this point in the history
Feature/fix pubsub tag parsing
  • Loading branch information
rusenask authored Jul 11, 2017
2 parents 8f2aca1 + 3c04063 commit cc36227
Show file tree
Hide file tree
Showing 8 changed files with 270 additions and 26 deletions.
59 changes: 59 additions & 0 deletions extension/notification/webhook/webhook_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package webhook

import (
"io/ioutil"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"

"github.com/rusenask/keel/types"
)

func TestWebhookRequest(t *testing.T) {
currentTime := time.Now()
handler := func(resp http.ResponseWriter, req *http.Request) {
body, err := ioutil.ReadAll(req.Body)
if err != nil {
t.Errorf("failed to parse body: %s", err)
}

bodyStr := string(body)

if !strings.Contains(bodyStr, types.NotificationPreDeploymentUpdate.String()) {
t.Errorf("missing deployment type")
}

if !strings.Contains(bodyStr, "LevelDebug") {
t.Errorf("missing level")
}

if !strings.Contains(bodyStr, "update deployment") {
t.Errorf("missing name")
}
if !strings.Contains(bodyStr, "message here") {
t.Errorf("missing message")
}

t.Log(bodyStr)

}

// create test server with handler
ts := httptest.NewServer(http.HandlerFunc(handler))
defer ts.Close()

s := &sender{
endpoint: ts.URL,
client: &http.Client{},
}

s.Send(types.EventNotification{
Name: "update deployment",
Message: "message here",
CreatedAt: currentTime,
Type: types.NotificationPreDeploymentUpdate,
Level: types.LevelDebug,
})
}
8 changes: 8 additions & 0 deletions provider/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,14 @@ func (p *Provider) updateDeployments(deployments []v1beta1.Deployment) (updated
continue
}

p.sender.Send(types.EventNotification{
Name: "preparing to update deployment",
Message: fmt.Sprintf("Preparing to update deployment %s/%s (%s)", deployment.Namespace, deployment.Name, strings.Join(getImages(&deployment), ", ")),
CreatedAt: time.Now(),
Type: types.NotificationPreDeploymentUpdate,
Level: types.LevelDebug,
})

err = p.implementer.Update(&deployment)
if err != nil {
log.WithFields(log.Fields{
Expand Down
14 changes: 1 addition & 13 deletions trigger/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,5 @@ func (s *TriggerServer) versionHandler(resp http.ResponseWriter, req *http.Reque
}

func (s *TriggerServer) trigger(event types.Event) error {
s.providers.Submit(event)
// for _, p := range s.providers {
// err := p.Submit(event)
// if err != nil {
// log.WithFields(log.Fields{
// "error": err,
// "provider": p.GetName(),
// "trigger": event.TriggerName,
// }).Error("trigger.trigger: got error while submitting event to provider")
// }
// }

return nil
return s.providers.Submit(event)
}
16 changes: 9 additions & 7 deletions trigger/pubsub/pubsub.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (

"github.com/rusenask/keel/provider"
"github.com/rusenask/keel/types"
"github.com/rusenask/keel/util/version"
"github.com/rusenask/keel/util/image"

log "github.com/Sirupsen/logrus"
)
Expand Down Expand Up @@ -160,24 +160,26 @@ func (s *PubsubSubscriber) callback(ctx context.Context, msg *pubsub.Message) {
return
}

imageName, parsedVersion, err := version.GetImageNameAndVersion(decoded.Tag)
ref, err := image.Parse(decoded.Tag)

// imageName, parsedVersion, err := version.GetImageNameAndVersion(decoded.Tag)
if err != nil {
log.WithFields(log.Fields{
"action": decoded.Action,
"tag": decoded.Tag,
"error": err,
}).Warn("trigger.pubsub: failed to get name and version from image")
}).Warn("trigger.pubsub: failed to parse image name")
return
}

// sending event to the providers
log.WithFields(log.Fields{
"action": decoded.Action,
"tag": decoded.Tag,
"version": parsedVersion.String(),
"action": decoded.Action,
"tag": ref.Tag(),
"image_name": ref.Name(),
}).Debug("trigger.pubsub: got message")
event := types.Event{
Repository: types.Repository{Name: imageName, Tag: parsedVersion.String()},
Repository: types.Repository{Name: ref.Repository(), Tag: ref.Tag()},
CreatedAt: time.Now(),
}

Expand Down
51 changes: 51 additions & 0 deletions trigger/pubsub/pubsub_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,54 @@ func TestCallback(t *testing.T) {
}

}
func TestCallbackTagNotSemver(t *testing.T) {

fp := &fakeProvider{}
providers := provider.New([]provider.Provider{fp})
sub := &PubsubSubscriber{disableAck: true, providers: providers}

dataMsg := &Message{Action: "INSERT", Tag: "gcr.io/stemnapp/alpine-website:latest"}
data, _ := json.Marshal(dataMsg)

msg := &pubsub.Message{Data: data}

sub.callback(context.Background(), msg)

if len(fp.submitted) == 0 {
t.Fatalf("no events found in provider")
}
if fp.submitted[0].Repository.Name != "gcr.io/stemnapp/alpine-website" {
t.Errorf("expected repo name %s but got %s", "gcr.io/v2-namespace/hello-world", fp.submitted[0].Repository.Name)
}

if fp.submitted[0].Repository.Tag != "latest" {
t.Errorf("expected repo tag %s but got %s", "latest", fp.submitted[0].Repository.Tag)
}

}

func TestCallbackNoTag(t *testing.T) {

fp := &fakeProvider{}
providers := provider.New([]provider.Provider{fp})
sub := &PubsubSubscriber{disableAck: true, providers: providers}

dataMsg := &Message{Action: "INSERT", Tag: "gcr.io/stemnapp/alpine-website"}
data, _ := json.Marshal(dataMsg)

msg := &pubsub.Message{Data: data}

sub.callback(context.Background(), msg)

if len(fp.submitted) == 0 {
t.Fatalf("no events found in provider")
}
if fp.submitted[0].Repository.Name != "gcr.io/stemnapp/alpine-website" {
t.Errorf("expected repo name %s but got %s", "gcr.io/v2-namespace/hello-world", fp.submitted[0].Repository.Name)
}

if fp.submitted[0].Repository.Tag != "latest" {
t.Errorf("expected repo tag %s but got %s", "latest", fp.submitted[0].Repository.Tag)
}

}
68 changes: 68 additions & 0 deletions types/level_jsonenums.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// generated by jsonenums -type=Level; DO NOT EDIT

package types

import (
"encoding/json"
"fmt"
)

var (
_LevelNameToValue = map[string]Level{
"LevelDebug": LevelDebug,
"LevelInfo": LevelInfo,
"LevelSuccess": LevelSuccess,
"LevelWarn": LevelWarn,
"LevelError": LevelError,
"LevelFatal": LevelFatal,
}

_LevelValueToName = map[Level]string{
LevelDebug: "LevelDebug",
LevelInfo: "LevelInfo",
LevelSuccess: "LevelSuccess",
LevelWarn: "LevelWarn",
LevelError: "LevelError",
LevelFatal: "LevelFatal",
}
)

func init() {
var v Level
if _, ok := interface{}(v).(fmt.Stringer); ok {
_LevelNameToValue = map[string]Level{
interface{}(LevelDebug).(fmt.Stringer).String(): LevelDebug,
interface{}(LevelInfo).(fmt.Stringer).String(): LevelInfo,
interface{}(LevelSuccess).(fmt.Stringer).String(): LevelSuccess,
interface{}(LevelWarn).(fmt.Stringer).String(): LevelWarn,
interface{}(LevelError).(fmt.Stringer).String(): LevelError,
interface{}(LevelFatal).(fmt.Stringer).String(): LevelFatal,
}
}
}

// MarshalJSON is generated so Level satisfies json.Marshaler.
func (r Level) MarshalJSON() ([]byte, error) {
if s, ok := interface{}(r).(fmt.Stringer); ok {
return json.Marshal(s.String())
}
s, ok := _LevelValueToName[r]
if !ok {
return nil, fmt.Errorf("invalid Level: %d", r)
}
return json.Marshal(s)
}

// UnmarshalJSON is generated so Level satisfies json.Unmarshaler.
func (r *Level) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return fmt.Errorf("Level should be a string, got %s", data)
}
v, ok := _LevelNameToValue[s]
if !ok {
return fmt.Errorf("invalid Level %q", s)
}
*r = v
return nil
}
62 changes: 62 additions & 0 deletions types/notification_jsonenums.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// generated by jsonenums -type=Notification; DO NOT EDIT

package types

import (
"encoding/json"
"fmt"
)

var (
_NotificationNameToValue = map[string]Notification{
"PreProviderSubmitNotification": PreProviderSubmitNotification,
"PostProviderSubmitNotification": PostProviderSubmitNotification,
"NotificationPreDeploymentUpdate": NotificationPreDeploymentUpdate,
"NotificationDeploymentUpdate": NotificationDeploymentUpdate,
}

_NotificationValueToName = map[Notification]string{
PreProviderSubmitNotification: "PreProviderSubmitNotification",
PostProviderSubmitNotification: "PostProviderSubmitNotification",
NotificationPreDeploymentUpdate: "NotificationPreDeploymentUpdate",
NotificationDeploymentUpdate: "NotificationDeploymentUpdate",
}
)

func init() {
var v Notification
if _, ok := interface{}(v).(fmt.Stringer); ok {
_NotificationNameToValue = map[string]Notification{
interface{}(PreProviderSubmitNotification).(fmt.Stringer).String(): PreProviderSubmitNotification,
interface{}(PostProviderSubmitNotification).(fmt.Stringer).String(): PostProviderSubmitNotification,
interface{}(NotificationPreDeploymentUpdate).(fmt.Stringer).String(): NotificationPreDeploymentUpdate,
interface{}(NotificationDeploymentUpdate).(fmt.Stringer).String(): NotificationDeploymentUpdate,
}
}
}

// MarshalJSON is generated so Notification satisfies json.Marshaler.
func (r Notification) MarshalJSON() ([]byte, error) {
if s, ok := interface{}(r).(fmt.Stringer); ok {
return json.Marshal(s.String())
}
s, ok := _NotificationValueToName[r]
if !ok {
return nil, fmt.Errorf("invalid Notification: %d", r)
}
return json.Marshal(s)
}

// UnmarshalJSON is generated so Notification satisfies json.Unmarshaler.
func (r *Notification) UnmarshalJSON(data []byte) error {
var s string
if err := json.Unmarshal(data, &s); err != nil {
return fmt.Errorf("Notification should be a string, got %s", data)
}
v, ok := _NotificationNameToValue[s]
if !ok {
return fmt.Errorf("invalid Notification %q", s)
}
*r = v
return nil
}
18 changes: 12 additions & 6 deletions types/types.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:generate jsonenums -type=Notification
//go:generate jsonenums -type=Level
package types

import (
Expand Down Expand Up @@ -146,11 +148,11 @@ const (

// EventNotification notification used for sending
type EventNotification struct {
Name string `json:"name,omitempty"`
Message string `json:"message,omitempty"`
CreatedAt time.Time `json:"createdAt,omitempty"`
Type Notification `json:"type,omitempty"`
Level Level `json:"level,omitempty"`
Name string `json:"name"`
Message string `json:"message"`
CreatedAt time.Time `json:"createdAt"`
Type Notification `json:"type"`
Level Level `json:"level"`
}

// Notification - notification types used by notifier
Expand All @@ -161,6 +163,7 @@ const (
PreProviderSubmitNotification Notification = iota
PostProviderSubmitNotification

NotificationPreDeploymentUpdate
NotificationDeploymentUpdate
)

Expand All @@ -170,6 +173,8 @@ func (n Notification) String() string {
return "pre provider submit"
case PostProviderSubmitNotification:
return "post provider submit"
case NotificationPreDeploymentUpdate:
return "preparing deployment update"
case NotificationDeploymentUpdate:
return "deployment update"
default:
Expand All @@ -180,7 +185,8 @@ func (n Notification) String() string {
type Level int

const (
LevelInfo Level = iota
LevelDebug Level = iota
LevelInfo
LevelSuccess
LevelWarn
LevelError
Expand Down

0 comments on commit cc36227

Please sign in to comment.