Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #35

Merged
merged 6 commits into from
Jul 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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