mirror of
https://github.com/komodorio/helm-dashboard.git
synced 2026-03-24 11:48:04 +00:00
* Correct path to static dir * Add UI build to makefile * Fix docker build * describe now works * Installed page - revision view - implement url consistent state logic (#403) * refactor * refactor * Fix/responsive and small stylings (#404) * add user defined (#405) * Fix/modal loading button (#406) * add repo to url (#407) * Fix/resources table badges (#408) * filters is now good * fix * test results fix * fix * fixes - error modal, uninstall modals, typees * fixes * bug fix * Helm dashboard v2 (#402) * missing config (#409) * fixes * fixes * Fix/minor responsiveness (#410) * installed release page * default helm icon * guard * refactor * refactor * refactor * key * refactor * fixes * fixes to install * install, add, upgrade, reconfigure now works * latest ver fix * Revision page ui fixes (#411) * link color * Add-repository-link (#412) * empty badge fix * diff fix in install repo * removed console.log * unique key in helathstatus * Cosmetics * Goreleaser upgraded * Another way to fix it * refactor * refactor * chart install fix (#413) * more maintailable * loading, empty space and default namespace * typed * loading diff state is shared * modal height fix * upgrade and add repo connected * add repo suggestion data connected to modal * removed console.log * Chart install fix (#414) * refactor: fix text align uninstall * install modal values big fix * refactor * no changes in diff msg * refactor * sorted versions * typography changes * refactor * refactor * refactor * migrate to sb 7 (#416) * Chart install fix (#415) * Add troubleshoot in komodor (#417) * status style * fix * fixes * delete now reload the page correclty * navigate after add repo fix * Chart install fix (#419) * refactor * refactor * Fix revision age (#420) * refactor * fixed redirects and nav links selected ui (#421) * test modal ui fixes * arrows fix * loading ui (#422) * test dialog now shows errors * fixed rollback diff, redirect after rollback, and debouncing before refetching chart values after changing user defined values (#423) * everything is working besides install chart * install chart should work now * no need for this anymore * styling and naming * improvements * navigation fix * flow fixes * top bar pixel perfect * onClose is optional * ts optional * pixel perfect - clusters, box shadow, error modal * installed page pixel perfect * fixes * need to fix this naming * rollback logic is now good * buttons now similiar to the old app * pass release instead of release date (#426) * repository page style fixes * rounded input * colors like in the old app * more rounding * colors * colors * Cosmetics * drop-shadow cause the dropdown to swallowed * smaller text * fixes (#428) * fixes * describe fix * Fix/lint (#431) * style fixes * fix * describe panel style fixes * diff when repo is available * diff style fixes * fixes to install dialog * specific version should be latests revision * refactor * fixes * fixes * cause troubles * Fixes (#434) * fix * dont fetch if repo not available * tag should not be visible * custom-shdaow fixes * space and shadow like in the old app * refactor (#435) * describe display logic aligned with the old app * style fix * action button style fix * selected revision default logic fix * font fix * style fixes * shutdown button fix * latest revision is now consistent in dev and prod * namespace should be empty on install * fix for current version on install * sorting fix * checkmark should be displayed in options - install * state jump fix * local charts (#436) * Several more fixes (#438) * api docs (#439) * html remove diff2html dep (#437) * Refactor * refactor * Adding storybook for StatusLabel component (#441) * refactor (#442) * we need the css * add prettier (#440) * add prettier * refactor * refactor * Fix reconfigure issue (#443) * first diff fetch fix * missing dep in hooks (#444) * namespace should be from query * triggering diff rerender by listening to loading * missing uservalues * no need for auto retry * we should work against latest revision * refactor * Fix build merge * refactor * refactor * fix * refactor * refactor * age tooltip * prettier fix * fix bug (#447) * Add eslint now (#449) * repo install chart now works as expected * release modal and eslint working good now * we should fetch when return to the initial value * Tailwind theme reorganized (#446) * install release code is like reading a story ! * namespace is not needed for chart values * install repo chart is now like reading a story :) * Fix/filternamesapce (#451) * not needed dep * prettier fix * namespace fix * add debounce (#452) * namespace filter fix * now namespace filter behaves like in the old app * more linter rules and configurations * intial value should be empty * no need to keep filters on cluster change * we don't want to keep tab state between pages * button should be disabled when loading * prettier fix * initial value we're not presented * navigation fix * namespace should always be empty * supporting pre selected namespaces * lint adjustments * Refactor stories fodler (#450) * refactor * refactor * if no user values, use the release values * Adding layer to base style (#456) * Extract duplicate type to types file (#453) * Refactor callApi into direct usage of apiService (#454) * Remove scanners from backend * Give some room for multiple HealthStatus (#458) * refactor: add dynamic api docs (#460) * remove scanners from openapi * was loading forever * fix * Extract defined values from the Modals (#461) * refactor (#462) * fix chart with no repo diff flow * naming fix * crypto UUID not available through https * revert * Update analytics.js with UUID fallback * Cosmetics * repo fetch fix * not need to depened on versions * forgot to push * revert * was causing infinite loop * COsmetics --------- Co-authored-by: Nir Parisian <nir.parisian@gmail.com> Co-authored-by: dav-sap <davidsaper@gmail.com> Co-authored-by: chad11111 <chad1111@tutanota.com> Co-authored-by: IdanSchiller <58664272+IdanSchiller@users.noreply.github.com> Co-authored-by: dav-sap <16819417+dav-sap@users.noreply.github.com> Co-authored-by: rotembm12 <46103618+rotembm12@users.noreply.github.com> Co-authored-by: naorzr <naorzruk@gmail.com> Co-authored-by: Gary Gensler <127234894+chad11111@users.noreply.github.com> Co-authored-by: Tamir Abutbul <1tamir198@gmail.com> Co-authored-by: Nir Parisian <nir2002@users.noreply.github.com>
233 lines
4.9 KiB
Go
233 lines
4.9 KiB
Go
package objects
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"io"
|
|
|
|
"github.com/joomcode/errorx"
|
|
"github.com/pkg/errors"
|
|
log "github.com/sirupsen/logrus"
|
|
"helm.sh/helm/v3/pkg/action"
|
|
"helm.sh/helm/v3/pkg/cli"
|
|
"helm.sh/helm/v3/pkg/release"
|
|
v1 "k8s.io/apimachinery/pkg/apis/testapigroup/v1"
|
|
"k8s.io/apimachinery/pkg/util/yaml"
|
|
"k8s.io/client-go/tools/clientcmd"
|
|
//"sigs.k8s.io/yaml"
|
|
)
|
|
|
|
type DataLayer struct {
|
|
KubeContext string
|
|
StatusInfo *StatusInfo
|
|
Namespaces []string
|
|
Cache *Cache
|
|
|
|
ConfGen HelmConfigGetter
|
|
appPerContext map[string]*Application
|
|
appPerContextMx *sync.Mutex
|
|
devel bool
|
|
LocalCharts []string
|
|
}
|
|
|
|
type StatusInfo struct {
|
|
CurVer string
|
|
LatestVer string
|
|
Analytics bool
|
|
CacheHitRatio float64
|
|
ClusterMode bool
|
|
}
|
|
|
|
func NewDataLayer(ns []string, ver string, cg HelmConfigGetter, devel bool) (*DataLayer, error) {
|
|
if cg == nil {
|
|
return nil, errors.New("HelmConfigGetter can't be nil")
|
|
}
|
|
|
|
return &DataLayer{
|
|
Namespaces: ns,
|
|
Cache: NewCache(),
|
|
StatusInfo: &StatusInfo{
|
|
CurVer: ver,
|
|
Analytics: false,
|
|
},
|
|
|
|
ConfGen: cg,
|
|
appPerContext: map[string]*Application{},
|
|
appPerContextMx: new(sync.Mutex),
|
|
devel: devel,
|
|
}, nil
|
|
}
|
|
|
|
func (d *DataLayer) ListContexts() ([]KubeContext, error) {
|
|
res := []KubeContext{}
|
|
|
|
if d.StatusInfo.ClusterMode {
|
|
return res, nil
|
|
}
|
|
|
|
cfg, err := clientcmd.NewDefaultPathOptions().GetStartingConfig()
|
|
if err != nil {
|
|
return nil, errorx.Decorate(err, "failed to get kubectl config")
|
|
}
|
|
|
|
for name, ctx := range cfg.Contexts {
|
|
res = append(res, KubeContext{
|
|
IsCurrent: cfg.CurrentContext == name,
|
|
Name: name,
|
|
Cluster: ctx.Cluster,
|
|
AuthInfo: ctx.AuthInfo,
|
|
Namespace: ctx.Namespace,
|
|
})
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func (d *DataLayer) GetStatus() *StatusInfo {
|
|
sum := float64(d.Cache.HitCount + d.Cache.MissCount)
|
|
if sum > 0 {
|
|
d.StatusInfo.CacheHitRatio = float64(d.Cache.HitCount) / sum
|
|
} else {
|
|
d.StatusInfo.CacheHitRatio = 0
|
|
}
|
|
return d.StatusInfo
|
|
}
|
|
|
|
type SectionFn = func(*release.Release, bool) (string, error)
|
|
|
|
func ParseManifests(out string) ([]*v1.Carp, error) {
|
|
dec := yaml.NewYAMLOrJSONDecoder(strings.NewReader(out), 4096)
|
|
res := make([]*v1.Carp, 0)
|
|
var tmp interface{}
|
|
for {
|
|
err := dec.Decode(&tmp)
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
|
|
if err != nil {
|
|
return res, errorx.Decorate(err, "failed to parse manifest document #%d", len(res)+1)
|
|
}
|
|
|
|
// k8s libs uses only JSON tags defined, say hello to https://github.com/go-yaml/yaml/issues/424
|
|
// we can juggle it
|
|
jsoned, err := json.Marshal(tmp)
|
|
if err != nil {
|
|
return res, err
|
|
}
|
|
|
|
var doc v1.Carp
|
|
err = json.Unmarshal(jsoned, &doc)
|
|
if err != nil {
|
|
return res, err
|
|
}
|
|
|
|
if doc.Kind == "" {
|
|
log.Warnf("Manifest piece is not k8s resource: %s", jsoned)
|
|
continue
|
|
}
|
|
|
|
res = append(res, &doc)
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
func (d *DataLayer) SetContext(ctx string) error {
|
|
if d.KubeContext != ctx {
|
|
err := d.Cache.Clear()
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to set context")
|
|
}
|
|
}
|
|
|
|
d.KubeContext = ctx
|
|
|
|
return nil
|
|
}
|
|
|
|
func (d *DataLayer) AppForCtx(ctx string) (*Application, error) {
|
|
d.appPerContextMx.Lock()
|
|
defer d.appPerContextMx.Unlock()
|
|
|
|
app, ok := d.appPerContext[ctx]
|
|
if !ok {
|
|
settings := cli.New()
|
|
settings.KubeContext = ctx
|
|
|
|
settings.SetNamespace(d.nsForCtx(ctx))
|
|
|
|
cfgGetter := func(ns string) (*action.Configuration, error) {
|
|
return d.ConfGen(settings, ns)
|
|
}
|
|
|
|
a, err := NewApplication(settings, cfgGetter, d.Namespaces, d.devel)
|
|
if err != nil {
|
|
return nil, errorx.Decorate(err, "Failed to create application for context '%s'", ctx)
|
|
}
|
|
|
|
a.Repositories.LocalCharts = d.LocalCharts
|
|
|
|
app = a
|
|
d.appPerContext[ctx] = app
|
|
}
|
|
return app, nil
|
|
}
|
|
|
|
func (d *DataLayer) nsForCtx(ctx string) string {
|
|
lst, err := d.ListContexts()
|
|
if err != nil {
|
|
log.Debugf("Failed to get contexts for NS lookup: %+v", err)
|
|
}
|
|
for _, c := range lst {
|
|
if c.Name == ctx {
|
|
return c.Namespace
|
|
}
|
|
}
|
|
log.Debugf("Strange: no context found for '%s'", ctx)
|
|
return ""
|
|
}
|
|
|
|
func (d *DataLayer) PeriodicTasks(ctx context.Context) {
|
|
if os.Getenv("HD_NO_AUTOUPDATE") == "" {
|
|
// auto-update repos
|
|
go d.loopUpdateRepos(ctx, 10*time.Minute) // TODO: parameterize interval?
|
|
}
|
|
}
|
|
|
|
func (d *DataLayer) loopUpdateRepos(ctx context.Context, interval time.Duration) {
|
|
ticker := time.NewTicker(interval)
|
|
for {
|
|
app, err := d.AppForCtx("")
|
|
if err != nil {
|
|
log.Warnf("Failed to get app object while in background repo update: %v", err)
|
|
break // no point in retrying
|
|
} else {
|
|
repos, err := app.Repositories.List()
|
|
if err != nil {
|
|
log.Warnf("Failed to get list of repos while in background update: %v", err)
|
|
}
|
|
|
|
for _, repo := range repos {
|
|
err := repo.Update()
|
|
if err != nil {
|
|
log.Warnf("Failed to update repo %s: %v", repo.Name(), err)
|
|
}
|
|
}
|
|
}
|
|
|
|
select {
|
|
case <-ctx.Done():
|
|
ticker.Stop()
|
|
return
|
|
case <-ticker.C:
|
|
continue
|
|
}
|
|
}
|
|
log.Debugf("Update repo loop done.")
|
|
}
|