Skip to content

Commit

Permalink
Merge pull request #73 from rusenask/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
rusenask committed Jul 31, 2017
2 parents 1da1d1b + c3d902d commit 69d9bbb
Show file tree
Hide file tree
Showing 14 changed files with 142 additions and 127 deletions.
1 change: 0 additions & 1 deletion bot/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ func (b *Bot) handleMessage(event *slack.MessageEvent) {

// All messages past this point are directed to @gopher itself
if !b.isBotMessage(event, eventText) {
log.Info("not a bot message")
return
}

Expand Down
14 changes: 1 addition & 13 deletions provider/helm/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
log "github.com/Sirupsen/logrus"
)

// ErrKeelConfigNotFound - default error when keel configuration for chart is not defined
var ErrKeelConfigNotFound = errors.New("keel configuration not found")

// getImages - get images from chart values
Expand Down Expand Up @@ -44,19 +45,6 @@ func getImages(vals chartutil.Values) ([]*types.TrackedImage, error) {
Trigger: keelCfg.Trigger,
}

if imageDetails.ImagePullSecretPath != "" {
secretName, err := getValueAsString(vals, imageDetails.ImagePullSecretPath)
if err != nil {
log.WithFields(log.Fields{
"error": err,
"repository_name": imageDetails.RepositoryPath,
"repository_tag": imageDetails.TagPath,
}).Warn("provider.helm: image pull secret was defined but failed to get it from values.yaml")
} else {
trackedImage.Secrets = []string{secretName}
}
}

images = append(images, trackedImage)
}

