help playground
parent
4269d8b14e
commit
8bfc2511a9
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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...)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue