diff --git a/.gitignore b/.gitignore index fa6e20af94..b5e7749acf 100644 --- a/.gitignore +++ b/.gitignore @@ -107,3 +107,6 @@ src/frontend/packages/core/src/index.html # Prebuild package stratos-frontend-prebuild.zip + +src/frontend/assets +src/frontend/sass \ No newline at end of file diff --git a/custom-src/frontend/app/custom/custom-routing.module.ts b/custom-src/frontend/app/custom/custom-routing.module.ts index 6d8dc36130..d0bf7c3944 100644 --- a/custom-src/frontend/app/custom/custom-routing.module.ts +++ b/custom-src/frontend/app/custom/custom-routing.module.ts @@ -23,7 +23,7 @@ const kubernetes: Routes = [ text: 'Helm', matIcon: 'helm', matIconFont: 'stratos-icons', - position: 60, + position: 65, requiresEndpointType: 'helm' } } diff --git a/custom-src/frontend/app/custom/kubernetes/kubernetes-dashboard/kubernetes-dashboard.component.html b/custom-src/frontend/app/custom/kubernetes/kubernetes-dashboard/kubernetes-dashboard.component.html index 23b665bab0..1d7dc8c78e 100644 --- a/custom-src/frontend/app/custom/kubernetes/kubernetes-dashboard/kubernetes-dashboard.component.html +++ b/custom-src/frontend/app/custom/kubernetes/kubernetes-dashboard/kubernetes-dashboard.component.html @@ -1,23 +1,13 @@ - -

{{ (kubeEndpointService.endpoint$ | async)?.entity.name }}

+ +

Dashboard

- -
diff --git a/custom-src/frontend/app/custom/kubernetes/kubernetes-dashboard/kubernetes-dashboard.component.ts b/custom-src/frontend/app/custom/kubernetes/kubernetes-dashboard/kubernetes-dashboard.component.ts index 4bb17c7d64..9b8905667b 100644 --- a/custom-src/frontend/app/custom/kubernetes/kubernetes-dashboard/kubernetes-dashboard.component.ts +++ b/custom-src/frontend/app/custom/kubernetes/kubernetes-dashboard/kubernetes-dashboard.component.ts @@ -1,10 +1,12 @@ -import { BehaviorSubject } from 'rxjs'; +import { BehaviorSubject, Observable } from 'rxjs'; import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; import { Component, OnInit, ViewChild, ElementRef, Renderer2 } from '@angular/core'; import { KubernetesEndpointService } from '../services/kubernetes-endpoint.service'; import { BaseKubeGuid } from '../kubernetes-page.types'; import { ActivatedRoute } from '@angular/router'; import { KubernetesService } from '../services/kubernetes.service'; +import { IHeaderBreadcrumb } from '../../../shared/components/page-header/page-header.types'; +import { map } from 'rxjs/operators'; @Component({ selector: 'app-kubernetes-dashboard', @@ -38,6 +40,8 @@ export class KubernetesDashboardTabComponent implements OnInit { href = ''; + public breadcrumbs$: Observable; + constructor(public kubeEndpointService: KubernetesEndpointService, private sanitizer: DomSanitizer, public renderer: Renderer2) { } ngOnInit() { @@ -50,6 +54,15 @@ export class KubernetesDashboardTabComponent implements OnInit { this.href = href; this.source = this.sanitizer.bypassSecurityTrustResourceUrl(`/pp/v1/kubedash/${guid}/`); console.log(window.location); + + this.breadcrumbs$ = this.kubeEndpointService.endpoint$.pipe( + map(endpoint => ([{ + breadcrumbs: [ + { value: endpoint.entity.name, routerLink: `/kubernetes/${endpoint.entity.guid}` }, + ] + }]) + ) + ); } iframeLoaded() { diff --git a/custom-src/frontend/app/custom/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts b/custom-src/frontend/app/custom/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts index b080650c56..dea6620d9f 100644 --- a/custom-src/frontend/app/custom/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts +++ b/custom-src/frontend/app/custom/kubernetes/kubernetes-tab-base/kubernetes-tab-base.component.ts @@ -28,6 +28,7 @@ import { KubernetesService } from '../services/kubernetes.service'; export class KubernetesTabBaseComponent implements OnInit { tabLinks = [ + { link: 'summary', label: 'Summary' }, { link: 'nodes', label: 'Nodes' }, { link: 'namespaces', label: 'Namespaces' }, { link: 'pods', label: 'Pods' }, diff --git a/custom-src/frontend/app/custom/kubernetes/kubernetes.routing.ts b/custom-src/frontend/app/custom/kubernetes/kubernetes.routing.ts index 9a974f530a..79d6e799bf 100644 --- a/custom-src/frontend/app/custom/kubernetes/kubernetes.routing.ts +++ b/custom-src/frontend/app/custom/kubernetes/kubernetes.routing.ts @@ -25,6 +25,8 @@ import { KubernetesNodeMetricsComponent } from './kubernetes-node/kubernetes-nod import { KubernetesNamespaceComponent } from './kubernetes-namespace/kubernetes-namespace.component'; import { KubernetesNamespacePodsComponent } from './kubernetes-namespace/kubernetes-namespace-pods/kubernetes-namespace-pods.component'; import { KubernetesDashboardTabComponent } from './kubernetes-dashboard/kubernetes-dashboard.component'; +import { KubernetesSummaryTabComponent } from './tabs/kubernetes-summary-tab/kubernetes-summary.component'; + const kubernetes: Routes = [{ path: '', component: KubernetesComponent @@ -120,9 +122,13 @@ const kubernetes: Routes = [{ children: [ { path: '', - redirectTo: 'nodes', + redirectTo: 'summary', pathMatch: 'full' }, + { + path: 'summary', + component: KubernetesSummaryTabComponent + }, { path: 'nodes', component: KubernetesNodesTabComponent diff --git a/src/jetstream/middleware.go b/src/jetstream/middleware.go index 56b8d7896c..8b8da043dd 100644 --- a/src/jetstream/middleware.go +++ b/src/jetstream/middleware.go @@ -162,7 +162,6 @@ func (p *portalProxy) urlCheckMiddleware(h echo.HandlerFunc) echo.HandlerFunc { func (p *portalProxy) setStaticCacheContentMiddleware(h echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { - log.Debug("setStaticContentHeadersMiddleware") c.Response().Header().Set("cache-control", "no-cache") return h(c) } diff --git a/src/jetstream/plugins/kubernetes/kube_dashboard.go b/src/jetstream/plugins/kubernetes/kube_dashboard.go index f09d1e4b40..3583f19c86 100644 --- a/src/jetstream/plugins/kubernetes/kube_dashboard.go +++ b/src/jetstream/plugins/kubernetes/kube_dashboard.go @@ -95,7 +95,7 @@ func normalizeLocation(location *url.URL) *url.URL { } func (k *KubernetesSpecification) kubeDashboardTest(c echo.Context) error { - log.Info("kubeDashboardTest request") + log.Debug("kubeDashboardTest request") // c.Response().Header().Set("X-FRAME-OPTIONS", "sameorigin") @@ -104,16 +104,13 @@ func (k *KubernetesSpecification) kubeDashboardTest(c echo.Context) error { var p = k.portalProxy - log.Info(userGUID) - log.Info(cnsiGUID) - - log.Info(c.Request().RequestURI) + log.Debug(c.Request().RequestURI) var prefix = "/pp/v1/kubedash/" + cnsiGUID + "/" path := c.Request().RequestURI[len(prefix):] - log.Info(path) + log.Debug(path) cnsiRecord, err := p.GetCNSIRecord(cnsiGUID) if err != nil { @@ -128,18 +125,18 @@ func (k *KubernetesSpecification) kubeDashboardTest(c echo.Context) error { return errors.New("Could not get token") } - log.Info(tokenRec.AuthToken) - log.Info(tokenRec.AuthType) + log.Debug(tokenRec.AuthToken) + log.Debug(tokenRec.AuthType) // Make the info call to the SSH endpoint info // Currently this is not cached, so we must get it each time apiEndpoint := cnsiRecord.APIEndpoint - log.Info(apiEndpoint) + log.Debug(apiEndpoint) // target := fmt.Sprintf("%s/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/", apiEndpoint) //target := fmt.Sprintf("%s/api/v1/namespaces/kube-system/services/http:kubernetes-dashboard:/proxy/", apiEndpoint) // target := http://localhost:8001/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy target := fmt.Sprintf("%s/api/v1/namespaces/kube-system/services/http:kubernetes-dashboard:/proxy/%s", apiEndpoint, path) - log.Info(target) + log.Debug(target) targetURL, _ := url.Parse(target) targetURL = normalizeLocation(targetURL) @@ -148,12 +145,12 @@ func (k *KubernetesSpecification) kubeDashboardTest(c echo.Context) error { return errors.New("Could not get config for this auth type") } - log.Info("Config") - log.Info(config.Host) - log.Info("Making request") + log.Debug("Config") + log.Debug(config.Host) + log.Debug("Making request") req := c.Request() w := c.Response().Writer - log.Infof("%v+", req) + log.Debugf("%v+", req) // if h.tryUpgrade(w, req) { // return @@ -181,7 +178,6 @@ func (k *KubernetesSpecification) kubeDashboardTest(c echo.Context) error { if len(req.URL.RawQuery) > 0 { queryPart = "?" + req.URL.RawQuery } - log.Warn("REDIRECT") w.Header().Set("Location", req.URL.Path+"/"+queryPart) w.WriteHeader(http.StatusMovedPermanently) return nil @@ -205,21 +201,21 @@ func (k *KubernetesSpecification) kubeDashboardTest(c echo.Context) error { proxy.Transport = transport proxy.FlushInterval = defaultFlushInterval proxy.ModifyResponse = func(response *http.Response) error { - log.Infof("GOT PROXY RESPONSE: %s", loc.String()) - log.Infof("%d", response.StatusCode) - log.Info(response.Header.Get("Content-Type")) + log.Debugf("GOT PROXY RESPONSE: %s", loc.String()) + log.Debugf("%d", response.StatusCode) + log.Debug(response.Header.Get("Content-Type")) - log.Infof("%v+", response.Header) + log.Debugf("%v+", response.Header) response.Header.Del("X-FRAME-OPTIONS") response.Header.Set("X-FRAME-OPTIONS", "sameorigin") - log.Info("%v+", response) + log.Debug("%v+", response) return nil } // Note that ServeHttp is non blocking and uses a go routine under the hood proxy.ServeHTTP(w, newReq) - log.Infof("Finsihed proxying request: %s", target) + log.Debugf("Finsihed proxying request: %s", target) return nil } diff --git a/src/jetstream/plugins/kubernetes/list_releases.go b/src/jetstream/plugins/kubernetes/list_releases.go index e3b5b99d61..01f2556d24 100644 --- a/src/jetstream/plugins/kubernetes/list_releases.go +++ b/src/jetstream/plugins/kubernetes/list_releases.go @@ -1,6 +1,8 @@ package kubernetes import ( + "net/url" + "github.com/labstack/echo" log "github.com/sirupsen/logrus" @@ -12,6 +14,19 @@ import ( "github.com/cloudfoundry-incubator/stratos/src/jetstream/repository/interfaces" ) +type kubeReleasesData struct { + Endpoint string `json:"endpoint"` + Name string `json:"releaseName"` + Namespace string `json:"releaseNamespace"` + Chart struct { + Name string `json:"chartName"` + Repository string `json:"repo"` + Version string `json:"version"` + } `json:"chart"` +} + +type kubeReleasesResponse map[string]kubeReleasesData + // ListReleases will list the helm releases for all endpoints func (c *KubernetesSpecification) ListReleases(ec echo.Context) error { @@ -51,3 +66,44 @@ func (c *KubernetesSpecification) listReleases(ep *interfaces.ConnectedEndpoint, response.Result = res done <- response } + +// ListReleases will list the helm releases for all endpoints +func (c *KubernetesSpecification) aListReleases(ec echo.Context) error { + + // Need to get a config object for the target endpoint + // endpointGUID := ec.Param("endpoint") + userID := ec.Get("user_id").(string) + + // Get the config maps directly - don't go via Tiller + + requests := c.makeKubeProxyRequest(userID, "GET", "/api/v1/configmaps?labelSelector=OWNER%3DTILLER") + responses, _ := c.portalProxy.DoProxyRequest(requests) + return c.portalProxy.SendProxiedResponse(ec, responses) +} + +func (c *KubernetesSpecification) makeKubeProxyRequest(userID, method, uri string) []interfaces.ProxyRequestInfo { + + var p = c.portalProxy + eps, err := p.ListEndpointsByUser(userID) + if err != nil { + return nil + } + + // Construct the metadata for proxying + requests := make([]interfaces.ProxyRequestInfo, 0) + for _, endpoint := range eps { + if endpoint.CNSIType == "k8s" { + req := interfaces.ProxyRequestInfo{} + req.UserGUID = userID + req.ResultGUID = endpoint.GUID + req.EndpointGUID = endpoint.GUID + req.Method = method + + uri, _ := url.Parse(uri) + req.URI = uri + requests = append(requests, req) + } + } + + return requests +}