help playground

pull/39/head
Karolis Rusenas 2017-07-14 21:42:20 +01:00
parent 4269d8b14e
commit 8bfc2511a9
3 changed files with 233 additions and 39 deletions

View File

@ -2,57 +2,179 @@ package helm
import (
"fmt"
"os"
"k8s.io/helm/pkg/helm"
helm_env "k8s.io/helm/pkg/helm/environment"
"github.com/rusenask/keel/types"
"github.com/rusenask/keel/util/image"
hapi_chart "k8s.io/helm/pkg/proto/hapi/chart"
rls "k8s.io/helm/pkg/proto/hapi/services"
"k8s.io/helm/pkg/tlsutil"
log "github.com/Sirupsen/logrus"
"k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/helm"
)
var (
tlsCaCertFile string // path to TLS CA certificate file
tlsCertFile string // path to TLS certificate file
tlsKeyFile string // path to TLS key file
tlsVerify bool // enable TLS and verify remote certificates
tlsEnable bool // enable TLS
const ProviderName = "helm"
// kubeContext string
// tillerTunnel *kube.Tunnel
settings helm_env.EnvSettings
)
type Provider struct {
implementer Implementer
func newClient() helm.Interface {
options := []helm.Option{helm.Host(settings.TillerHost)}
events chan *types.Event
stop chan struct{}
}
if tlsVerify || tlsEnable {
tlsopts := tlsutil.Options{KeyFile: tlsKeyFile, CertFile: tlsCertFile, InsecureSkipVerify: true}
if tlsVerify {
tlsopts.CaCertFile = tlsCaCertFile
tlsopts.InsecureSkipVerify = false
func NewProvider(implementer Implementer) *Provider {
return &Provider{
implementer: implementer,
events: make(chan *types.Event, 100),
stop: make(chan struct{}),
}
}
func (p *Provider) GetName() string {
return ProviderName
}
// Submit - submit event to provider
func (p *Provider) Submit(event types.Event) error {
p.events <- &event
return nil
}
// Start - starts kubernetes provider, waits for events
func (p *Provider) Start() error {
return p.startInternal()
}
// Stop - stops kubernetes provider
func (p *Provider) Stop() {
close(p.stop)
}
func (p *Provider) startInternal() error {
for {
select {
case event := <-p.events:
log.WithFields(log.Fields{
"repository": event.Repository.Name,
"tag": event.Repository.Tag,
"registry": event.Repository.Host,
}).Info("provider.helm: processing event")
err := p.processEvent(event)
if err != nil {
log.WithFields(log.Fields{
"error": err,
"image": event.Repository.Name,
"tag": event.Repository.Tag,
}).Error("provider.helm: failed to process event")
}
case <-p.stop:
log.Info("provider.helm: got shutdown signal, stopping...")
return nil
}
tlscfg, err := tlsutil.ClientConfig(tlsopts)
}
}
func (p *Provider) processEvent(event *types.Event) (err error) {
return nil
}
func (p *Provider) getImpactedReleases(event *types.Event) ([]*rls.ListReleasesResponse, error) {
releaseList, err := p.implementer.ListReleases()
if err != nil {
return nil, err
}
for _, release := range releaseList.Releases {
ref, err := parseImage(release.Chart, release.Config)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(2)
log.WithFields(log.Fields{
"error": err,
}).Error("provider.helm: failed to get image name and tag from release")
continue
}
options = append(options, helm.WithTLS(tlscfg))
log.WithFields(log.Fields{
"parsed_image_named": ref.Remote(),
}).Info("provider.helm: checking image")
}
return helm.NewClient(options...)
return nil, nil
}
type HelmImplementer struct {
client helm.Interface
}
// resp, err := u.client.UpdateRelease(
// u.release,
// chartPath,
// helm.UpdateValueOverrides(rawVals),
// helm.UpgradeDryRun(u.dryRun),
// helm.UpgradeRecreate(u.recreate),
// helm.UpgradeForce(u.force),
// helm.UpgradeDisableHooks(u.disableHooks),
// helm.UpgradeTimeout(u.timeout),
// helm.ResetValues(u.resetValues),
// helm.ReuseValues(u.reuseValues),
// helm.UpgradeWait(u.wait))
// if err != nil {
// return fmt.Errorf("UPGRADE FAILED: %v", prettyError(err))
// }
func NewHelmImplementer() *HelmImplementer {
client := newClient()
func updateHelmRelease(implementer Implementer, releaseName string, chart *hapi_chart.Chart, rawVals string) error {
return &HelmImplementer{
client: client,
resp, err := implementer.UpdateReleaseFromChart(releaseName, chart,
helm.UpdateValueOverrides([]byte(rawVals)),
helm.UpgradeDryRun(false),
helm.UpgradeRecreate(false),
helm.UpgradeForce(true),
helm.UpgradeDisableHooks(false),
helm.UpgradeTimeout(30),
helm.ResetValues(false),
helm.ReuseValues(true),
helm.UpgradeWait(true))
if err != nil {
return err
}
log.WithFields(log.Fields{
"version": resp.Release.Version,
"release": releaseName,
}).Info("provider.helm: release updated")
return nil
}
func (i *HelmImplementer) ListReleases(opts ...helm.ReleaseListOption) (*rls.ListReleasesResponse, error) {
return i.client.ListReleases(opts...)
func parseImage(chart *hapi_chart.Chart, config *hapi_chart.Config) (*image.Reference, error) {
vals, err := chartutil.ReadValues([]byte(config.Raw))
if err != nil {
return nil, err
}
log.Info(config.Raw)
imageName, err := vals.PathValue("image.repository")
if err != nil {
return nil, err
}
imageTag, err := vals.PathValue("image.tag")
if err != nil {
return nil, fmt.Errorf("failed to get image tag: %s", err)
}
imageNameStr, ok := imageName.(string)
if !ok {
return nil, fmt.Errorf("failed to convert image name ref to string")
}
imageTagStr, ok := imageTag.(string)
if !ok {
return nil, fmt.Errorf("failed to convert image tag ref to string")
}
if imageTagStr != "" {
return image.Parse(imageNameStr + ":" + imageTagStr)
}
return image.Parse(imageNameStr)
}

View File

@ -1,17 +1,52 @@
package helm
import (
"fmt"
"testing"
)
func TestImplementerList(t *testing.T) {
imp := NewHelmImplementer()
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)
}
if releases.Count == 0 {
t.Errorf("why no releases? ")
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 TestUpdateRelease(t *testing.T) {
imp := NewHelmImplementer("192.168.99.100:30083")
releases, err := imp.ListReleases()
if err != nil {
t.Fatalf("unexpected error: %s", err)
}
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())
err = updateHelmRelease(imp, release.Name, release.Chart, "image.tag=0.0.11")
if err != nil {
t.Errorf("failed to update release, error: %s", err)
}
}
}

View File

@ -1 +1,38 @@
package helm
import (
"k8s.io/helm/pkg/helm"
"k8s.io/helm/pkg/proto/hapi/chart"
rls "k8s.io/helm/pkg/proto/hapi/services"
)
var (
TillerAddress = "tiller-deploy:44134"
)
type Implementer interface {
ListReleases(opts ...helm.ReleaseListOption) (*rls.ListReleasesResponse, error)
UpdateReleaseFromChart(rlsName string, chart *chart.Chart, opts ...helm.UpdateOption) (*rls.UpdateReleaseResponse, error)
}
type HelmImplementer struct {
client helm.Interface
}
func NewHelmImplementer(address string) *HelmImplementer {
if address == "" {
address = TillerAddress
}
return &HelmImplementer{
client: helm.NewClient(helm.Host(address)),
}
}
func (i *HelmImplementer) ListReleases(opts ...helm.ReleaseListOption) (*rls.ListReleasesResponse, error) {
return i.client.ListReleases(opts...)
}
func (i *HelmImplementer) UpdateReleaseFromChart(rlsName string, chart *chart.Chart, opts ...helm.UpdateOption) (*rls.UpdateReleaseResponse, error) {
return i.client.UpdateReleaseFromChart(rlsName, chart, opts...)
}