notifications, testing
parent
72d7fc6092
commit
76bc42c8af
|
@ -2,13 +2,16 @@ package helm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/rusenask/keel/types"
|
"github.com/rusenask/keel/types"
|
||||||
"github.com/rusenask/keel/util/image"
|
"github.com/rusenask/keel/util/image"
|
||||||
"github.com/rusenask/keel/util/version"
|
"github.com/rusenask/keel/util/version"
|
||||||
|
|
||||||
hapi_chart "k8s.io/helm/pkg/proto/hapi/chart"
|
hapi_chart "k8s.io/helm/pkg/proto/hapi/chart"
|
||||||
// rls "k8s.io/helm/pkg/proto/hapi/services"
|
|
||||||
|
"github.com/rusenask/keel/extension/notification"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
|
@ -17,15 +20,15 @@ import (
|
||||||
"k8s.io/helm/pkg/strvals"
|
"k8s.io/helm/pkg/strvals"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Manager - high level interface into helm provider related data used by
|
||||||
|
// triggers
|
||||||
|
type Manager interface {
|
||||||
|
Images() ([]*image.Reference, error)
|
||||||
|
}
|
||||||
|
|
||||||
// ProviderName - helm provider name
|
// ProviderName - helm provider name
|
||||||
const ProviderName = "helm"
|
const ProviderName = "helm"
|
||||||
|
|
||||||
// keel paths
|
|
||||||
const (
|
|
||||||
policyPath = "keel.policy"
|
|
||||||
imagesPath = "keel.images"
|
|
||||||
)
|
|
||||||
|
|
||||||
// UpdatePlan - release update plan
|
// UpdatePlan - release update plan
|
||||||
type UpdatePlan struct {
|
type UpdatePlan struct {
|
||||||
Namespace string
|
Namespace string
|
||||||
|
@ -43,6 +46,7 @@ type UpdatePlan struct {
|
||||||
// policy: all
|
// policy: all
|
||||||
// # trigger type, defaults to events such as pubsub, webhooks
|
// # trigger type, defaults to events such as pubsub, webhooks
|
||||||
// trigger: poll
|
// trigger: poll
|
||||||
|
// pollSchedule: "@every 2m"
|
||||||
// # images to track and update
|
// # images to track and update
|
||||||
// images:
|
// images:
|
||||||
// - repository: image.repository
|
// - repository: image.repository
|
||||||
|
@ -55,9 +59,10 @@ type Root struct {
|
||||||
|
|
||||||
// KeelChartConfig - keel related configuration taken from values.yaml
|
// KeelChartConfig - keel related configuration taken from values.yaml
|
||||||
type KeelChartConfig struct {
|
type KeelChartConfig struct {
|
||||||
Policy types.PolicyType `json:"policy"`
|
Policy types.PolicyType `json:"policy"`
|
||||||
Trigger string `json:"trigger"`
|
Trigger types.TriggerType `json:"trigger"`
|
||||||
Images []ImageDetails `json:"images"`
|
PollSchedule string `json:"pollSchedule"`
|
||||||
|
Images []ImageDetails `json:"images"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageDetails - image details
|
// ImageDetails - image details
|
||||||
|
@ -70,18 +75,23 @@ type ImageDetails struct {
|
||||||
type Provider struct {
|
type Provider struct {
|
||||||
implementer Implementer
|
implementer Implementer
|
||||||
|
|
||||||
|
sender notification.Sender
|
||||||
|
|
||||||
events chan *types.Event
|
events chan *types.Event
|
||||||
stop chan struct{}
|
stop chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewProvider(implementer Implementer) *Provider {
|
// NewProvider - create new Helm provider
|
||||||
|
func NewProvider(implementer Implementer, sender notification.Sender) *Provider {
|
||||||
return &Provider{
|
return &Provider{
|
||||||
implementer: implementer,
|
implementer: implementer,
|
||||||
|
sender: sender,
|
||||||
events: make(chan *types.Event, 100),
|
events: make(chan *types.Event, 100),
|
||||||
stop: make(chan struct{}),
|
stop: make(chan struct{}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetName - get provider name
|
||||||
func (p *Provider) GetName() string {
|
func (p *Provider) GetName() string {
|
||||||
return ProviderName
|
return ProviderName
|
||||||
}
|
}
|
||||||
|
@ -102,8 +112,9 @@ func (p *Provider) Stop() {
|
||||||
close(p.stop)
|
close(p.stop)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) Releases() ([]*types.HelmRelease, error) {
|
// TrackedImages - returns tracked images from all releases that have keel configuration
|
||||||
releases := []*types.HelmRelease{}
|
func (p *Provider) TrackedImages() ([]*types.TrackedImage, error) {
|
||||||
|
var trackedImages []*types.TrackedImage
|
||||||
|
|
||||||
releaseList, err := p.implementer.ListReleases()
|
releaseList, err := p.implementer.ListReleases()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -111,10 +122,53 @@ func (p *Provider) Releases() ([]*types.HelmRelease, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, release := range releaseList.Releases {
|
for _, release := range releaseList.Releases {
|
||||||
|
// getting configuration
|
||||||
|
vals, err := values(release.Chart, release.Config)
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"error": err,
|
||||||
|
"release": release.Name,
|
||||||
|
"namespace": release.Namespace,
|
||||||
|
}).Error("provider.helm: failed to get values.yaml for release")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg, err := getKeelConfig(vals)
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"error": err,
|
||||||
|
"release": release.Name,
|
||||||
|
"namespace": release.Namespace,
|
||||||
|
}).Error("provider.helm: failed to get config for release")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.PollSchedule == "" {
|
||||||
|
cfg.PollSchedule = types.KeelPollDefaultSchedule
|
||||||
|
}
|
||||||
|
|
||||||
|
releaseImages, err := getImages(vals)
|
||||||
|
if err != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"error": err,
|
||||||
|
"release": release.Name,
|
||||||
|
"namespace": release.Namespace,
|
||||||
|
}).Error("provider.helm: failed to get images for release")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, img := range releaseImages {
|
||||||
|
trackedImages = append(trackedImages, &types.TrackedImage{
|
||||||
|
Image: img,
|
||||||
|
PollSchedule: cfg.PollSchedule,
|
||||||
|
Trigger: cfg.Trigger,
|
||||||
|
Provider: ProviderName,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return releases, nil
|
return trackedImages, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) startInternal() error {
|
func (p *Provider) startInternal() error {
|
||||||
|
@ -162,6 +216,22 @@ func (p *Provider) createUpdatePlans(event *types.Event) ([]*UpdatePlan, error)
|
||||||
|
|
||||||
newVersion, err := version.GetVersion(event.Repository.Tag)
|
newVersion, err := version.GetVersion(event.Repository.Tag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
||||||
|
plan, update, errCheck := checkUnversionedRelease(&event.Repository, release.Namespace, release.Name, release.Chart, release.Config)
|
||||||
|
if errCheck != nil {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"error": err,
|
||||||
|
"deployment": release.Name,
|
||||||
|
"namespace": release.Namespace,
|
||||||
|
}).Error("provider.kubernetes: got error while checking unversioned release")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if update {
|
||||||
|
plans = append(plans, plan)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"error": err,
|
"error": err,
|
||||||
}).Error("provider.helm: failed to parse version")
|
}).Error("provider.helm: failed to parse version")
|
||||||
|
@ -187,6 +257,15 @@ func (p *Provider) createUpdatePlans(event *types.Event) ([]*UpdatePlan, error)
|
||||||
|
|
||||||
func (p *Provider) applyPlans(plans []*UpdatePlan) error {
|
func (p *Provider) applyPlans(plans []*UpdatePlan) error {
|
||||||
for _, plan := range plans {
|
for _, plan := range plans {
|
||||||
|
|
||||||
|
p.sender.Send(types.EventNotification{
|
||||||
|
Name: "update release",
|
||||||
|
Message: fmt.Sprintf("Preparing to update release %s/%s (%s)", plan.Namespace, plan.Name, strings.Join(mapToSlice(plan.Values), ", ")),
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
Type: types.NotificationPreReleaseUpdate,
|
||||||
|
Level: types.LevelDebug,
|
||||||
|
})
|
||||||
|
|
||||||
err := updateHelmRelease(p.implementer, plan.Name, plan.Chart, plan.Values)
|
err := updateHelmRelease(p.implementer, plan.Name, plan.Chart, plan.Values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
|
@ -194,8 +273,25 @@ func (p *Provider) applyPlans(plans []*UpdatePlan) error {
|
||||||
"name": plan.Name,
|
"name": plan.Name,
|
||||||
"namespace": plan.Namespace,
|
"namespace": plan.Namespace,
|
||||||
}).Error("provider.helm: failed to apply plan")
|
}).Error("provider.helm: failed to apply plan")
|
||||||
|
|
||||||
|
p.sender.Send(types.EventNotification{
|
||||||
|
Name: "update release",
|
||||||
|
Message: fmt.Sprintf("Release update feailed %s/%s (%s), error: %s", plan.Namespace, plan.Name, strings.Join(mapToSlice(plan.Values), ", "), err),
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
Type: types.NotificationReleaseUpdate,
|
||||||
|
Level: types.LevelError,
|
||||||
|
})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.sender.Send(types.EventNotification{
|
||||||
|
Name: "update release",
|
||||||
|
Message: fmt.Sprintf("Successfully updated release %s/%s (%s)", plan.Namespace, plan.Name, strings.Join(mapToSlice(plan.Values), ", ")),
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
Type: types.NotificationReleaseUpdate,
|
||||||
|
Level: types.LevelSuccess,
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -4,13 +4,57 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
|
|
||||||
|
"github.com/rusenask/keel/extension/notification"
|
||||||
"github.com/rusenask/keel/types"
|
"github.com/rusenask/keel/types"
|
||||||
|
|
||||||
"k8s.io/helm/pkg/chartutil"
|
"k8s.io/helm/pkg/chartutil"
|
||||||
|
"k8s.io/helm/pkg/helm"
|
||||||
|
"k8s.io/helm/pkg/proto/hapi/chart"
|
||||||
|
hapi_release5 "k8s.io/helm/pkg/proto/hapi/release"
|
||||||
|
rls "k8s.io/helm/pkg/proto/hapi/services"
|
||||||
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type fakeSender struct {
|
||||||
|
sentEvent types.EventNotification
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fakeSender) Configure(cfg *notification.Config) (bool, error) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *fakeSender) Send(event types.EventNotification) error {
|
||||||
|
s.sentEvent = event
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type fakeImplementer struct {
|
||||||
|
listReleasesResponse *rls.ListReleasesResponse
|
||||||
|
|
||||||
|
// updated info
|
||||||
|
updatedRlsName string
|
||||||
|
updatedChart *chart.Chart
|
||||||
|
updatedOptions []helm.UpdateOption
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *fakeImplementer) ListReleases(opts ...helm.ReleaseListOption) (*rls.ListReleasesResponse, error) {
|
||||||
|
return i.listReleasesResponse, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *fakeImplementer) UpdateReleaseFromChart(rlsName string, chart *chart.Chart, opts ...helm.UpdateOption) (*rls.UpdateReleaseResponse, error) {
|
||||||
|
i.updatedRlsName = rlsName
|
||||||
|
i.updatedChart = chart
|
||||||
|
i.updatedOptions = opts
|
||||||
|
|
||||||
|
return &rls.UpdateReleaseResponse{
|
||||||
|
Release: &hapi_release5.Release{
|
||||||
|
Version: 2,
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// helper function to generate keel configuration
|
// helper function to generate keel configuration
|
||||||
func testingConfigYaml(cfg *KeelChartConfig) (vals chartutil.Values, err error) {
|
func testingConfigYaml(cfg *KeelChartConfig) (vals chartutil.Values, err error) {
|
||||||
root := &Root{Keel: *cfg}
|
root := &Root{Keel: *cfg}
|
||||||
|
@ -22,30 +66,41 @@ func testingConfigYaml(cfg *KeelChartConfig) (vals chartutil.Values, err error)
|
||||||
return chartutil.ReadValues(bts)
|
return chartutil.ReadValues(bts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestParseImage(t *testing.T) {
|
|
||||||
imp := NewHelmImplementer("192.168.99.100:30083")
|
|
||||||
|
|
||||||
releases, err := imp.ListReleases()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unexpected error: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(releases.Count)
|
|
||||||
|
|
||||||
for _, release := range releases.Releases {
|
|
||||||
ref, err := parseImage(release.Chart, release.Config)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("failed to parse image, error: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(ref.Remote())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGetChartPolicy(t *testing.T) {
|
func TestGetChartPolicy(t *testing.T) {
|
||||||
imp := NewHelmImplementer("192.168.99.100:30083")
|
|
||||||
|
|
||||||
releases, err := imp.ListReleases()
|
chartVals := `
|
||||||
|
name: al Rashid
|
||||||
|
where:
|
||||||
|
city: Basrah
|
||||||
|
title: caliph
|
||||||
|
image:
|
||||||
|
repository: gcr.io/v2-namespace/hello-world
|
||||||
|
tag: 1.1.0
|
||||||
|
|
||||||
|
keel:
|
||||||
|
policy: all
|
||||||
|
trigger: poll
|
||||||
|
images:
|
||||||
|
- repository: image.repository
|
||||||
|
tag: image.tag
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
fakeImpl := &fakeImplementer{
|
||||||
|
listReleasesResponse: &rls.ListReleasesResponse{
|
||||||
|
Releases: []*hapi_release5.Release{
|
||||||
|
&hapi_release5.Release{
|
||||||
|
Name: "release-1",
|
||||||
|
Chart: &chart.Chart{
|
||||||
|
Values: &chart.Config{Raw: chartVals},
|
||||||
|
},
|
||||||
|
Config: &chart.Config{Raw: ""},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
releases, err := fakeImpl.ListReleases()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %s", err)
|
t.Fatalf("unexpected error: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -59,10 +114,6 @@ func TestGetChartPolicy(t *testing.T) {
|
||||||
t.Fatalf("failed to get values: %s", err)
|
t.Fatalf("failed to get values: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// policy, err := getChartPolicy(vals)
|
|
||||||
// if err != nil {
|
|
||||||
// t.Errorf("failed to parse image, error: %s", err)
|
|
||||||
// }
|
|
||||||
cfg, err := getKeelConfig(vals)
|
cfg, err := getKeelConfig(vals)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("failed to get image paths: %s", err)
|
t.Errorf("failed to get image paths: %s", err)
|
||||||
|
@ -79,9 +130,8 @@ func TestGetChartPolicy(t *testing.T) {
|
||||||
t.Errorf("policy not found")
|
t.Errorf("policy not found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetTriggerFromConfig(t *testing.T) {
|
func TestGetTriggerFromConfig(t *testing.T) {
|
||||||
vals, err := testingConfigYaml(&KeelChartConfig{Trigger: "poll"})
|
vals, err := testingConfigYaml(&KeelChartConfig{Trigger: types.TriggerTypePoll})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to load testdata: %s", err)
|
t.Fatalf("Failed to load testdata: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -91,7 +141,7 @@ func TestGetTriggerFromConfig(t *testing.T) {
|
||||||
t.Errorf("failed to get image paths: %s", err)
|
t.Errorf("failed to get image paths: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Trigger != "poll" {
|
if cfg.Trigger != types.TriggerTypePoll {
|
||||||
t.Errorf("invalid trigger: %s", cfg.Trigger)
|
t.Errorf("invalid trigger: %s", cfg.Trigger)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,27 +162,117 @@ func TestGetPolicyFromConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// func TestUpdateRelease(t *testing.T) {
|
func TestGetImagesFromConfig(t *testing.T) {
|
||||||
// imp := NewHelmImplementer("192.168.99.100:30083")
|
vals, err := testingConfigYaml(&KeelChartConfig{Policy: types.PolicyTypeAll, Images: []ImageDetails{
|
||||||
|
ImageDetails{
|
||||||
|
RepositoryPath: "repopath",
|
||||||
|
TagPath: "tagpath",
|
||||||
|
},
|
||||||
|
}})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to load testdata: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
// releases, err := imp.ListReleases()
|
cfg, err := getKeelConfig(vals)
|
||||||
// if err != nil {
|
if err != nil {
|
||||||
// t.Fatalf("unexpected error: %s", err)
|
t.Errorf("failed to get image paths: %s", err)
|
||||||
// }
|
}
|
||||||
|
|
||||||
// for _, release := range releases.Releases {
|
if cfg.Images[0].RepositoryPath != "repopath" {
|
||||||
|
t.Errorf("invalid repo path: %s", cfg.Images[0].RepositoryPath)
|
||||||
|
}
|
||||||
|
|
||||||
// ref, err := parseImage(release.Chart, release.Config)
|
if cfg.Images[0].TagPath != "tagpath" {
|
||||||
// if err != nil {
|
t.Errorf("invalid tag path: %s", cfg.Images[0].TagPath)
|
||||||
// t.Errorf("failed to parse image, error: %s", err)
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// fmt.Println(ref.Remote())
|
func TestUpdateRelease(t *testing.T) {
|
||||||
|
// imp := NewHelmImplementer("192.168.99.100:30083")
|
||||||
|
|
||||||
// err = updateHelmRelease(imp, release.Name, release.Chart, "image.tag=0.0.11")
|
chartVals := `
|
||||||
|
name: al Rashid
|
||||||
|
where:
|
||||||
|
city: Basrah
|
||||||
|
title: caliph
|
||||||
|
image:
|
||||||
|
repository: karolisr/webhook-demo
|
||||||
|
tag: 0.0.10
|
||||||
|
|
||||||
// if err != nil {
|
keel:
|
||||||
// t.Errorf("failed to update release, error: %s", err)
|
policy: all
|
||||||
// }
|
trigger: poll
|
||||||
// }
|
images:
|
||||||
// }
|
- repository: image.repository
|
||||||
|
tag: image.tag
|
||||||
|
|
||||||
|
`
|
||||||
|
myChart := &chart.Chart{
|
||||||
|
Values: &chart.Config{Raw: chartVals},
|
||||||
|
}
|
||||||
|
|
||||||
|
fakeImpl := &fakeImplementer{
|
||||||
|
listReleasesResponse: &rls.ListReleasesResponse{
|
||||||
|
Releases: []*hapi_release5.Release{
|
||||||
|
&hapi_release5.Release{
|
||||||
|
Name: "release-1",
|
||||||
|
Chart: myChart,
|
||||||
|
Config: &chart.Config{Raw: ""},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
provider := NewProvider(fakeImpl, &fakeSender{})
|
||||||
|
|
||||||
|
err := provider.processEvent(&types.Event{
|
||||||
|
Repository: types.Repository{
|
||||||
|
Name: "karolisr/webhook-demo",
|
||||||
|
Tag: "0.0.11",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to process event, error: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// checking updated release
|
||||||
|
if fakeImpl.updatedChart != myChart {
|
||||||
|
t.Errorf("wrong chart updated")
|
||||||
|
}
|
||||||
|
|
||||||
|
if fakeImpl.updatedRlsName != "release-1" {
|
||||||
|
t.Errorf("unexpected release updated: %s", fakeImpl.updatedRlsName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var pollingValues = `
|
||||||
|
name: al Rashid
|
||||||
|
where:
|
||||||
|
city: Basrah
|
||||||
|
title: caliph
|
||||||
|
image:
|
||||||
|
repository: gcr.io/v2-namespace/hello-world
|
||||||
|
tag: 1.1.0
|
||||||
|
|
||||||
|
keel:
|
||||||
|
policy: all
|
||||||
|
trigger: poll
|
||||||
|
pollSchedule: "@every 12m"
|
||||||
|
images:
|
||||||
|
- repository: image.repository
|
||||||
|
tag: image.tag
|
||||||
|
|
||||||
|
`
|
||||||
|
|
||||||
|
func TestGetPollingSchedule(t *testing.T) {
|
||||||
|
vals, _ := chartutil.ReadValues([]byte(pollingValues))
|
||||||
|
|
||||||
|
cfg, err := getKeelConfig(vals)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("failed to get config: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.PollSchedule != "@every 12m" {
|
||||||
|
t.Errorf("unexpected polling schedule: %s", cfg.PollSchedule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue