Merge branch 'develop' into feature/helm_provider

pull/39/head
Karolis Rusenas 2017-07-11 21:14:05 +01:00
commit f1f6f50100
8 changed files with 270 additions and 26 deletions

View File

@ -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,
})
}

View File

@ -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{

View File

@ -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)
}

View File

@ -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"
)
@ -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(),
}

View File

@ -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
types/level_jsonenums.go Normal file
View File

@ -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
}

View File

@ -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
}

View File

@ -1,3 +1,5 @@
//go:generate jsonenums -type=Notification
//go:generate jsonenums -type=Level
package types
import (
@ -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
@ -161,6 +163,7 @@ const (
PreProviderSubmitNotification Notification = iota
PostProviderSubmitNotification
NotificationPreDeploymentUpdate
NotificationDeploymentUpdate
)
@ -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:
@ -180,7 +185,8 @@ func (n Notification) String() string {
type Level int
const (
LevelInfo Level = iota
LevelDebug Level = iota
LevelInfo
LevelSuccess
LevelWarn
LevelError