Expand Down
74 changes: 0 additions & 74 deletions provider/helm/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,57 +27,10 @@ keel:
`

var chartValuesBSecret = `
---
image:
imagePullSecret: muchsecrecy
repository: gcr.io/v2-namespace/hello-world
tag: "1.1.0"
keel:
images:
-
imagePullSecret: image.imagePullSecret
repository: image.repository
tag: image.tag
policy: all
trigger: poll
name: "al Rashid"
where:
city: Basrah
title: caliph`

var chartValuesBSecretNoPath = `
---
image:
repository: gcr.io/v2-namespace/hello-world
tag: "1.1.0"
keel:
images:
-
imagePullSecret: image.imagePullSecret
repository: image.repository
tag: image.tag
policy: all
trigger: poll
name: "al Rashid"
where:
city: Basrah
title: caliph`

func Test_getImages(t *testing.T) {
vals, _ := chartutil.ReadValues([]byte(chartValuesA))
img, _ := image.Parse("gcr.io/v2-namespace/hello-world:1.1.0")

valsSecret, err := chartutil.ReadValues([]byte(chartValuesBSecret))
if err != nil {
t.Fatalf("failed to parse chartValuesBSecret")
}

valsSecretNoPath, err := chartutil.ReadValues([]byte(chartValuesBSecretNoPath))
if err != nil {
t.Fatalf("failed to parse chartValuesBSecretNoPath")
}

type args struct {
vals chartutil.Values
}
Expand All @@ -100,33 +53,6 @@ func Test_getImages(t *testing.T) {
},
wantErr: false,
},
{
name: "hello-world image with secrets",
args: args{
vals: valsSecret,
},
want: []*types.TrackedImage{
&types.TrackedImage{
Image: img,
Trigger: types.TriggerTypePoll,
Secrets: []string{"muchsecrecy"},
},
},
wantErr: false,
},
{
name: "hello-world image with secret but no actual value",
args: args{
vals: valsSecretNoPath,
},
want: []*types.TrackedImage{
&types.TrackedImage{
Image: img,
Trigger: types.TriggerTypePoll,
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
11 changes: 8 additions & 3 deletions provider/helm/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,8 @@ type KeelChartConfig struct {

// ImageDetails - image details
type ImageDetails struct {
RepositoryPath string `json:"repository"`
TagPath string `json:"tag"`
ImagePullSecretPath string `json:"imagePullSecret"`
RepositoryPath string `json:"repository"`
TagPath string `json:"tag"`
}

// Provider - helm provider, responsible for managing release updates
Expand Down Expand Up @@ -150,6 +149,8 @@ func (p *Provider) TrackedImages() ([]*types.TrackedImage, error) {
if cfg.PollSchedule == "" {
cfg.PollSchedule = types.KeelPollDefaultSchedule
}
// used to check pod secrets
selector := fmt.Sprintf("app=%s,release=%s", release.Chart.Metadata.Name, release.Name)

releaseImages, err := getImages(vals)
if err != nil {
Expand All @@ -162,6 +163,9 @@ func (p *Provider) TrackedImages() ([]*types.TrackedImage, error) {
}

for _, img := range releaseImages {
img.Meta = map[string]string{
"selector": selector,
}
img.Namespace = release.Namespace
img.Provider = ProviderName
trackedImages = append(trackedImages, img)
Expand Down Expand Up @@ -235,6 +239,7 @@ func (p *Provider) createUpdatePlans(event *types.Event) ([]*UpdatePlan, error)

log.WithFields(log.Fields{
"error": err,
"tag": event.Repository.Tag,
}).Error("provider.helm: failed to parse version")
continue
}
Expand Down
12 changes: 6 additions & 6 deletions provider/helm/helm_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package helm

import (
"fmt"
"reflect"
"testing"

Expand Down Expand Up @@ -90,7 +89,8 @@ keel:
&hapi_release5.Release{
Name: "release-1",
Chart: &chart.Chart{
Values: &chart.Config{Raw: chartVals},
Values: &chart.Config{Raw: chartVals},
Metadata: &chart.Metadata{Name: "app-x"},
},
Config: &chart.Config{Raw: ""},
},
Expand All @@ -117,8 +117,6 @@ keel:
t.Errorf("failed to get image paths: %s", err)
}

fmt.Println(cfg)

if cfg.Policy == types.PolicyTypeAll {
policyFound = true
}
Expand Down Expand Up @@ -159,7 +157,8 @@ keel:
&hapi_release5.Release{
Name: "release-1",
Chart: &chart.Chart{
Values: &chart.Config{Raw: chartVals},
Values: &chart.Config{Raw: chartVals},
Metadata: &chart.Metadata{Name: "app-x"},
},
Config: &chart.Config{Raw: ""},
},
Expand Down Expand Up @@ -206,7 +205,8 @@ keel:
&hapi_release5.Release{
Name: "release-1",
Chart: &chart.Chart{
Values: &chart.Config{Raw: chartVals},
Values: &chart.Config{Raw: chartVals},
Metadata: &chart.Metadata{Name: "app-x"},
},
Config: &chart.Config{Raw: ""},
},
Expand Down
5 changes: 0 additions & 5 deletions provider/helm/unversioned_updates.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package helm

import (
"fmt"

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

Expand Down Expand Up @@ -54,7 +52,6 @@ func checkUnversionedRelease(repo *types.Repository, namespace, name string, cha

// checking for impacted images
for _, imageDetails := range keelCfg.Images {
fmt.Println(imageDetails.TagPath)

imageRef, err := parseImage(vals, &imageDetails)
if err != nil {
Expand All @@ -66,8 +63,6 @@ func checkUnversionedRelease(repo *types.Repository, namespace, name string, cha
continue
}

fmt.Println(imageRef.Repository())

if imageRef.Repository() != eventRepoRef.Repository() {
log.WithFields(log.Fields{
"parsed_image_name": imageRef.Remote(),
Expand Down
5 changes: 0 additions & 5 deletions provider/helm/versioned_updates.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package helm

import (
"fmt"

"github.com/rusenask/keel/types"
"github.com/rusenask/keel/util/image"
"github.com/rusenask/keel/util/version"
Expand Down Expand Up @@ -48,7 +46,6 @@ func checkVersionedRelease(newVersion *types.Version, repo *types.Repository, na
}
// checking for impacted images
for _, imageDetails := range keelCfg.Images {
fmt.Println(imageDetails.TagPath)

imageRef, err := parseImage(vals, &imageDetails)
if err != nil {
Expand All @@ -60,8 +57,6 @@ func checkVersionedRelease(newVersion *types.Version, repo *types.Repository, na
continue
}

fmt.Println(imageRef.Repository())

if imageRef.Repository() != eventRepoRef.Repository() {
log.WithFields(log.Fields{
"parsed_image_name": imageRef.Remote(),
Expand Down
8 changes: 8 additions & 0 deletions provider/kubernetes/implementer.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Implementer interface {
Deployments(namespace string) (*v1beta1.DeploymentList, error)
Update(deployment *v1beta1.Deployment) error
Secret(namespace, name string) (*v1.Secret, error)
Pods(namespace, labelSelector string) (*v1.PodList, error)
}

// KubernetesImplementer - default kubernetes client implementer, uses
Expand Down Expand Up @@ -101,6 +102,13 @@ func (i *KubernetesImplementer) Update(deployment *v1beta1.Deployment) error {
return err
}

// Secret - get secret
func (i *KubernetesImplementer) Secret(namespace, name string) (*v1.Secret, error) {

return i.client.Secrets(namespace).Get(name, meta_v1.GetOptions{})
}

// Pods - get pods
func (i *KubernetesImplementer) Pods(namespace, labelSelector string) (*v1.PodList, error) {
return i.client.Pods(namespace).List(meta_v1.ListOptions{LabelSelector: labelSelector})
}
6 changes: 6 additions & 0 deletions provider/kubernetes/kubernetes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ type fakeImplementer struct {
deployment *v1beta1.Deployment
deploymentList *v1beta1.DeploymentList

podList *v1.PodList

// stores value of an updated deployment
updated *v1beta1.Deployment

Expand Down Expand Up @@ -43,6 +45,10 @@ func (i *fakeImplementer) Secret(namespace, name string) (*v1.Secret, error) {
return i.availableSecret, nil
}

func (i *fakeImplementer) Pods(namespace, labelSelector string) (*v1.PodList, error) {
return i.podList, nil
}

type fakeSender struct {
sentEvent types.EventNotification
}
Expand Down
56 changes: 50 additions & 6 deletions secrets/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"net/url"

"github.com/rusenask/keel/provider/helm"
"github.com/rusenask/keel/provider/kubernetes"
"github.com/rusenask/keel/types"

Expand Down Expand Up @@ -40,12 +41,51 @@ func (g *DefaultGetter) Get(image *types.TrackedImage) (*types.Credentials, erro
return nil, ErrNamespaceNotSpecified
}

if len(image.Secrets) == 0 {
return nil, ErrSecretsNotSpecified
switch image.Provider {
case helm.ProviderName:
// looking up secrets based on selector
secrets, err := g.lookupSecrets(image)
if err != nil {
return nil, err
}

// populating secrets
image.Secrets = secrets
}

return g.getCredentialsFromSecret(image)
}

func (g *DefaultGetter) lookupSecrets(image *types.TrackedImage) ([]string, error) {
secrets := []string{}

selector, ok := image.Meta["selector"]
if !ok {
// nothing
return secrets, nil
}

podList, err := g.kubernetesImplementer.Pods(image.Namespace, selector)
if err != nil {
return secrets, err
}

for _, pod := range podList.Items {
podSecrets := getPodImagePullSecrets(&pod)
secrets = append(secrets, podSecrets...)
}

return secrets, nil
}

func getPodImagePullSecrets(pod *v1.Pod) []string {
var secrets []string
for _, s := range pod.Spec.ImagePullSecrets {
secrets = append(secrets, s.Name)
}
return secrets
}

func (g *DefaultGetter) getCredentialsFromSecret(image *types.TrackedImage) (*types.Credentials, error) {

credentials := &types.Credentials{}
Expand Down Expand Up @@ -112,12 +152,16 @@ func (g *DefaultGetter) getCredentialsFromSecret(image *types.TrackedImage) (*ty
if h == image.Image.Registry() {
credentials.Username = auth.Username
credentials.Password = auth.Password

log.WithFields(log.Fields{
"namespace": image.Namespace,
"provider": image.Provider,
"registry": image.Image.Registry(),
"image": image.Image.Repository(),
}).Info("secrets.defaultGetter: secret looked up successfully")

return credentials, nil
}
log.WithFields(log.Fields{
"registry": registry,
"want": image.Image.Registry(),
}).Info("scanning registries")
}

}
Expand Down
Loading

0 comments on commit 69d9bbb

Please sign in to comment.