diff --git a/cluster/addons/kube-ui/image/.gitignore b/cluster/addons/kube-ui/image/.gitignore deleted file mode 100644 index 8b040c11b0a..00000000000 --- a/cluster/addons/kube-ui/image/.gitignore +++ /dev/null @@ -1 +0,0 @@ -kube-ui diff --git a/cluster/addons/kube-ui/image/Dockerfile b/cluster/addons/kube-ui/image/Dockerfile deleted file mode 100644 index 7faad8dca62..00000000000 --- a/cluster/addons/kube-ui/image/Dockerfile +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2015 The Kubernetes Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -FROM scratch -MAINTAINER Tim St. Clair -ADD kube-ui kube-ui -EXPOSE 8080 -ENTRYPOINT ["/kube-ui"] diff --git a/cluster/addons/kube-ui/image/Makefile b/cluster/addons/kube-ui/image/Makefile deleted file mode 100644 index d2b87e0c9a4..00000000000 --- a/cluster/addons/kube-ui/image/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# Makefile for the Docker image gcr.io/google_containers/kube-ui -# MAINTAINER: Tim St. Clair -# If you update this image please check the tag value before pushing. - -.PHONY: all container push clean - -# Keep this at dev, so no one accidentally blows away the latest published version. -TAG = dev # current version: v1.1 -PREFIX = gcr.io/google_containers - -all: push - -kube-ui: kube-ui.go - CGO_ENABLED=0 GOOS=linux godep go build -a -installsuffix cgo -ldflags '-w' ./kube-ui.go - -container: kube-ui - docker build -t $(PREFIX)/kube-ui:$(TAG) . - -push: container - gcloud docker push $(PREFIX)/kube-ui:$(TAG) - -clean: - rm -f kube-ui diff --git a/cluster/addons/kube-ui/image/kube-ui.go b/cluster/addons/kube-ui/image/kube-ui.go deleted file mode 100644 index 16b95698b00..00000000000 --- a/cluster/addons/kube-ui/image/kube-ui.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// A simple static web server for hosting the Kubernetes cluster UI. -package main - -import ( - "flag" - "fmt" - "mime" - "net/http" - - "github.com/golang/glog" - "k8s.io/kubernetes/pkg/ui/data/dashboard" - - assetfs "github.com/elazarl/go-bindata-assetfs" -) - -var ( - port = flag.Int("port", 8080, "Port number to serve at.") -) - -func main() { - flag.Parse() - - // Send correct mime type for .svg files. TODO: remove when - // https://github.com/golang/go/commit/21e47d831bafb59f22b1ea8098f709677ec8ce33 - // makes it into all of our supported go versions. - mime.AddExtensionType(".svg", "image/svg+xml") - - // Expose files in www/ on - fileServer := http.FileServer(&assetfs.AssetFS{ - Asset: dashboard.Asset, - AssetDir: dashboard.AssetDir, - Prefix: "www/app", - }) - http.Handle("/", fileServer) - - // TODO: Add support for serving over TLS. - glog.Fatal(http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", *port), nil)) -} diff --git a/hack/build-ui.sh b/hack/build-ui.sh old mode 100755 new mode 100644 index c04b786d02a..b5111319884 --- a/hack/build-ui.sh +++ b/hack/build-ui.sh @@ -26,13 +26,11 @@ source "${KUBE_ROOT}/hack/lib/init.sh" cd "${KUBE_ROOT}" if ! which go-bindata > /dev/null 2>&1 ; then - echo "Cannot find go-bindata. Install with \"go get github.com/jteeuwen/go-bindata/...\"" - exit 1 + echo "Cannot find go-bindata. Install with \"go get github.com/jteeuwen/go-bindata/...\"" + exit 1 fi readonly TMP_DATAFILE="/tmp/datafile.go" -readonly DASHBOARD_SRC="www/app/..." -readonly DASHBOARD_PKG="dashboard" readonly SWAGGER_SRC="third_party/swagger-ui/..." readonly SWAGGER_PKG="swagger" @@ -51,18 +49,6 @@ function kube::hack::build_ui() { gofmt -s -w "${TMP_DATAFILE}" mv "${TMP_DATAFILE}" "${output_file}" - } -case "${1:-}" in - dashboard) - kube::hack::build_ui "${DASHBOARD_PKG}" "${DASHBOARD_SRC}" - ;; - swagger) - kube::hack::build_ui "${SWAGGER_PKG}" "${SWAGGER_SRC}" - ;; - *) - kube::hack::build_ui "${DASHBOARD_PKG}" "${DASHBOARD_SRC}" - kube::hack::build_ui "${SWAGGER_PKG}" "${SWAGGER_SRC}" - ;; -esac +kube::hack::build_ui "${SWAGGER_PKG}" "${SWAGGER_SRC}" diff --git a/pkg/ui/data/dashboard/datafile.go b/pkg/ui/data/dashboard/datafile.go deleted file mode 100644 index 2d2085b44cb..00000000000 --- a/pkg/ui/data/dashboard/datafile.go +++ /dev/null @@ -1,4939 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors All rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// generated by hack/build-ui.sh; DO NOT EDIT - -package dashboard - -import ( - "fmt" - "io/ioutil" - "os" - "path" - "path/filepath" - "strings" - "time" -) - -type asset struct { - bytes []byte - info os.FileInfo -} - -type bindata_file_info struct { - name string - size int64 - mode os.FileMode - modTime time.Time -} - -func (fi bindata_file_info) Name() string { - return fi.name -} -func (fi bindata_file_info) Size() int64 { - return fi.size -} -func (fi bindata_file_info) Mode() os.FileMode { - return fi.mode -} -func (fi bindata_file_info) ModTime() time.Time { - return fi.modTime -} -func (fi bindata_file_info) IsDir() bool { - return false -} -func (fi bindata_file_info) Sys() interface{} { - return nil -} - -var _www_app_assets_css_app_css = []byte(`.nav-back{width:80px;font-size:14px;padding-left:14px;line-height:15px;background-size:14px 14px;background-repeat:no-repeat;display:block}a{text-decoration:none}.main-fab{position:absolute;z-index:20;font-size:30px;top:100px;left:24px;transform:scale(.88,.88)}.md-breadcrumb{padding-left:16px}.md-table{min-width:100%;border-collapse:collapse}.md-table tbody tr:focus,.md-table tbody tr:hover{cursor:pointer;background-color:rgba(63,81,181,.2)}.md-table-header{border-bottom:1px solid #e6e6e6;color:#828282;text-align:left;font-size:.75em;font-weight:700;padding:16px 16px 16px 0}.md-table-header a{text-decoration:none;color:inherit}.md-table-caret{display:inline-block;vertical-align:middle}.md-table-content{font-size:.8em;padding:16px 16px 16px 0}.md-table-td-more{max-width:72px;width:72px;padding:16px}.md-table-thumbs{max-width:104px;width:104px;padding:16px 32px}.md-table-thumbs div{overflow:hidden;width:40px;height:40px;border-radius:20px;border:1px solid rgba(0,0,0,.2);background-size:cover;box-shadow:0 8px 10px rgba(0,0,0,.3);-webkit-box-shadow:0 8px 10px rgba(0,0,0,.1)}.md-table-footer{height:40px}.md-table-count-info{line-height:40px;font-size:.75em}.md-table-footer-item{width:40px;height:40px;vertical-align:middle}.bold,.md-table-active-page{font-weight:700}.gray,.grey{color:#888}md-input-container.md-default-theme .md-input{color:#fff;border-color:#fff;margin-top:24px}.dashboard-subnav{font-size:.9em;min-height:38px;max-height:38px;background-color:#09c1d1!important}.dashboard-subnav md-select.md-default-theme:focus .md-select-label{border-bottom:none;color:#fff}.selectSubPages p{text-align:center;color:#fff}.selectSubPages .md-default-theme .md-select-label.md-placeholder{color:#fff}.selectSubPages .md-select-label{padding-top:0;font-size:1em;line-height:1em;border-bottom:none;padding-bottom:0}.selectSubPages md-select{margin-top:10px;margin-right:80px;padding:0}md-select-menu{max-height:none}.md-toolbar-tools{padding-left:8px;padding-right:8px}.md-toolbar-small{height:38px;min-height:38px}.md-toolbar-tools-small{background-color:#09c1d1}.kubernetes-ui-menu,.kubernetes-ui-menu ul{list-style:none;padding:0}.kubernetes-ui-menu li{margin:0}.kubernetes-ui-menu>li{border-top:1px solid rgba(0,0,0,.12)}.kubernetes-ui-menu .md-button{border-radius:0;color:inherit;cursor:pointer;font-weight:400;line-height:40px;margin:0;max-height:40px;overflow:hidden;padding:0 16px;text-align:left;text-decoration:none;white-space:normal;width:100%}.kubernetes-ui-menu a.md-button{display:block}.kubernetes-ui-menu button.md-button::-moz-focus-inner{padding:0}.kubernetes-ui-menu .md-button.active{color:#03a9f4}.menu-heading{color:#888;display:block;font-size:inherit;font-weight:500;line-height:40px;margin:0;padding:0 16px;text-align:left;width:100%}.kubernetes-ui-menu li.parentActive,.kubernetes-ui-menu li.parentActive .menu-toggle-list{background-color:#f6f6f6}.menu-toggle-list{background:#fff;max-height:999px;overflow:hidden;position:relative;z-index:1;-webkit-transition:.75s cubic-bezier(.35,0,.25,1);-webkit-transition-property:max-height;-moz-transition:.75s cubic-bezier(.35,0,.25,1);-moz-transition-property:max-height;transition:.75s cubic-bezier(.35,0,.25,1);transition-property:max-height}.menu-toggle-list.ng-hide{max-height:0}.kubernetes-ui-menu .menu-toggle-list a.md-button{display:block;padding:0 16px 0 32px;text-transform:none}.md-button-toggle .md-toggle-icon{background:url(../img/icons/list_control_down.png) center center no-repeat;background-size:100% auto;display:inline-block;height:24px;margin:auto 0 auto auto;speak:none;width:24px;transition:transform .3s ease-in-out;-webkit-transition:-webkit-transform .3s ease-in-out}.md-button-toggle .md-toggle-icon.toggled{transform:rotate(180deg);-webkit-transform:rotate(180deg)}.menu-icon{background:0 0;border:none;margin-right:16px;padding:0}.whiteframedemoBasicUsage md-whiteframe{background:#fff;margin:2px;padding:2px}.tabsDefaultTabs{height:100%;width:100%}.tabsDefaultTabs .remove-tab{margin-bottom:40px}.tabsDefaultTabs .home-buttons .md-button{display:block;max-height:30px}.tabsDefaultTabs .home-buttons .md-button.add-tab{margin-top:20px;max-height:30px!important}.tabsDefaultTabs .demo-tab{display:block;position:relative;background:#fff;border:0 solid #000;min-height:0;width:100%}.tabsDefaultTabs .tab0,.tabsDefaultTabs .tab1,.tabsDefaultTabs .tab2,.tabsDefaultTabs .tab3{background-color:#bbdefb}.tabsDefaultTabs .md-header{background-color:#1976D2!important}.tabsDefaultTabs md-tab{color:#90caf9!important}.tabsDefaultTabs md-tab.active,.tabsDefaultTabs md-tab:focus{color:#fff!important}.tabsDefaultTabs md-tab[disabled]{opacity:.5}.tabsDefaultTabs .md-header .md-ripple{border-color:#FFFF8D!important}.tabsDefaultTabs md-tabs-ink-bar{background-color:#FFFF8D!important}.tabsDefaultTabs .title{padding-top:8px;padding-right:8px;text-align:left;text-transform:uppercase;color:#888;margin-top:24px}.tabsDefaultTabs [layout-align]>*,.tabsDefaultTabs form>[layout]>*{margin-left:8px}.tabsDefaultTabs .long>input{width:264px}.menuBtn{background-color:transparent;border:none;height:38px;margin:16px;position:absolute;width:36px}md-toolbar h1{margin:auto}md-list .md-button{color:inherit;font-weight:500;text-align:left;width:100%}md-list .md-button.selected{color:#03a9f4}#content{overflow:hidden}#content md-content{padding-left:0;padding-right:0;padding-top:0}#content .md-button.action{background-color:transparent;border:none;height:38px;margin:8px auto 16px 0;position:absolute;top:10px;right:25px;width:36px}#content img{display:block;height:auto;max-width:500px}.content-wrapper{position:relative}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}md-toolbar h1{font-size:1.25em;font-weight:400}.menuBtn{background:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB3aWR0aD0iMjRweCIgaGVpZ2h0PSIyNHB4IiB2aWV3Qm94PSIwIDAgMjQgMjQiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDI0IDI0IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPGcgaWQ9IkhlYWRlciI+CiAgICA8Zz4KICAgICAgICA8cmVjdCB4PSItNjE4IiB5PSItMjIzMiIgZmlsbD0ibm9uZSIgd2lkdGg9IjE0MDAiIGhlaWdodD0iMzYwMCIvPgogICAgPC9nPgo8L2c+CjxnIGlkPSJMYWJlbCI+CjwvZz4KPGcgaWQ9Ikljb24iPgogICAgPGc+CiAgICAgICAgPHJlY3QgZmlsbD0ibm9uZSIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0Ii8+CiAgICAgICAgPHBhdGggZD0iTTMsMThoMTh2LTJIM1YxOHogTTMsMTNoMTh2LTJIM1YxM3ogTTMsNnYyaDE4VjZIM3oiIHN0eWxlPSJmaWxsOiNmM2YzZjM7Ii8+CiAgICA8L2c+CjwvZz4KPGcgaWQ9IkdyaWQiIGRpc3BsYXk9Im5vbmUiPgogICAgPGcgZGlzcGxheT0iaW5saW5lIj4KICAgIDwvZz4KPC9nPgo8L3N2Zz4=) center center no-repeat}.actionBtn{background:url(data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzNiIgaGVpZ2h0PSIzNiIgdmlld0JveD0iMCAwIDM2IDM2Ij4NCiAgICA8cGF0aCBkPSJNMCAwaDM2djM2aC0zNnoiIGZpbGw9Im5vbmUiLz4NCiAgICA8cGF0aCBkPSJNNCAyN2gyOHYtM2gtMjh2M3ptMC04aDI4di0zaC0yOHYzem0wLTExdjNoMjh2LTNoLTI4eiIvPg0KPC9zdmc+) center center no-repeat}.kubernetes-ui-logo{background-image:url(../img/kubernetes.svg);background-size:40px 40px;width:40px;height:40px}.kubernetes-ui-text{line-height:40px;vertical-align:middle;padding:2px}md-select-menu.md-default-theme md-option:focus:not([selected]){background:#eee}md-select-menu md-option{transition:box-shadow .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1),-webkit-transform .4s cubic-bezier(.25,.8,.25,1);transition:box-shadow .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1),transform .4s cubic-bezier(.25,.8,.25,1)}md-select-menu md-option:not([disabled]):focus,md-select-menu md-option:not([disabled]):hover{background-color:rgba(158,158,158,.2)}.dashboard .body-wrapper{padding:25px}.dashboard [flex-align-self=end]{-webkit-align-self:flex-end;-ms-flex-align-self:end;align-self:flex-end}.dashboard .back{font-size:18px;line-height:27px;margin-bottom:30px}.dashboard .heading{font-size:18px;line-height:21px;color:#222;margin-bottom:25px}.dashboard .heading .label{color:#777}.dashboard .clear-bg{background-color:transparent}.dashboard .list-pods .pod-group{margin:25px}.dashboard .list-pods .pod-group md-grid-list{margin-top:50px;color:#fff}.dashboard .list-pods .pod-group md-grid-list figcaption{width:100%}.dashboard .list-pods .pod-group md-grid-list md-grid-tile-header{padding-left:10px}.dashboard .list-pods .pod-group md-grid-list md-grid-tile-header .labels{width:100%}.dashboard .list-pods .pod-group md-grid-list md-grid-tile{transition:all 700ms ease-in 50ms}.dashboard .list-pods .pod-group md-grid-list .inner-box{padding-left:10px;padding-right:10px}.dashboard .list-pods .pod-group md-grid-list md-grid-tile-footer{background:rgba(0,0,0,.5)}.dashboard .list-pods .pod-group md-grid-list md-grid-tile-footer .pod-title{margin-left:10px}.dashboard .list-pods .pod-group md-grid-list md-grid-tile-footer .pod-host{text-align:right;padding-right:15px}.dashboard .list-pods .pod-group md-grid-list md-grid-tile-footer a{color:#fff}.dashboard .list-pods .pod-group md-grid-list .restarts{width:100%;text-align:right;padding-right:10px}.dashboard .list-pods .pod-group md-grid-list .restarts .restart-button,.dashboard .list-pods .pod-group md-grid-list .restarts .restart-button:focus,.dashboard .list-pods .pod-group md-grid-list .restarts .restart-button:hover,.dashboard .list-pods .pod-group md-grid-list .restarts .restart-button:not([disabled]):focus,.dashboard .list-pods .pod-group md-grid-list .restarts .restart-button:not([disabled]):hover{background-color:#ff1744;width:30px;height:30px}.dashboard .list-pods .gray{background:#f5f5f5}.dashboard .list-pods .dark-overlay{background-color:#292935;opacity:.5}.dashboard .list-pods .light-overlay{background-color:#FFF;opacity:.2}.dashboard .list-pods .color-1{background-color:#2962ff;fill:#2962ff;stroke:#2962ff}.dashboard .list-pods .color-max-1{background-color:#dce5ff;border-color:#dce5ff;fill:#dce5ff}.dashboard .list-pods md-grid-list.list-color-1 md-grid-tile.colored{background-color:#2962ff}.dashboard .list-pods .color-2{background-color:#a0f;fill:#a0f;stroke:#a0f}.dashboard .list-pods .color-max-2{background-color:#e6b3ff;border-color:#e6b3ff;fill:#e6b3ff}.dashboard .list-pods md-grid-list.list-color-2 md-grid-tile.colored{background-color:#a0f}.dashboard .list-pods .color-3{background-color:#00c853;fill:#00c853;stroke:#00c853}.dashboard .list-pods .color-max-3{background-color:#7cffb2;border-color:#7cffb2;fill:#7cffb2}.dashboard .list-pods md-grid-list.list-color-3 md-grid-tile.colored{background-color:#00c853}.dashboard .list-pods .color-4{background-color:#304ffe;fill:#304ffe;stroke:#304ffe}.dashboard .list-pods .color-max-4{background-color:#e2e6ff;border-color:#e2e6ff;fill:#e2e6ff}.dashboard .list-pods md-grid-list.list-color-4 md-grid-tile.colored{background-color:#304ffe}.dashboard .list-pods .color-5{background-color:#0091ea;fill:#0091ea;stroke:#0091ea}.dashboard .list-pods .color-max-5{background-color:#9edaff;border-color:#9edaff;fill:#9edaff}.dashboard .list-pods md-grid-list.list-color-5 md-grid-tile.colored{background-color:#0091ea}.dashboard .list-pods .color-6{background-color:#ff6d00;fill:#ff6d00;stroke:#ff6d00}.dashboard .list-pods .color-max-6{background-color:#ffd3b3;border-color:#ffd3b3;fill:#ffd3b3}.dashboard .list-pods md-grid-list.list-color-6 md-grid-tile.colored{background-color:#ff6d00}.dashboard .list-pods .color-7{background-color:#00bfa5;fill:#00bfa5;stroke:#00bfa5}.dashboard .list-pods .color-max-7{background-color:#72ffec;border-color:#72ffec;fill:#72ffec}.dashboard .list-pods md-grid-list.list-color-7 md-grid-tile.colored{background-color:#00bfa5}.dashboard .list-pods .color-8{background-color:#c51162;fill:#c51162;stroke:#c51162}.dashboard .list-pods .color-max-8{background-color:#f693bf;border-color:#f693bf;fill:#f693bf}.dashboard .list-pods md-grid-list.list-color-8 md-grid-tile.colored{background-color:#c51162}.dashboard .list-pods .color-9{background-color:#64dd17;fill:#64dd17;stroke:#64dd17}.dashboard .list-pods .color-max-9{background-color:#cbf7b0;border-color:#cbf7b0;fill:#cbf7b0}.dashboard .list-pods md-grid-list.list-color-9 md-grid-tile.colored{background-color:#64dd17}.dashboard .list-pods .color-10{background-color:#6200ea;fill:#6200ea;stroke:#6200ea}.dashboard .list-pods .color-max-10{background-color:#c69eff;border-color:#c69eff;fill:#c69eff}.dashboard .list-pods md-grid-list.list-color-10 md-grid-tile.colored{background-color:#6200ea}.dashboard .list-pods .color-11{background-color:#ffd600;fill:#ffd600;stroke:#ffd600}.dashboard .list-pods .color-max-11{background-color:#fff3b3;border-color:#fff3b3;fill:#fff3b3}.dashboard .list-pods md-grid-list.list-color-11 md-grid-tile.colored{background-color:#ffd600}.dashboard .list-pods .color-12{background-color:#00b8d4;fill:#00b8d4;stroke:#00b8d4}.dashboard .list-pods .color-max-12{background-color:#87efff;border-color:#87efff;fill:#87efff}.dashboard .list-pods md-grid-list.list-color-12 md-grid-tile.colored{background-color:#00b8d4}.dashboard .list-pods .color-13{background-color:#ffab00;fill:#ffab00;stroke:#ffab00}.dashboard .list-pods .color-max-13{background-color:#ffe6b3;border-color:#ffe6b3;fill:#ffe6b3}.dashboard .list-pods md-grid-list.list-color-13 md-grid-tile.colored{background-color:#ffab00}.dashboard .list-pods .color-14{background-color:#dd2c00;fill:#dd2c00;stroke:#dd2c00}.dashboard .list-pods .color-max-14{background-color:#ffa791;border-color:#ffa791;fill:#ffa791}.dashboard .list-pods md-grid-list.list-color-14 md-grid-tile.colored{background-color:#dd2c00}.dashboard .list-pods .color-15{background-color:#2979ff;fill:#2979ff;stroke:#2979ff}.dashboard .list-pods .color-max-15{background-color:#dce9ff;border-color:#dce9ff;fill:#dce9ff}.dashboard .list-pods md-grid-list.list-color-15 md-grid-tile.colored{background-color:#2979ff}.dashboard .list-pods .color-16{background-color:#d500f9;fill:#d500f9;stroke:#d500f9}.dashboard .list-pods .color-max-16{background-color:#f3acff;border-color:#f3acff;fill:#f3acff}.dashboard .list-pods md-grid-list.list-color-16 md-grid-tile.colored{background-color:#d500f9}.dashboard .list-pods .color-17{background-color:#00e676;fill:#00e676;stroke:#00e676}.dashboard .list-pods .color-max-17{background-color:#9affce;border-color:#9affce;fill:#9affce}.dashboard .list-pods md-grid-list.list-color-17 md-grid-tile.colored{background-color:#00e676}.dashboard .list-pods .color-18{background-color:#3d5afe;fill:#3d5afe;stroke:#3d5afe}.dashboard .list-pods .color-max-18{background-color:#eff1ff;border-color:#eff1ff;fill:#eff1ff}.dashboard .list-pods md-grid-list.list-color-18 md-grid-tile.colored{background-color:#3d5afe}.dashboard .list-pods .color-19{background-color:#00b0ff;fill:#00b0ff;stroke:#00b0ff}.dashboard .list-pods .color-max-19{background-color:#b3e7ff;border-color:#b3e7ff;fill:#b3e7ff}.dashboard .list-pods md-grid-list.list-color-19 md-grid-tile.colored{background-color:#00b0ff}.dashboard .list-pods .color-20{background-color:#ff9100;fill:#ff9100;stroke:#ff9100}.dashboard .list-pods .color-max-20{background-color:#ffdeb3;border-color:#ffdeb3;fill:#ffdeb3}.dashboard .list-pods md-grid-list.list-color-20 md-grid-tile.colored{background-color:#ff9100}.dashboard .list-pods .color-21{background-color:#1de9b6;fill:#1de9b6;stroke:#1de9b6}.dashboard .list-pods .color-max-21{background-color:#c0f9eb;border-color:#c0f9eb;fill:#c0f9eb}.dashboard .list-pods md-grid-list.list-color-21 md-grid-tile.colored{background-color:#1de9b6}.dashboard .list-pods .color-22{background-color:#f50057;fill:#f50057;stroke:#f50057}.dashboard .list-pods .color-max-22{background-color:#ffa8c7;border-color:#ffa8c7;fill:#ffa8c7}.dashboard .list-pods md-grid-list.list-color-22 md-grid-tile.colored{background-color:#f50057}.dashboard .list-pods .color-23{background-color:#76ff03;fill:#76ff03;stroke:#76ff03}.dashboard .list-pods .color-max-23{background-color:#d7ffb5;border-color:#d7ffb5;fill:#d7ffb5}.dashboard .list-pods md-grid-list.list-color-23 md-grid-tile.colored{background-color:#76ff03}.dashboard .list-pods .color-24{background-color:#651fff;fill:#651fff;stroke:#651fff}.dashboard .list-pods .color-max-24{background-color:#e0d2ff;border-color:#e0d2ff;fill:#e0d2ff}.dashboard .list-pods md-grid-list.list-color-24 md-grid-tile.colored{background-color:#651fff}.dashboard .list-pods .color-25{background-color:#ffea00;fill:#ffea00;stroke:#ffea00}.dashboard .list-pods .color-max-25{background-color:#fff9b3;border-color:#fff9b3;fill:#fff9b3}.dashboard .list-pods md-grid-list.list-color-25 md-grid-tile.colored{background-color:#ffea00}.dashboard .list-pods .color-26{background-color:#00e5ff;fill:#00e5ff;stroke:#00e5ff}.dashboard .list-pods .color-max-26{background-color:#b3f7ff;border-color:#b3f7ff;fill:#b3f7ff}.dashboard .list-pods md-grid-list.list-color-26 md-grid-tile.colored{background-color:#00e5ff}.dashboard .list-pods .color-27{background-color:#ffc400;fill:#ffc400;stroke:#ffc400}.dashboard .list-pods .color-max-27{background-color:#ffedb3;border-color:#ffedb3;fill:#ffedb3}.dashboard .list-pods md-grid-list.list-color-27 md-grid-tile.colored{background-color:#ffc400}.dashboard .list-pods .color-28{background-color:#ff3d00;fill:#ff3d00;stroke:#ff3d00}.dashboard .list-pods .color-max-28{background-color:#ffc5b3;border-color:#ffc5b3;fill:#ffc5b3}.dashboard .list-pods md-grid-list.list-color-28 md-grid-tile.colored{background-color:#ff3d00}.dashboard .list-pods .color-29{background-color:#448aff;fill:#448aff;stroke:#448aff}.dashboard .list-pods .color-max-29{background-color:#f6faff;border-color:#f6faff;fill:#f6faff}.dashboard .list-pods md-grid-list.list-color-29 md-grid-tile.colored{background-color:#448aff}.dashboard .list-pods .color-30{background-color:#e040fb;fill:#e040fb;stroke:#e040fb}.dashboard .list-pods .color-max-30{background-color:#fcefff;border-color:#fcefff;fill:#fcefff}.dashboard .list-pods md-grid-list.list-color-30 md-grid-tile.colored{background-color:#e040fb}.dashboard .list-pods .color-31{background-color:#69f0ae;fill:#69f0ae;stroke:#69f0ae}.dashboard .list-pods .color-max-31{background-color:#fff;border-color:#fff;fill:#fff}.dashboard .list-pods md-grid-list.list-color-31 md-grid-tile.colored{background-color:#69f0ae}.dashboard .list-pods .color-32{background-color:#536dfe;fill:#536dfe;stroke:#536dfe}.dashboard .list-pods .color-max-32{background-color:#fff;border-color:#fff;fill:#fff}.dashboard .list-pods md-grid-list.list-color-32 md-grid-tile.colored{background-color:#536dfe}.dashboard .list-pods .color-33{background-color:#40c4ff;fill:#40c4ff;stroke:#40c4ff}.dashboard .list-pods .color-max-33{background-color:#f3fbff;border-color:#f3fbff;fill:#f3fbff}.dashboard .list-pods md-grid-list.list-color-33 md-grid-tile.colored{background-color:#40c4ff}.dashboard .list-pods .color-34{background-color:#ffab40;fill:#ffab40;stroke:#ffab40}.dashboard .list-pods .color-max-34{background-color:#fffaf3;border-color:#fffaf3;fill:#fffaf3}.dashboard .list-pods md-grid-list.list-color-34 md-grid-tile.colored{background-color:#ffab40}.dashboard .list-pods .color-35{background-color:#64ffda;fill:#64ffda;stroke:#64ffda}.dashboard .list-pods .color-max-35{background-color:#fff;border-color:#fff;fill:#fff}.dashboard .list-pods md-grid-list.list-color-35 md-grid-tile.colored{background-color:#64ffda}.dashboard .list-pods .color-36{background-color:#ff4081;fill:#ff4081;stroke:#ff4081}.dashboard .list-pods .color-max-36{background-color:#fff3f7;border-color:#fff3f7;fill:#fff3f7}.dashboard .list-pods md-grid-list.list-color-36 md-grid-tile.colored{background-color:#ff4081}.dashboard .list-pods .color-37{background-color:#b2ff59;fill:#b2ff59;stroke:#b2ff59}.dashboard .list-pods .color-max-37{background-color:#fff;border-color:#fff;fill:#fff}.dashboard .list-pods md-grid-list.list-color-37 md-grid-tile.colored{background-color:#b2ff59}.dashboard .list-pods .color-38{background-color:#7c4dff;fill:#7c4dff;stroke:#7c4dff}.dashboard .list-pods .color-max-38{background-color:#fff;border-color:#fff;fill:#fff}.dashboard .list-pods md-grid-list.list-color-38 md-grid-tile.colored{background-color:#7c4dff}.dashboard .list-pods .color-39{background-color:#ff0;fill:#ff0;stroke:#ff0}.dashboard .list-pods .color-max-39{background-color:#ffffb3;border-color:#ffffb3;fill:#ffffb3}.dashboard .list-pods md-grid-list.list-color-39 md-grid-tile.colored{background-color:#ff0}.dashboard .list-pods .color-40{background-color:#18ffff;fill:#18ffff;stroke:#18ffff}.dashboard .list-pods .color-max-40{background-color:#cbffff;border-color:#cbffff;fill:#cbffff}.dashboard .list-pods md-grid-list.list-color-40 md-grid-tile.colored{background-color:#18ffff}.dashboard .list-pods .color-41{background-color:#ffd740;fill:#ffd740;stroke:#ffd740}.dashboard .list-pods .color-max-41{background-color:#fffcf3;border-color:#fffcf3;fill:#fffcf3}.dashboard .list-pods md-grid-list.list-color-41 md-grid-tile.colored{background-color:#ffd740}.dashboard .list-pods .color-42{background-color:#ff6e40;fill:#ff6e40;stroke:#ff6e40}.dashboard .list-pods .color-max-42{background-color:#fff6f3;border-color:#fff6f3;fill:#fff6f3}.dashboard .list-pods md-grid-list.list-color-42 md-grid-tile.colored{background-color:#ff6e40}.dashboard .list-pods .color-warning{background-color:#ff9800!important;border-color:#ff9800!important;fill:#ff9800!important;stroke:#ff9800!important}.dashboard .list-pods .color-critical{background-color:#f44336!important;border-color:#f44336!important;fill:#f44336!important;stroke:#f44336!important}.dashboard .list-pods .status-waiting{background-color:#2e2e3b!important;border-color:#dad462!important;border-width:2px!important;border-style:solid!important}.dashboard .list-pods .status-terminated,.dashboard .list-pods .status-unknown{background-color:#ff1744!important;border-color:#e3002c!important;border-width:1px!important;border-style:solid!important}.dashboard .dash-table{min-width:100%;border-collapse:collapse}.dashboard .dash-table tbody tr:focus:not(.no-link),.dashboard .dash-table tbody tr:hover:not(.no-link){cursor:pointer;background-color:rgba(63,81,181,.2)}.dashboard .dash-table .dash-table-header{border-bottom:1px solid #e6e6e6;color:#828282;text-align:left;font-size:.75em;font-weight:700;padding:16px 16px 16px 0}.dashboard .dash-table .dash-table-header a{text-decoration:none;color:inherit}.dashboard .dash-table .dash-table-caret{display:inline-block;vertical-align:middle}.dashboard .dash-table .dash-table-content{font-size:.8em;padding:16px 16px 16px 0;height:72px}.dashboard .dash-table .dash-table-td-more{max-width:72px;width:72px;padding:16px}.dashboard .dash-table .dash-table-thumbs{max-width:104px;width:104px;padding:16px 32px}.dashboard .dash-table .dash-table-thumbs div{overflow:hidden;width:40px;height:40px;border-radius:20px;border:1px solid rgba(0,0,0,.2);background-size:cover;box-shadow:0 8px 10px rgba(0,0,0,.3);-webkit-box-shadow:0 8px 10px rgba(0,0,0,.1)}.dashboard .dash-table .dash-table-footer{height:40px}.dashboard .dash-table .dash-table-count-info{line-height:40px;font-size:.75em}.dashboard .dash-table .dash-table-footer-item{width:40px;height:40px;vertical-align:middle}.dashboard .dash-table .bold,.dashboard .dash-table .dash-table-active-page{font-weight:700}.dashboard .dash-table .grey{color:grey}.dashboard .dash-table md-input-container.md-default-theme .md-input{color:#fff;border-color:#fff;margin-top:24px}.dashboard .server-overview .dark-overlay{background-color:#292935;opacity:.5}.dashboard .server-overview .light-overlay{background-color:#FFF;opacity:.2}.dashboard .server-overview md-grid-list.list-color-1 md-grid-tile.colored{background-color:#2962ff}.dashboard .server-overview md-grid-list.list-color-2 md-grid-tile.colored{background-color:#a0f}.dashboard .server-overview md-grid-list.list-color-3 md-grid-tile.colored{background-color:#00c853}.dashboard .server-overview .color-4{background-color:#304ffe;fill:#304ffe;stroke:#304ffe}.dashboard .server-overview .color-max-4{background-color:#e2e6ff;border-color:#e2e6ff;fill:#e2e6ff}.dashboard .server-overview md-grid-list.list-color-4 md-grid-tile.colored{background-color:#304ffe}.dashboard .server-overview .color-5{background-color:#0091ea;fill:#0091ea;stroke:#0091ea}.dashboard .server-overview .color-max-5{background-color:#9edaff;border-color:#9edaff;fill:#9edaff}.dashboard .server-overview md-grid-list.list-color-5 md-grid-tile.colored{background-color:#0091ea}.dashboard .server-overview .color-6{background-color:#ff6d00;fill:#ff6d00;stroke:#ff6d00}.dashboard .server-overview .color-max-6{background-color:#ffd3b3;border-color:#ffd3b3;fill:#ffd3b3}.dashboard .server-overview md-grid-list.list-color-6 md-grid-tile.colored{background-color:#ff6d00}.dashboard .server-overview .color-7{background-color:#00bfa5;fill:#00bfa5;stroke:#00bfa5}.dashboard .server-overview .color-max-7{background-color:#72ffec;border-color:#72ffec;fill:#72ffec}.dashboard .server-overview md-grid-list.list-color-7 md-grid-tile.colored{background-color:#00bfa5}.dashboard .server-overview .color-8{background-color:#c51162;fill:#c51162;stroke:#c51162}.dashboard .server-overview .color-max-8{background-color:#f693bf;border-color:#f693bf;fill:#f693bf}.dashboard .server-overview md-grid-list.list-color-8 md-grid-tile.colored{background-color:#c51162}.dashboard .server-overview .color-9{background-color:#64dd17;fill:#64dd17;stroke:#64dd17}.dashboard .server-overview .color-max-9{background-color:#cbf7b0;border-color:#cbf7b0;fill:#cbf7b0}.dashboard .server-overview md-grid-list.list-color-9 md-grid-tile.colored{background-color:#64dd17}.dashboard .server-overview .color-10{background-color:#6200ea;fill:#6200ea;stroke:#6200ea}.dashboard .server-overview .color-max-10{background-color:#c69eff;border-color:#c69eff;fill:#c69eff}.dashboard .server-overview md-grid-list.list-color-10 md-grid-tile.colored{background-color:#6200ea}.dashboard .server-overview .color-11{background-color:#ffd600;fill:#ffd600;stroke:#ffd600}.dashboard .server-overview .color-max-11{background-color:#fff3b3;border-color:#fff3b3;fill:#fff3b3}.dashboard .server-overview md-grid-list.list-color-11 md-grid-tile.colored{background-color:#ffd600}.dashboard .server-overview .color-12{background-color:#00b8d4;fill:#00b8d4;stroke:#00b8d4}.dashboard .server-overview .color-max-12{background-color:#87efff;border-color:#87efff;fill:#87efff}.dashboard .server-overview md-grid-list.list-color-12 md-grid-tile.colored{background-color:#00b8d4}.dashboard .server-overview .color-13{background-color:#ffab00;fill:#ffab00;stroke:#ffab00}.dashboard .server-overview .color-max-13{background-color:#ffe6b3;border-color:#ffe6b3;fill:#ffe6b3}.dashboard .server-overview md-grid-list.list-color-13 md-grid-tile.colored{background-color:#ffab00}.dashboard .server-overview .color-14{background-color:#dd2c00;fill:#dd2c00;stroke:#dd2c00}.dashboard .server-overview .color-max-14{background-color:#ffa791;border-color:#ffa791;fill:#ffa791}.dashboard .server-overview md-grid-list.list-color-14 md-grid-tile.colored{background-color:#dd2c00}.dashboard .server-overview .color-15{background-color:#2979ff;fill:#2979ff;stroke:#2979ff}.dashboard .server-overview .color-max-15{background-color:#dce9ff;border-color:#dce9ff;fill:#dce9ff}.dashboard .server-overview md-grid-list.list-color-15 md-grid-tile.colored{background-color:#2979ff}.dashboard .server-overview .color-16{background-color:#d500f9;fill:#d500f9;stroke:#d500f9}.dashboard .server-overview .color-max-16{background-color:#f3acff;border-color:#f3acff;fill:#f3acff}.dashboard .server-overview md-grid-list.list-color-16 md-grid-tile.colored{background-color:#d500f9}.dashboard .server-overview .color-17{background-color:#00e676;fill:#00e676;stroke:#00e676}.dashboard .server-overview .color-max-17{background-color:#9affce;border-color:#9affce;fill:#9affce}.dashboard .server-overview md-grid-list.list-color-17 md-grid-tile.colored{background-color:#00e676}.dashboard .server-overview .color-18{background-color:#3d5afe;fill:#3d5afe;stroke:#3d5afe}.dashboard .server-overview .color-max-18{background-color:#eff1ff;border-color:#eff1ff;fill:#eff1ff}.dashboard .server-overview md-grid-list.list-color-18 md-grid-tile.colored{background-color:#3d5afe}.dashboard .server-overview .color-19{background-color:#00b0ff;fill:#00b0ff;stroke:#00b0ff}.dashboard .server-overview .color-max-19{background-color:#b3e7ff;border-color:#b3e7ff;fill:#b3e7ff}.dashboard .server-overview md-grid-list.list-color-19 md-grid-tile.colored{background-color:#00b0ff}.dashboard .server-overview .color-20{background-color:#ff9100;fill:#ff9100;stroke:#ff9100}.dashboard .server-overview .color-max-20{background-color:#ffdeb3;border-color:#ffdeb3;fill:#ffdeb3}.dashboard .server-overview md-grid-list.list-color-20 md-grid-tile.colored{background-color:#ff9100}.dashboard .server-overview .color-21{background-color:#1de9b6;fill:#1de9b6;stroke:#1de9b6}.dashboard .server-overview .color-max-21{background-color:#c0f9eb;border-color:#c0f9eb;fill:#c0f9eb}.dashboard .server-overview md-grid-list.list-color-21 md-grid-tile.colored{background-color:#1de9b6}.dashboard .server-overview .color-22{background-color:#f50057;fill:#f50057;stroke:#f50057}.dashboard .server-overview .color-max-22{background-color:#ffa8c7;border-color:#ffa8c7;fill:#ffa8c7}.dashboard .server-overview md-grid-list.list-color-22 md-grid-tile.colored{background-color:#f50057}.dashboard .server-overview .color-23{background-color:#76ff03;fill:#76ff03;stroke:#76ff03}.dashboard .server-overview .color-max-23{background-color:#d7ffb5;border-color:#d7ffb5;fill:#d7ffb5}.dashboard .server-overview md-grid-list.list-color-23 md-grid-tile.colored{background-color:#76ff03}.dashboard .server-overview .color-24{background-color:#651fff;fill:#651fff;stroke:#651fff}.dashboard .server-overview .color-max-24{background-color:#e0d2ff;border-color:#e0d2ff;fill:#e0d2ff}.dashboard .server-overview md-grid-list.list-color-24 md-grid-tile.colored{background-color:#651fff}.dashboard .server-overview .color-25{background-color:#ffea00;fill:#ffea00;stroke:#ffea00}.dashboard .server-overview .color-max-25{background-color:#fff9b3;border-color:#fff9b3;fill:#fff9b3}.dashboard .server-overview md-grid-list.list-color-25 md-grid-tile.colored{background-color:#ffea00}.dashboard .server-overview .color-26{background-color:#00e5ff;fill:#00e5ff;stroke:#00e5ff}.dashboard .server-overview .color-max-26{background-color:#b3f7ff;border-color:#b3f7ff;fill:#b3f7ff}.dashboard .server-overview md-grid-list.list-color-26 md-grid-tile.colored{background-color:#00e5ff}.dashboard .server-overview .color-27{background-color:#ffc400;fill:#ffc400;stroke:#ffc400}.dashboard .server-overview .color-max-27{background-color:#ffedb3;border-color:#ffedb3;fill:#ffedb3}.dashboard .server-overview md-grid-list.list-color-27 md-grid-tile.colored{background-color:#ffc400}.dashboard .server-overview .color-28{background-color:#ff3d00;fill:#ff3d00;stroke:#ff3d00}.dashboard .server-overview .color-max-28{background-color:#ffc5b3;border-color:#ffc5b3;fill:#ffc5b3}.dashboard .server-overview md-grid-list.list-color-28 md-grid-tile.colored{background-color:#ff3d00}.dashboard .server-overview .color-29{background-color:#448aff;fill:#448aff;stroke:#448aff}.dashboard .server-overview .color-max-29{background-color:#f6faff;border-color:#f6faff;fill:#f6faff}.dashboard .server-overview md-grid-list.list-color-29 md-grid-tile.colored{background-color:#448aff}.dashboard .server-overview .color-30{background-color:#e040fb;fill:#e040fb;stroke:#e040fb}.dashboard .server-overview .color-max-30{background-color:#fcefff;border-color:#fcefff;fill:#fcefff}.dashboard .server-overview md-grid-list.list-color-30 md-grid-tile.colored{background-color:#e040fb}.dashboard .server-overview .color-31{background-color:#69f0ae;fill:#69f0ae;stroke:#69f0ae}.dashboard .server-overview .color-max-31{background-color:#fff;border-color:#fff;fill:#fff}.dashboard .server-overview md-grid-list.list-color-31 md-grid-tile.colored{background-color:#69f0ae}.dashboard .server-overview .color-32{background-color:#536dfe;fill:#536dfe;stroke:#536dfe}.dashboard .server-overview .color-max-32{background-color:#fff;border-color:#fff;fill:#fff}.dashboard .server-overview md-grid-list.list-color-32 md-grid-tile.colored{background-color:#536dfe}.dashboard .server-overview .color-33{background-color:#40c4ff;fill:#40c4ff;stroke:#40c4ff}.dashboard .server-overview .color-max-33{background-color:#f3fbff;border-color:#f3fbff;fill:#f3fbff}.dashboard .server-overview md-grid-list.list-color-33 md-grid-tile.colored{background-color:#40c4ff}.dashboard .server-overview .color-34{background-color:#ffab40;fill:#ffab40;stroke:#ffab40}.dashboard .server-overview .color-max-34{background-color:#fffaf3;border-color:#fffaf3;fill:#fffaf3}.dashboard .server-overview md-grid-list.list-color-34 md-grid-tile.colored{background-color:#ffab40}.dashboard .server-overview .color-35{background-color:#64ffda;fill:#64ffda;stroke:#64ffda}.dashboard .server-overview .color-max-35{background-color:#fff;border-color:#fff;fill:#fff}.dashboard .server-overview md-grid-list.list-color-35 md-grid-tile.colored{background-color:#64ffda}.dashboard .server-overview .color-36{background-color:#ff4081;fill:#ff4081;stroke:#ff4081}.dashboard .server-overview .color-max-36{background-color:#fff3f7;border-color:#fff3f7;fill:#fff3f7}.dashboard .server-overview md-grid-list.list-color-36 md-grid-tile.colored{background-color:#ff4081}.dashboard .server-overview .color-37{background-color:#b2ff59;fill:#b2ff59;stroke:#b2ff59}.dashboard .server-overview .color-max-37{background-color:#fff;border-color:#fff;fill:#fff}.dashboard .server-overview md-grid-list.list-color-37 md-grid-tile.colored{background-color:#b2ff59}.dashboard .server-overview .color-38{background-color:#7c4dff;fill:#7c4dff;stroke:#7c4dff}.dashboard .server-overview .color-max-38{background-color:#fff;border-color:#fff;fill:#fff}.dashboard .server-overview md-grid-list.list-color-38 md-grid-tile.colored{background-color:#7c4dff}.dashboard .server-overview .color-39{background-color:#ff0;fill:#ff0;stroke:#ff0}.dashboard .server-overview .color-max-39{background-color:#ffffb3;border-color:#ffffb3;fill:#ffffb3}.dashboard .server-overview md-grid-list.list-color-39 md-grid-tile.colored{background-color:#ff0}.dashboard .server-overview .color-40{background-color:#18ffff;fill:#18ffff;stroke:#18ffff}.dashboard .server-overview .color-max-40{background-color:#cbffff;border-color:#cbffff;fill:#cbffff}.dashboard .server-overview md-grid-list.list-color-40 md-grid-tile.colored{background-color:#18ffff}.dashboard .server-overview .color-41{background-color:#ffd740;fill:#ffd740;stroke:#ffd740}.dashboard .server-overview .color-max-41{background-color:#fffcf3;border-color:#fffcf3;fill:#fffcf3}.dashboard .server-overview md-grid-list.list-color-41 md-grid-tile.colored{background-color:#ffd740}.dashboard .server-overview .color-42{background-color:#ff6e40;fill:#ff6e40;stroke:#ff6e40}.dashboard .server-overview .color-max-42{background-color:#fff6f3;border-color:#fff6f3;fill:#fff6f3}.dashboard .server-overview md-grid-list.list-color-42 md-grid-tile.colored{background-color:#ff6e40}.dashboard .server-overview .color-warning{background-color:#ff9800!important;border-color:#ff9800!important;fill:#ff9800!important;stroke:#ff9800!important}.dashboard .server-overview .color-critical{background-color:#f44336!important;border-color:#f44336!important;fill:#f44336!important;stroke:#f44336!important}.dashboard .server-overview .status-waiting{background-color:#2e2e3b!important;border-color:#dad462!important;border-width:2px!important;border-style:solid!important}.dashboard .server-overview .status-terminated,.dashboard .server-overview .status-unknown{background-color:#ff1744!important;border-color:#e3002c!important;border-width:1px!important;border-style:solid!important}.dashboard .server-overview .color-1{background-color:#512DA8;border-color:#512DA8;fill:#512DA8;stroke:#512DA8}.dashboard .server-overview .color-2{background-color:#9C27B0;border-color:#9C27B0;fill:#9C27B0;stroke:#9C27B0}.dashboard .server-overview .color-3{background-color:#00BCD4;border-color:#00BCD4;fill:#00BCD4;stroke:#00BCD4}.dashboard .server-overview .color-max-1{background-color:#b6a2e6;border-color:#b6a2e6;fill:#b6a2e6}.dashboard .server-overview .color-max-2{background-color:#dfa0ea;border-color:#dfa0ea;fill:#dfa0ea}.dashboard .server-overview .color-max-3{background-color:#87f1ff;border-color:#87f1ff;fill:#87f1ff}.dashboard .server-overview .color-max-warning{background-color:#ffd699!important;border-color:#ffd699!important;fill:#ffd699!important}.dashboard .server-overview .color-max-critical{background-color:#fccbc7!important;border-color:#fccbc7!important;fill:#fccbc7!important}.dashboard .server-overview .max_tick_arc{stroke:#FFF!important}.dashboard .server-overview .concentricchart .bg-circle{background:#F9F9F9;fill:#F9F9F9;stroke:#FFF;stroke-width:1px}.dashboard .server-overview .concentricchart text{font-size:12px;font-family:Roboto,sans-serif}.dashboard .server-overview .concentricchart .value_group{fill:#fff}.dashboard .server-overview .concentricchart .legend_group rect{opacity:.8}.dashboard .server-overview svg.legend{height:auto}.dashboard .server-overview svg.legend text{font-size:12px;font-family:Roboto,sans-serif}.dashboard .server-overview svg.legend .hostName{font-size:16px}.dashboard .server-overview .minion-name{text-align:center;vertical-align:bottom;width:100%}.dashboard .server-overview .chart_area{width:325px;height:auto}.dashboard .groups{font-size:13px}.dashboard .groups .header{line-height:21px}.dashboard .groups .header a{padding-left:5px;padding-right:5px}.dashboard .groups .header .selector-area .filter-text{font-size:13px;margin-left:10px}.dashboard .groups .header .selector-area .cancel-button{width:18px;height:18px;padding:0}.dashboard .groups .header .selector-area .cancel-button:focus,.dashboard .groups .header .selector-area .cancel-button:hover{background-color:none!important}.dashboard .groups .header .selector-area .cancel-icon{width:15px;height:15px;fill:#777}.dashboard .groups .select-group-by{min-width:110px;margin-left:10px;margin-right:40px}.dashboard .groups .select-group-by .md-select-label{padding-top:6px;font-size:13px}.dashboard .groups .group-item{padding-top:20px}.dashboard .groups .group-item .filter-button{height:18px;width:18px}.dashboard .groups .group-item .filter-button .filter-icon{width:18px;height:18px}.dashboard .groups .icon-area{min-width:34px}.dashboard .groups .icon-area .group-icon{border-radius:21px;width:21px;height:21px}.dashboard .groups .group-main-area .subtype{line-height:21px}.dashboard .groups md-divider{margin-top:40px;margin-bottom:30px}.dashboard .groups .group-name{padding-top:10px}.dashboard .groups .selectFilter{padding-top:7px;margin-right:30px}.dashboard .groups .selectFilter .md-select-label{border-bottom:none!important;width:17px;min-width:17px;padding-right:0}.dashboard .groups md-select-menu{min-height:40px;max-height:40px}.dashboard .groups .group-link-area{padding-left:15px;padding-bottom:15px}.dashboard .groups .group-link-area button{line-height:12px}.dashboard .groups .group-type-circle{width:21px;height:21px}.dashboard .groups md-select{margin-top:0}.dashboard .detail{color:#222}.dashboard .detail .back{font-size:18px;line-height:27px;margin-bottom:30px}.dashboard .detail .heading{font-size:18px;line-height:21px;color:#222;margin-bottom:25px}.dashboard .detail .heading .label{color:#777}.dashboard .detail td.name{font-size:14px;color:#222;line-height:24px}.dashboard .detail td.value{margin-left:50px;font-size:14px;color:#888;line-height:24px}.dashboard .detail .containerTable td{padding-right:20px}.dashboard .align-top tbody{vertical-align:top}`) - -func www_app_assets_css_app_css_bytes() ([]byte, error) { - return _www_app_assets_css_app_css, nil -} - -func www_app_assets_css_app_css() (*asset, error) { - bytes, err := www_app_assets_css_app_css_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/css/app.css", size: 39855, mode: os.FileMode(416), modTime: time.Unix(1436215736, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_img_docarrow_png = []byte("\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00!\x00\x00\x00\"\b\x06\x00\x00\x00\xd1p\xb0\xc1\x00\x00\x00\x04sBIT\b\b\b\b|\bd\x88\x00\x00\x00\tpHYs\x00\x00\x15\xfd\x00\x00\x15\xfd\x01\xcdpQa\x00\x00\x00\x1ctEXtSoftware\x00Adobe Fireworks CS6輲\x8c\x00\x00\x00\xefIDATX\x85\xd5\xd71\x0e\xc20\f\x05І\xebq\x0568\x01\x8c\x1c\x80\xeep\x1aV\x18Y`\x05\xc1\x19\x10e\x81\xe13\x05UU\xab\xd8\xf1\xb7\xa2~\xc9K\x87\xf4)\x8e\xea4\x00\xa8JgR\x1aPUcB\x84\x10\xfeU\xef.X\xac\x8eh?KU2\x00\x92\x15\xb3ٞ\x01\x00\xaf\xe6\x83\xf9\xf2 >L\xc9\xf5\xa5\x88\b\x88\xd1@(\x88u}B_\xa4\x10\nb:\xdb\xe3\xf6xfCh\xed\xb0@h\b\v\x84\x8aȅ\xd0\x119\x10\x17\x84\x16\xe2\x86\xd0@\\\x11R\x88;\x82\x01\xa1 \xac\x10\xea(\x1f\xf2&')\xab\x1d\xd7{\xff.4\xef\xaf\u007f;\xac\x003B\x02\x90\xec\xb6\xe9c%\x01\xb8!4\x00\x17\x84\x16@G\xe4\x00\xa8\x88\\\x00\ra\x01\xd0\x10C\x17]\t\x80ڎ\xee\x95_\n\xa0\"\xda\x10\r\x80\x8e\x88\x10\r@\x82\bݗ\x94\xc8x\xfeʽ\xf3\x03\xba\v\x18\x94\x12\x8b\x872\x00\x00\x00\x00IEND\xaeB`\x82") - -func www_app_assets_img_docarrow_png_bytes() ([]byte, error) { - return _www_app_assets_img_docarrow_png, nil -} - -func www_app_assets_img_docarrow_png() (*asset, error) { - bytes, err := www_app_assets_img_docarrow_png_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/img/docArrow.png", size: 373, mode: os.FileMode(416), modTime: time.Unix(1430167784, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_img_ic_arrow_drop_down_24px_svg = []byte(` - - - -`) - -func www_app_assets_img_ic_arrow_drop_down_24px_svg_bytes() ([]byte, error) { - return _www_app_assets_img_ic_arrow_drop_down_24px_svg, nil -} - -func www_app_assets_img_ic_arrow_drop_down_24px_svg() (*asset, error) { - bytes, err := www_app_assets_img_ic_arrow_drop_down_24px_svg_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/img/ic_arrow_drop_down_24px.svg", size: 166, mode: os.FileMode(416), modTime: time.Unix(1433423161, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_img_ic_arrow_drop_up_24px_svg = []byte(` - - - - - - - - - - - - - - - - - - - - - - - -`) - -func www_app_assets_img_ic_arrow_drop_up_24px_svg_bytes() ([]byte, error) { - return _www_app_assets_img_ic_arrow_drop_up_24px_svg, nil -} - -func www_app_assets_img_ic_arrow_drop_up_24px_svg() (*asset, error) { - bytes, err := www_app_assets_img_ic_arrow_drop_up_24px_svg_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/img/ic_arrow_drop_up_24px.svg", size: 795, mode: os.FileMode(416), modTime: time.Unix(1433423161, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_img_ic_keyboard_arrow_left_24px_svg = []byte(``) - -func www_app_assets_img_ic_keyboard_arrow_left_24px_svg_bytes() ([]byte, error) { - return _www_app_assets_img_ic_keyboard_arrow_left_24px_svg, nil -} - -func www_app_assets_img_ic_keyboard_arrow_left_24px_svg() (*asset, error) { - bytes, err := www_app_assets_img_ic_keyboard_arrow_left_24px_svg_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/img/ic_keyboard_arrow_left_24px.svg", size: 151, mode: os.FileMode(416), modTime: time.Unix(1433423161, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_img_ic_keyboard_arrow_right_24px_svg = []byte(``) - -func www_app_assets_img_ic_keyboard_arrow_right_24px_svg_bytes() ([]byte, error) { - return _www_app_assets_img_ic_keyboard_arrow_right_24px_svg, nil -} - -func www_app_assets_img_ic_keyboard_arrow_right_24px_svg() (*asset, error) { - bytes, err := www_app_assets_img_ic_keyboard_arrow_right_24px_svg_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/img/ic_keyboard_arrow_right_24px.svg", size: 149, mode: os.FileMode(416), modTime: time.Unix(1433423161, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_img_icons_arrow_back_png = []byte("\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x80\x00\x00\x00\x80\b\x06\x00\x00\x00\xc3>a\xcb\x00\x00\x00\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00\x020IDATx\x9c\xed\xddIn\x13q\x10F\xf1ׄ\x05\xd7\xe0f\t\xc3\x166\x1c\xc0\x10\xa60\xc5!\x90\x046\x84Ab\xba\v7r`aY2\x02B\xecj\xf7_\xd5\xf5~\x92\x97\x91Jz_za\xc96H\x92$I\x92$I\x92$I\x92$I\x92$I\x92\xa4\xac\xb6Z\x1f\x90\xdc\x1ep\x15\xf8\xd1\xfa\x10\r\xab\x03\xde\x00?\x813\xe0V\xdbs4\xa4\xe5\xf8\x8b\x97#(\xa2\x03N\xf8=\xbe#(\xa2\x03\xa6\xfc=\xfe\xf2\bn\xb7:P\x9bs\x91\xf8\x8e`\xa4V\x89\xef\bF\xa6\x03\xf6Y-\xbe#\x18\x91\x87\xac\x17\u007f\xf1:\x1a\xfed\xf5e\xdd\xff\xfc\xc5k\xca\xfc\t\xa2\x84\xa2\xf1\x0f0~Z\xc6/,\x1a\xff%\xc6O\xeb\x05\xc6/+\x1a\xff\x10\xe3\xa7e\xfc\u008c_\xd8sb\xf1_a\xfc\xb4\x8c_X4\xfek\x8c\x9f\x96\xf1\v3~aψ\xc5?\xc2\xf8i\x19\xbf0\xe3\x17\x16\x8d\u007f\x8c\xf1\xd3z\x8a\xf1ˊ\xc6?\xc1\xf8iE\xe3\x9f\x02\x97\x86>Z\xfd0~aO0~Y\xd1\xf8\xef1~Z}\xc4\xf7;\x12\x922~a{\xc4\xe2\u007f\xc0\xf8i\x19\xbf\xb0h\xfc\x8f\x18?-\xe3\x17\xf6\x18\xe3\x975!\x16\xff\x13\xc6\xff\xa7\fo\x80\\\t\xfe\xfd\x8c\xf9\x10\x94\u0604\xd8S\xe0;py\xe8\xa3կ\t\x8e\xa0\xbc\t\xb1\x11|\xc3\x11\xa4w\x17GP\x9e#\x90#\x90#\x10p\x0fGP^t\x04_q\x04\xe99\x029\x02\xc1.\x8e\xa0\x8e\xa0x\xabsDG\xf0\x0eG\x90Z\xc7\xfc\xeb\xe2##\xf0\xe7\xe3G`\xdd'\xc1\f\xd8\x1e\xfe\\mª_Qc\xfc\x11\xba\xe8\bf\xc0N\xa3\x1b\xb5A\x1d0\xe5\xff\xf1\xaf\xb5:P\x9bw\xde\bf\xc0\xf5v\xa7i(\x1dp\xc0\x9f\xf1o\xb4 \xf7#U\x14\x00\x00\x02\xf4IDATx\xda|SkHSa\x18~\xceٙ\xd3m\xce\xcd\xcdL\x99I\xf7D\xa2?QXYBBZ\x19i\xa8\xe4\r\xaa\x95\x18*\x95B\xa4T&\bQZa\x96\x81\x05I\x14R\x96\x81H\x17B\xbbHY\x16d\x14\xa5\xa2&\xe4e\xe66\xddڙ\xbb\x9c\xad\xef\x9cyL\xff\xf4\xfd\xfa.\xcf\xf3\xbc\xcfy\xde\xf7P\x98\xb7|>\x9f\xba\u007f\xd4}\xd1h\xf1&5<\xb5\xe9\xbf\x0e\xbb\x85\xfb\xd8%R\x18\x92\x94\xa3a!\x92\xe71Q\xd2R\x8a\xa2L\"\x87\x9a%ꆌ\x9e\x9a\x91I.\xf1z\x9b-\xb2\xf7\x97\x9f\xa8\x92\xd3\b`\x80I\xabW8\xaf\xd6Kq$Yi\x8c\xd0H\xdaɾ\x98\bMR&+\x1778\xeeyx\xa1y:b`\xcc3\xdf\x106\xc5\xc8\x10\xa9\x95\xa0\xb9\x93]p\xbfl1\x83\x924\xd5D\xb8F\x92N\xf5\x8d\xb8\x9e\x1c\xbclJb\x9d\xbe\x05\xa0\xd8h)\xf6m\x96#(\x80B\xd3k\x16=\x83\xae\x05\xef\xfc\xfd\x8d\"\xed\v\xc6\xe6\xf0\xe9Er}a(\xeaZm0\xecPb\xdd\xd2\x00\x98\xff\xf8\xadW\x1fҀwW\xd7j\xc5\xf1T\x15\xf2\xaf\x9a\xe0p\xf9`c\xbdzz\xcc\xcciE\xd5\xf2\xc6)\xd4\x15\x84B\xafc\xb0\xeb\xec\x04\xda{f\xd0\xf5݉\xdd\x15\x13$\x0f\n7\x8fiQF0\x1eΏ\x1f1q:\xa6\xeb\x87S'\n\x90\x94A\x1c\x91\xe0(T\xe6\xaa!\x93R\xc2\xfe\\\x8e\x1a\xc1$\xd0q3G\xc4%0Z\xfc\n\xdd}N-\xf3y\xc0%\x15\x056\xac\n@\xdb\a\a\x1et\xdaq\xfb\x84\x0er\x19E:\x04\xc1\xae\xe1\x8a\t)\x1b\x83\x84`?\xf5\xfb\xf3\xe8\x19rS̨\x99\x9b\v\x86\xaf\x12\x1dƠ\"[\x8dp\xb5\x04\x8f߱Į\x0f\xe9\xf1\n\x9c\xca\b\x81\xc7\xebô\xdd;\x87\xff=́\x11\xfb}\xfe\x80ZH\x96'\xde{i\x17B\xcbۮ\x10\x80w;\xec\xe0\ve%(0E\x82\xad1hp\xa9\xc5\xcag\xe0\x17\xb0\xb2^\x1c\xbdf\x16,7\x97\x87\xe1}\xaf\v\xfb\x13\xe4h\xebv\x80#\x0e\xb4*\x1a-oY\xe4'+q\xb8\xd62\x97\x01\xbf\x98\x8cx9{\xff\r+\xe7\x0f|;\xab\x9a\xa6Q[\xa0Ap\x10\x8d\xbc\xeaIp\xc4q\xd3I\x1d֯\x94\tU\xe7\x93\xf7\xc6ɝ\xd4O\xa3\xfb\xd9\xe9;S\x89߆ݴ\xf8@D\x91\xb9U\x01\x9dJ\x02\x8a\f\xfb\x04\xf9V\xbe\x9dՏ\xacs\xe45QRT\xe6\xa8;\x98\xe8ELjY\x9a\xac\xb7\xb0\x81\xd3[f\ag\xdb\xda@\xe4\x92\xea\xe2\x80\xf1\"\xb7\xc8\fФ\x84\xd7\xeb\xcf\xecLV\xc8\xe0\xf2\b&\x85&?\x04\xfb\xf1nmiU\xb6\xc2L\xd3\xff\x06j\xfeh\xf3\xad,i\xb0\bd\x1eS\x95\xab\xb4\x90\xb0w\x12\xae\x9d\x12A#&O\xe6\xab/3\xf5Ħ\x06\xffY\xc5{\x82m[b\x03\x8bVDJ\x1b\xf9\xf3_\x01\x06\x00\xf19?q\xaaE\xa0\xa4\x00\x00\x00\x00IEND\xaeB`\x82") - -func www_app_assets_img_icons_favicon_png_bytes() ([]byte, error) { - return _www_app_assets_img_icons_favicon_png, nil -} - -func www_app_assets_img_icons_favicon_png() (*asset, error) { - bytes, err := www_app_assets_img_icons_favicon_png_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/img/icons/favicon.png", size: 1663, mode: os.FileMode(416), modTime: time.Unix(1430167784, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_img_icons_ic_arrow_forward_24px_svg = []byte(``) - -func www_app_assets_img_icons_ic_arrow_forward_24px_svg_bytes() ([]byte, error) { - return _www_app_assets_img_icons_ic_arrow_forward_24px_svg, nil -} - -func www_app_assets_img_icons_ic_arrow_forward_24px_svg() (*asset, error) { - bytes, err := www_app_assets_img_icons_ic_arrow_forward_24px_svg_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/img/icons/ic_arrow_forward_24px.svg", size: 158, mode: os.FileMode(416), modTime: time.Unix(1430167784, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_img_icons_ic_cancel_24px_svg = []byte(``) - -func www_app_assets_img_icons_ic_cancel_24px_svg_bytes() ([]byte, error) { - return _www_app_assets_img_icons_ic_cancel_24px_svg, nil -} - -func www_app_assets_img_icons_ic_cancel_24px_svg() (*asset, error) { - bytes, err := www_app_assets_img_icons_ic_cancel_24px_svg_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/img/icons/ic_cancel_24px.svg", size: 276, mode: os.FileMode(416), modTime: time.Unix(1430167784, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_img_icons_ic_close_24px_svg = []byte(``) - -func www_app_assets_img_icons_ic_close_24px_svg_bytes() ([]byte, error) { - return _www_app_assets_img_icons_ic_close_24px_svg, nil -} - -func www_app_assets_img_icons_ic_close_24px_svg() (*asset, error) { - bytes, err := www_app_assets_img_icons_ic_close_24px_svg_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/img/icons/ic_close_24px.svg", size: 202, mode: os.FileMode(416), modTime: time.Unix(1430167784, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_img_icons_ic_menu_svg = []byte(` - - - - - - - - -`) - -func www_app_assets_img_icons_ic_menu_svg_bytes() ([]byte, error) { - return _www_app_assets_img_icons_ic_menu_svg, nil -} - -func www_app_assets_img_icons_ic_menu_svg() (*asset, error) { - bytes, err := www_app_assets_img_icons_ic_menu_svg_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/img/icons/ic_menu.svg", size: 791, mode: os.FileMode(416), modTime: time.Unix(1430167784, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_img_icons_ic_menu_24px_svg = []byte(` - - - - - - - - - - - - - - - - - - - - - -`) - -func www_app_assets_img_icons_ic_menu_24px_svg_bytes() ([]byte, error) { - return _www_app_assets_img_icons_ic_menu_24px_svg, nil -} - -func www_app_assets_img_icons_ic_menu_24px_svg() (*asset, error) { - bytes, err := www_app_assets_img_icons_ic_menu_24px_svg_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/img/icons/ic_menu_24px.svg", size: 841, mode: os.FileMode(416), modTime: time.Unix(1430167784, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_img_icons_list_control_down_png = []byte("\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x000\x00\x00\x000\b\x03\x00\x00\x00`\xdc\t\xb5\x00\x00\x00\x19tEXtSoftware\x00Adobe ImageReadyq\xc9e<\x00\x00\x00'PLTE\xa8\xa8\xa8\xfc\xfc\xfc\xc0\xc0\xc0\xb6\xb6\xb6\xf7\xf7\xf7\xaa\xaa\xaa\xf6\xf6\xf6\xe6\xe6\xe6\xe8\xe8赵\xb5\xc3\xc3\xc3\xe5\xe5\xe5\xff\xff\xffZLu\xde\x00\x00\x00\rtRNS\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00=\xe8\"\x86\x00\x00\x00\x8bIDATx\xda\xec\xd4I\x12\x80 \fD\xd1\x04\x04\x9c\xee\u007f^ˁ\xd2`\xb7\x96k\xc3\xd2\xfao\xa1\t\xca\xfc\xf1\x88\x03\a\xbf\x01}\xd7\x06\xb9\u007f\x02S\x8a\x8d\xc8C*\x1c\x94$bE\x1eD\xac0`\x14\xb1\"\xc7\xf5\xc9H\x81\x06+\xba\xad\x0f\xca\xdf\xc1\nԷ_\xe9*`\u007f\x9b\xc3)p\u007f\x1f\\\x15\xa4\a\x93>\x04\xe9\xd1j\xec\x82\xf4p\x97\xaa@=^\xbe]\xc0\x9el\xeb*p\xcf\xd6[\x03\xe9\xe9}P\xf5\x9f\x80\x03\a\xafg\x11`\x00\xb0\xe4e\a\x17\x87\xea}\x00\x00\x00\x00IEND\xaeB`\x82") - -func www_app_assets_img_icons_list_control_down_png_bytes() ([]byte, error) { - return _www_app_assets_img_icons_list_control_down_png, nil -} - -func www_app_assets_img_icons_list_control_down_png() (*asset, error) { - bytes, err := www_app_assets_img_icons_list_control_down_png_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/img/icons/list_control_down.png", size: 309, mode: os.FileMode(416), modTime: time.Unix(1430167784, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_img_kubernetes_svg = []byte(` - - - - -`) - -func www_app_assets_img_kubernetes_svg_bytes() ([]byte, error) { - return _www_app_assets_img_kubernetes_svg, nil -} - -func www_app_assets_img_kubernetes_svg() (*asset, error) { - bytes, err := www_app_assets_img_kubernetes_svg_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/img/kubernetes.svg", size: 11663, mode: os.FileMode(416), modTime: time.Unix(1430167784, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_js_app_js = []byte(`var componentNamespaces = ["kubernetesApp.components.dashboard"]; -// APP START -// **************************** -// /www/app/assets/app.js is autogenerated. Do not modify. -// Changes should be made in /master/modules/js or /master/components//js -// **************************** -// ----------------------------------- - -var app = angular.module('kubernetesApp', [ - 'ngRoute', - 'ngMaterial', - 'ngLodash', - 'door3.css', - 'kubernetesApp.config', - 'kubernetesApp.services', - 'angular.filter' -].concat(componentNamespaces)); - -app.factory('menu', [ - '$location', - '$rootScope', - 'sections', - '$route', - function($location, $rootScope, sections, $route) { - - var self; - - $rootScope.$on('$locationChangeSuccess', onLocationChange); - - return self = { - - sections: sections, - - setSections: function(_sections) { this.sections = _sections; }, - selectSection: function(section) { self.openedSection = section; }, - toggleSelectSection: function(section) { - self.openedSection = (self.openedSection === section ? null : section); - }, - isSectionSelected: function(section) { return self.openedSection === section; }, - selectPage: function(section, page) { - self.currentSection = section; - self.currentPage = page; - }, - isPageSelected: function(page) { return self.currentPage === page; } - }; - - function onLocationChange() { - var path = $route.current.originalPath; - - var matchPage = function(section, page) { - if (path === page.url || path === (page.url + '/')) { - self.selectSection(section); - self.selectPage(section, page); - } - }; - - sections.forEach(function(section) { - if (section.children) { - section.children.forEach(function(childSection) { - if (childSection.pages) { - childSection.pages.forEach(function(page) { matchPage(childSection, page); }); - } - }); - } else if (section.pages) { - section.pages.forEach(function(page) { matchPage(section, page); }); - } else if (section.type === 'link') { - matchPage(section, section); - } - }); - } - } -]); - -angular.module('kubernetesApp.config', []); -angular.module('kubernetesApp.services', ['kubernetesApp.config']); - -app.config([ - '$routeProvider', - function($routeProvider) { - $routeProvider.when("/404", {templateUrl: "views/partials/404.html"}) - // else 404 - .otherwise({redirectTo: "/404"}); - } -]) - .config([ - '$routeProvider', - 'manifestRoutes', - function($routeProvider, manifestRoutes) { - angular.forEach(manifestRoutes, function(r) { - var route = { - templateUrl: r.templateUrl - }; - if (r.controller) { - route.controller = r.controller; - } - if (r.css) { - route.css = r.css; - } - $routeProvider.when(r.url, route); - }); - } - ]); - -app.value("sections", [{"name":"Dashboard","url":"/dashboard","type":"link","templateUrl":"/components/dashboard/pages/home.html"},{"name":"Dashboard","type":"heading","children":[{"name":"Dashboard","type":"toggle","url":"/dashboard","templateUrl":"/components/dashboard/pages/home.html","pages":[{"name":"Pods","url":"/dashboard/pods","templateUrl":"/components/dashboard/views/listPods.html","type":"link"},{"name":"Pod Visualizer","url":"/dashboard/visualpods","templateUrl":"/components/dashboard/views/listPodsVisualizer.html","type":"link"},{"name":"Services","url":"/dashboard/services","templateUrl":"/components/dashboard/views/listServices.html","type":"link"},{"name":"Replication Controllers","url":"/dashboard/replicationcontrollers","templateUrl":"/components/dashboard/views/listReplicationControllers.html","type":"link"},{"name":"Events","url":"/dashboard/events","templateUrl":"/components/dashboard/views/listEvents.html","type":"link"},{"name":"Nodes","url":"/dashboard/nodes","templateUrl":"/components/dashboard/views/listMinions.html","type":"link"},{"name":"Replication Controller","url":"/dashboard/replicationcontrollers/:replicationControllerId","templateUrl":"/components/dashboard/views/replication.html","type":"link"},{"name":"Service","url":"/dashboard/services/:serviceId","templateUrl":"/components/dashboard/views/service.html","type":"link"},{"name": "Node","url": "/dashboard/nodes/:nodeId","templateUrl": "/components/dashboard/views/node.html","type": "link"},{"name":"Explore","url":"/dashboard/groups/:grouping*?/selector/:selector*?","templateUrl":"/components/dashboard/views/groups.html","type":"link"},{"name":"Pod","url":"/dashboard/pods/:podId","templateUrl":"/components/dashboard/views/pod.html","type":"link"}]}]},{"name":"Graph","url":"/graph","type":"link","templateUrl":"/components/graph/pages/home.html"},{"name":"Graph","url":"/graph/inspect","type":"link","templateUrl":"/components/graph/pages/inspect.html","css":"/components/graph/css/show-details-table.css"},{"name":"Graph","type":"heading","children":[{"name":"Graph","type":"toggle","url":"/graph","templateUrl":"/components/graph/pages/home.html","pages":[{"name":"Test","url":"/graph/test","type":"link","templateUrl":"/components/graph/pages/home.html"}]}]}]); - -app.directive('includeReplace', - function() { - 'use strict'; - return { - require: 'ngInclude', - restrict: 'A', /* optional */ - link: function(scope, el, attrs) { el.replaceWith(el.children()); } - }; - }) - .directive('compile', - ["$compile", function($compile) { - 'use strict'; - return function(scope, element, attrs) { - scope.$watch(function(scope) { return scope.$eval(attrs.compile); }, - function(value) { - element.html(value); - $compile(element.contents())(scope); - }); - }; - }]) - .directive("kubernetesUiMenu", - function() { - 'use strict'; - return { - templateUrl: "views/partials/kubernetes-ui-menu.tmpl.html" - }; - }) - .directive('menuToggle', function() { - 'use strict'; - return { - scope: {section: '='}, - templateUrl: 'views/partials/menu-toggle.tmpl.html', - link: function($scope, $element) { - var controller = $element.parent().controller(); - - $scope.isOpen = function() { return controller.isOpen($scope.section); }; - $scope.toggle = function() { controller.toggleOpen($scope.section); }; - - var parentNode = $element[0].parentNode.parentNode.parentNode; - if (parentNode.classList.contains('parent-list-item')) { - var heading = parentNode.querySelector('h2'); - $element[0].firstChild.setAttribute('aria-describedby', heading.id); - } - } - }; - }); - -app.filter('startFrom', - function() { - 'use strict'; - return function(input, start) { return input.slice(start); }; - }) - .filter('nospace', function() { - 'use strict'; - return function(value) { return (!value) ? '' : value.replace(/ /g, ''); }; - }); - -app.run(['$route', angular.noop]) - .run(["lodash", function(lodash) { - // Alias lodash - window['_'] = lodash; - }]); - -app.service('SidebarService', [ - '$rootScope', - function($rootScope) { - var service = this; - service.sidebarItems = []; - - service.clearSidebarItems = function() { service.sidebarItems = []; }; - - service.renderSidebar = function() { - var _entries = ''; - service.sidebarItems.forEach(function(entry) { _entries += entry.Html; }); - - if (_entries) { - $rootScope.sidenavLeft = '
' + _entries + '
'; - } - }; - - service.addSidebarItem = function(item) { - - service.sidebarItems.push(item); - - service.sidebarItems.sort(function(a, b) { return (a.order > b.order) ? 1 : ((b.order > a.order) ? -1 : 0); }); - }; - } -]); - - -app.value("tabs", [{"component":"dashboard","title":"Dashboard"}]); -app.constant("manifestRoutes", [{"description":"Dashboard visualization.","url":"/dashboard/","templateUrl":"components/dashboard/pages/home.html"},{"description":"Pods","url":"/dashboard/pods","templateUrl":"components/dashboard/views/listPods.html"},{"description":"Pod Visualizer","url":"/dashboard/visualpods","templateUrl":"components/dashboard/views/listPodsVisualizer.html"},{"description":"Services","url":"/dashboard/services","templateUrl":"components/dashboard/views/listServices.html"},{"description":"Replication Controllers","url":"/dashboard/replicationcontrollers","templateUrl":"components/dashboard/views/listReplicationControllers.html"},{"description":"Events","url":"/dashboard/events","templateUrl":"components/dashboard/views/listEvents.html"},{"description":"Nodes","url":"/dashboard/nodes","templateUrl":"components/dashboard/views/listMinions.html"},{"description":"Replication Controller","url":"/dashboard/replicationcontrollers/:replicationControllerId","templateUrl":"components/dashboard/views/replication.html"},{"description":"Service","url":"/dashboard/services/:serviceId","templateUrl":"components/dashboard/views/service.html"},{"description":"Node","url":"/dashboard/nodes/:nodeId","templateUrl":"components/dashboard/views/node.html"},{"description":"Explore","url":"/dashboard/groups/:grouping*?/selector/:selector*?","templateUrl":"components/dashboard/views/groups.html"},{"description":"Pod","url":"/dashboard/pods/:podId","templateUrl":"components/dashboard/views/pod.html"}]); - -angular.module("kubernetesApp.config", []) - -.constant("ENV", { - "/": { - "k8sApiServer": "/api/v1", - "k8sDataServer": "", - "k8sDataPollMinIntervalSec": 10, - "k8sDataPollMaxIntervalSec": 120, - "k8sDataPollErrorThreshold": 5, - "cAdvisorProxy": "", - "cAdvisorPort": "4194" - } -}) - -.constant("ngConstant", true) - -; -/**========================================================= - * Module: config.js - * App routes and resources configuration - =========================================================*/ -/**========================================================= - * Module: constants.js - * Define constants to inject across the application - =========================================================*/ -/**========================================================= - * Module: home-page.js - * Page Controller - =========================================================*/ - -app.controller('PageCtrl', [ - '$scope', - '$timeout', - '$mdSidenav', - 'menu', - '$rootScope', - function($scope, $timeout, $mdSidenav, menu, $rootScope) { - $scope.menu = menu; - - $scope.path = path; - $scope.goHome = goHome; - $scope.openMenu = openMenu; - $rootScope.openMenu = openMenu; - $scope.closeMenu = closeMenu; - $scope.isSectionSelected = isSectionSelected; - - $rootScope.$on('$locationChangeSuccess', openPage); - - // Methods used by menuLink and menuToggle directives - this.isOpen = isOpen; - this.isSelected = isSelected; - this.toggleOpen = toggleOpen; - this.shouldLockOpen = shouldLockOpen; - $scope.toggleKubernetesUiMenu = toggleKubernetesUiMenu; - - var mainContentArea = document.querySelector("[role='main']"); - var kubernetesUiMenu = document.querySelector("[role='kubernetes-ui-menu']"); - - // ********************* - // Internal methods - // ********************* - - var _t = false; - - $scope.showKubernetesUiMenu = false; - - function shouldLockOpen() { - return _t; - } - - function toggleKubernetesUiMenu() { - $scope.showKubernetesUiMenu = !$scope.showKubernetesUiMenu; - } - - function closeMenu() { - $timeout(function() { - $mdSidenav('left').close(); - }); - } - - function openMenu() { - $timeout(function() { - _t = !$mdSidenav('left').isOpen(); - $mdSidenav('left').toggle(); - }); - } - - function path() { - return $location.path(); - } - - function goHome($event) { - menu.selectPage(null, null); - $location.path( '/' ); - } - - function openPage() { - $scope.closeMenu(); - mainContentArea.focus(); - } - - function isSelected(page) { - return menu.isPageSelected(page); - } - - function isSectionSelected(section) { - var selected = false; - var openedSection = menu.openedSection; - if(openedSection === section){ - selected = true; - } - else if(section.children) { - section.children.forEach(function(childSection) { - if(childSection === openedSection){ - selected = true; - } - }); - } - return selected; - } - - function isOpen(section) { - return menu.isSectionSelected(section); - } - - function toggleOpen(section) { - menu.toggleSelectSection(section); - } - - } -]).filter('humanizeDoc', function() { - return function(doc) { - if (!doc) return; - if (doc.type === 'directive') { - return doc.name.replace(/([A-Z])/g, function($1) { - return '-'+$1.toLowerCase(); - }); - } - return doc.label || doc.name; - }; }); - -/**========================================================= - * Module: main.js - * Main Application Controller - =========================================================*/ -/**========================================================= - * Module: tabs-global.js - * Page Controller - =========================================================*/ - -app.controller('TabCtrl', [ - '$scope', - '$location', - 'tabs', - function($scope, $location, tabs) { - $scope.tabs = tabs; - - $scope.switchTab = function(index) { - var location_path = $location.path(); - var tab = tabs[index]; - - if (tab) { - var path = '/%s'.format(tab.component); - if (location_path.indexOf(path) == -1) { - $location.path(path); - } - } - }; - } -]); - -/**========================================================= - * Module: sidebar.js - * Wraps the sidebar and handles collapsed state - =========================================================*/ -(function() { - "use strict"; - - angular.module('kubernetesApp.services') - .service('cAdvisorService', ["$http", "$q", "ENV", function($http, $q, ENV) { - var _baseUrl = function(minionIp) { - var minionPort = ENV['/']['cAdvisorPort'] || "8081"; - var proxy = ENV['/']['cAdvisorProxy'] || "/api/v1/proxy/nodes/"; - - return proxy + minionIp + ':' + minionPort + '/api/v1.0/'; - }; - - this.getMachineInfo = getMachineInfo; - - function getMachineInfo(minionIp) { - var fullUrl = _baseUrl(minionIp) + 'machine'; - var deferred = $q.defer(); - - // hack - $http.get(fullUrl).success(function(data) { - deferred.resolve(data); - }).error(function(data, status) { deferred.reject('There was an error') }); - return deferred.promise; - } - - this.getContainerInfo = getContainerInfo; - // containerId optional - function getContainerInfo(minionIp, containerId) { - containerId = (typeof containerId === "undefined") ? "/" : containerId; - - var fullUrl = _baseUrl(minionIp) + 'containers' + containerId; - var deferred = $q.defer(); - - var request = { - "num_stats": 10, - "num_samples": 0 - }; - - $http.post(fullUrl, request) - .success(function(data) { deferred.resolve(data); }) - .error(function() { deferred.reject('There was an error') }); - return deferred.promise; - } - - this.getDataForMinion = function(minionIp) { - var machineData, containerData; - var deferred = $q.defer(); - - var p = $q.all([getMachineInfo(minionIp), getContainerInfo(minionIp)]) - .then( - function(dataArray) { - machineData = dataArray[0]; - containerData = dataArray[1]; - - var memoryData = parseMemory(machineData, containerData); - var cpuData = parseCpu(machineData, containerData); - var fsData = parseFilesystems(machineData, containerData); - deferred.resolve({ - memoryData: memoryData, - cpuData: cpuData, - filesystemData: fsData, - machineData: machineData, - containerData: containerData - }); - - }, - function(errorData) { deferred.reject(errorData); }); - - return deferred.promise; - }; - - // Utils to process cadvisor data - function humanize(num, size, units) { - var unit; - for (unit = units.pop(); units.length && num >= size; unit = units.pop()) { - num /= size; - } - return [num, unit]; - } - - // Following the IEC naming convention - function humanizeIEC(num) { - var ret = humanize(num, 1024, ["TiB", "GiB", "MiB", "KiB", "Bytes"]); - return ret[0].toFixed(2) + " " + ret[1]; - } - - // Following the Metric naming convention - function humanizeMetric(num) { - var ret = humanize(num, 1000, ["TB", "GB", "MB", "KB", "Bytes"]); - return ret[0].toFixed(2) + " " + ret[1]; - } - - function hasResource(stats, resource) { return stats.stats.length > 0 && stats.stats[0][resource]; } - - // Gets the length of the interval in nanoseconds. - function getInterval(current, previous) { - var cur = new Date(current); - var prev = new Date(previous); - - // ms -> ns. - return (cur.getTime() - prev.getTime()) * 1000000; - } - - function parseCpu(machineInfo, containerInfo) { - var cur = containerInfo.stats[containerInfo.stats.length - 1]; - var results = []; - - var cpuUsage = 0; - if (containerInfo.spec.has_cpu && containerInfo.stats.length >= 2) { - var prev = containerInfo.stats[containerInfo.stats.length - 2]; - var rawUsage = cur.cpu.usage.total - prev.cpu.usage.total; - var intervalInNs = getInterval(cur.timestamp, prev.timestamp); - - // Convert to millicores and take the percentage - cpuUsage = Math.round(((rawUsage / intervalInNs) / machineInfo.num_cores) * 100); - if (cpuUsage > 100) { - cpuUsage = 100; - } - } - - return { - cpuPercentUsage: cpuUsage - }; - } - - function parseFilesystems(machineInfo, containerInfo) { - var cur = containerInfo.stats[containerInfo.stats.length - 1]; - if (!cur.filesystem) { - return; - } - - var filesystemData = []; - for (var i = 0; i < cur.filesystem.length; i++) { - var data = cur.filesystem[i]; - var totalUsage = Math.floor((data.usage * 100.0) / data.capacity); - - var f = { - device: data.device, - filesystemNumber: i + 1, - usage: data.usage, - usageDescription: humanizeMetric(data.usage), - capacity: data.capacity, - capacityDescription: humanizeMetric(data.capacity), - totalUsage: Math.floor((data.usage * 100.0) / data.capacity) - }; - - filesystemData.push(f); - } - return filesystemData; - } - - var oneMegabyte = 1024 * 1024; - var oneGigabyte = 1024 * oneMegabyte; - - function parseMemory(machineInfo, containerInfo) { - if (containerInfo.spec.has_memory && !hasResource(containerInfo, "memory")) { - return; - } - - // var titles = ["Time", "Total", "Hot"]; - var data = []; - for (var i = 0; i < containerInfo.stats.length; i++) { - var cur = containerInfo.stats[i]; - - var elements = []; - elements.push(cur.timestamp); - elements.push(cur.memory.usage / oneMegabyte); - elements.push(cur.memory.working_set / oneMegabyte); - data.push(elements); - } - - // Get the memory limit, saturate to the machine size. - var memory_limit = machineInfo.memory_capacity; - if (containerInfo.spec.memory.limit && (containerInfo.spec.memory.limit < memory_limit)) { - memory_limit = containerInfo.spec.memory.limit; - } - - var cur = containerInfo.stats[containerInfo.stats.length - 1]; - - var r = { - current: { - memoryUsage: cur.memory.usage, - workingMemoryUsage: cur.memory.working_set, - memoryLimit: memory_limit, - memoryUsageDescription: humanizeMetric(cur.memory.usage), - workingMemoryUsageDescription: humanizeMetric(cur.memory.working_set), - memoryLimitDescription: humanizeMetric(memory_limit) - }, - historical: data - }; - - return r; - } - }]); -})(); - -app.provider('k8sApi', - function() { - - var urlBase = ''; - var _namespace = 'default'; - - this.setUrlBase = function(value) { urlBase = value; }; - - this.setNamespace = function(value) { _namespace = value; }; - this.getNamespace = function() { return _namespace; }; - - var _get = function($http, baseUrl, query) { - var _fullUrl = baseUrl; - - if (query !== undefined) { - _fullUrl += '/' + query; - } - - return $http.get(_fullUrl); - }; - - this.$get = ["$http", "$q", function($http, $q) { - var api = {}; - - api.getUrlBase = function() { return urlBase + '/namespaces/' + _namespace; }; - - api.getPods = function(query) { return _get($http, api.getUrlBase() + '/pods', query); }; - - api.getNodes = function(query) { return _get($http, urlBase + '/nodes', query); }; - - api.getMinions = api.getNodes; - - api.getServices = function(query) { return _get($http, api.getUrlBase() + '/services', query); }; - - api.getReplicationControllers = function(query) { - return _get($http, api.getUrlBase() + '/replicationcontrollers', query) - }; - - api.getEvents = function(query) { return _get($http, api.getUrlBase() + '/events', query); }; - - return api; - }]; - }) - .config(["k8sApiProvider", "ENV", function(k8sApiProvider, ENV) { - if (ENV && ENV['/'] && ENV['/']['k8sApiServer']) { - k8sApiProvider.setUrlBase(ENV['/']['k8sApiServer']); - } - }]); - -(function() { - "use strict"; - - var pollK8sDataServiceProvider = function PollK8sDataServiceProvider(_) { - // A set of configuration controlling the polling behavior. - // Their values should be configured in the application before - // creating the service instance. - - var useSampleData = false; - this.setUseSampleData = function(value) { useSampleData = value; }; - - var sampleDataFiles = ["shared/assets/sampleData1.json"]; - this.setSampleDataFiles = function(value) { sampleDataFiles = value; }; - - var dataServer = "http://localhost:5555/cluster"; - this.setDataServer = function(value) { dataServer = value; }; - - var pollMinIntervalSec = 10; - this.setPollMinIntervalSec = function(value) { pollMinIntervalSec = value; }; - - var pollMaxIntervalSec = 120; - this.setPollMaxIntervalSec = function(value) { pollMaxIntervalSec = value; }; - - var pollErrorThreshold = 5; - this.setPollErrorThreshold = function(value) { pollErrorThreshold = value; }; - - this.$get = function($http, $timeout) { - // Now the sequenceNumber will be used for debugging and verification purposes. - var k8sdatamodel = { - "data": undefined, - "sequenceNumber": 0, - "useSampleData": useSampleData - }; - var pollingError = 0; - var promise = undefined; - - // Implement fibonacci back off when the service is down. - var pollInterval = pollMinIntervalSec; - var pollIncrement = pollInterval; - - // Reset polling interval. - var resetCounters = function() { - pollInterval = pollMinIntervalSec; - pollIncrement = pollInterval; - }; - - // Bump error count and polling interval. - var bumpCounters = function() { - // Bump the error count. - pollingError++; - - // TODO: maybe display an error in the UI to the end user. - if (pollingError % pollErrorThreshold === 0) { - console.log("Error: " + pollingError + " consecutive polling errors for " + dataServer + "."); - } - - // Bump the polling interval. - var oldIncrement = pollIncrement; - pollIncrement = pollInterval; - pollInterval += oldIncrement; - - // Reset when limit reached. - if (pollInterval > pollMaxIntervalSec) { - resetCounters(); - } - }; - - var updateModel = function(newModel) { - var dedupe = function(dataModel) { - if (dataModel.resources) { - dataModel.resources = _.uniq(dataModel.resources, function(resource) { return resource.id; }); - } - - if (dataModel.relations) { - dataModel.relations = - _.uniq(dataModel.relations, function(relation) { return relation.source + relation.target; }); - } - }; - - dedupe(newModel); - - var newModelString = JSON.stringify(newModel); - var oldModelString = ""; - if (k8sdatamodel.data) { - oldModelString = JSON.stringify(k8sdatamodel.data); - } - - if (newModelString !== oldModelString) { - k8sdatamodel.data = newModel; - k8sdatamodel.sequenceNumber++; - } - - pollingError = 0; - resetCounters(); - }; - - var nextSampleDataFile = 0; - var getSampleDataFile = function() { - var result = ""; - if (sampleDataFiles.length > 0) { - result = sampleDataFiles[nextSampleDataFile % sampleDataFiles.length]; - ++nextSampleDataFile; - } - - return result; - }; - - var pollOnce = function(scope, repeat) { - var dataSource = (k8sdatamodel.useSampleData) ? getSampleDataFile() : dataServer; - $.getJSON(dataSource) - .done(function(newModel, jqxhr, textStatus) { - if (newModel && newModel.success) { - delete newModel.success; // Remove success indicator. - delete newModel.timestamp; // Remove changing timestamp. - updateModel(newModel); - scope.$apply(); - promise = repeat ? $timeout(function() { pollOnce(scope, true); }, pollInterval * 1000) : undefined; - return; - } - - bumpCounters(); - promise = repeat ? $timeout(function() { pollOnce(scope, true); }, pollInterval * 1000) : undefined; - }) - .fail(function(jqxhr, textStatus, error) { - bumpCounters(); - promise = repeat ? $timeout(function() { pollOnce(scope, true); }, pollInterval * 1000) : undefined; - }); - }; - - var isPolling = function() { return promise ? true : false; }; - - var start = function(scope) { - // If polling has already started, then calling start() again would - // just reset the counters and polling interval, but it will not - // start a new thread polling in parallel to the existing polling - // thread. - resetCounters(); - if (!promise) { - k8sdatamodel.data = undefined; - pollOnce(scope, true); - } - }; - - var stop = function() { - if (promise) { - $timeout.cancel(promise); - promise = undefined; - } - }; - - var refresh = function(scope) { - stop(scope); - resetCounters(); - k8sdatamodel.data = undefined; - pollOnce(scope, false); - }; - - return { - "k8sdatamodel": k8sdatamodel, - "isPolling": isPolling, - "refresh": refresh, - "start": start, - "stop": stop - }; - }; - }; - - angular.module("kubernetesApp.services") - .provider("pollK8sDataService", ["lodash", pollK8sDataServiceProvider]) - .config(["pollK8sDataServiceProvider", "ENV", function(pollK8sDataServiceProvider, ENV) { - if (ENV && ENV['/']) { - if (ENV['/']['k8sDataServer']) { - pollK8sDataServiceProvider.setDataServer(ENV['/']['k8sDataServer']); - } - if (ENV['/']['k8sDataPollIntervalMinSec']) { - pollK8sDataServiceProvider.setPollIntervalSec(ENV['/']['k8sDataPollIntervalMinSec']); - } - if (ENV['/']['k8sDataPollIntervalMaxSec']) { - pollK8sDataServiceProvider.setPollIntervalSec(ENV['/']['k8sDataPollIntervalMaxSec']); - } - if (ENV['/']['k8sDataPollErrorThreshold']) { - pollK8sDataServiceProvider.setPollErrorThreshold(ENV['/']['k8sDataPollErrorThreshold']); - } - } - }]); - -}()); - -/**========================================================= - * Module: toggle-state.js - * Services to share toggle state functionality - =========================================================*/ - - -app.controller('cAdvisorController', [ - '$scope', - '$routeParams', - 'k8sApi', - 'lodash', - 'cAdvisorService', - '$q', - '$interval', - function($scope, $routeParams, k8sApi, lodash, cAdvisorService, $q, $interval) { - $scope.k8sApi = k8sApi; - - $scope.activeMinionDataById = {}; - $scope.maxDataByById = {}; - - $scope.getData = function() { - $scope.loading = true; - - k8sApi.getMinions().success(angular.bind(this, function(res) { - $scope.minions = res; - // console.log(res); - var promises = lodash.map(res.items, function(m) { return cAdvisorService.getDataForMinion(m.metadata.name); }); - - $q.all(promises).then( - function(dataArray) { - lodash.each(dataArray, function(data, i) { - var m = res.items[i]; - - var maxData = maxMemCpuInfo(m.metadata.name, data.memoryData, data.cpuData, data.filesystemData); - - // console.log("maxData", maxData); - var hostname = ""; - if(m.status.addresses) - hostname = m.status.addresses[0].address; - - $scope.activeMinionDataById[m.metadata.name] = - transformMemCpuInfo(data.memoryData, data.cpuData, data.filesystemData, maxData, hostname); - }); - - }, - function(errorData) { - // console.log("Error: " + errorData); - $scope.loading = false; - }); - - $scope.loading = false; - })).error(angular.bind(this, this.handleError)); - }; - - function handleError(data, status, headers, config) { - // console.log("Error (" + status + "): " + data); - $scope.loading = false; - }; - - // d3 - function getColorForIndex(i, percentage) { - // var colors = ['red', 'blue', 'yellow', 'pink', 'purple', 'green', 'orange']; - // return colors[i]; - var c = "color-" + (i + 1); - if (percentage && percentage >= 90) - c = c + ' color-critical'; - else if (percentage && percentage >= 80) - c = c + ' color-warning'; - - return c; - } - - function getMaxColorForIndex(i, percentage) { - // var colors = ['red', 'blue', 'yellow', 'pink', 'purple', 'green', 'orange']; - // return colors[i]; - var c = "color-max-" + (i + 1); - if (percentage && percentage >= 90) - c = c + ' color-max-critical'; - else if (percentage && percentage >= 80) - c = c + ' color-max-warning'; - - return c; - } - - function maxMemCpuInfo(mId, mem, cpu, fsDataArray) { - if ($scope.maxDataByById[mId] === undefined) $scope.maxDataByById[mId] = {}; - - var currentMem = mem.current; - var currentCpu = cpu; - - var items = []; - - if ($scope.maxDataByById[mId]['cpu'] === undefined || - $scope.maxDataByById[mId]['cpu'] < currentCpu.cpuPercentUsage) { - // console.log("New max cpu " + mId, $scope.maxDataByById[mId].cpu, currentCpu.cpuPercentUsage); - $scope.maxDataByById[mId]['cpu'] = currentCpu.cpuPercentUsage; - } - items.push({ - maxValue: $scope.maxDataByById[mId]['cpu'], - maxTickClassNames: getColorForIndex(0, $scope.maxDataByById[mId]['cpu']), - maxClassNames: getMaxColorForIndex(0, $scope.maxDataByById[mId]['cpu']) - }); - - var memPercentage = Math.floor((currentMem.memoryUsage * 100.0) / currentMem.memoryLimit); - if ($scope.maxDataByById[mId]['mem'] === undefined || $scope.maxDataByById[mId]['mem'] < memPercentage) - $scope.maxDataByById[mId]['mem'] = memPercentage; - items.push({ - maxValue: $scope.maxDataByById[mId]['mem'], - maxTickClassNames: getColorForIndex(1, $scope.maxDataByById[mId]['mem']), - maxClassNames: getMaxColorForIndex(1, $scope.maxDataByById[mId]['mem']) - }); - - for (var i = 0; i < fsDataArray.length; i++) { - var f = fsDataArray[i]; - var fid = 'FS #' + f.filesystemNumber; - if ($scope.maxDataByById[mId][fid] === undefined || $scope.maxDataByById[mId][fid] < f.totalUsage) - $scope.maxDataByById[mId][fid] = f.totalUsage; - items.push({ - maxValue: $scope.maxDataByById[mId][fid], - maxTickClassNames: getColorForIndex(2 + i, $scope.maxDataByById[mId][fid]), - maxClassNames: getMaxColorForIndex(2 + i, $scope.maxDataByById[mId][fid]) - }); - } - - // console.log("Max Data is now " + mId, $scope.maxDataByById[mId]); - return items; - } - - function transformMemCpuInfo(mem, cpu, fsDataArray, maxData, hostName) { - var currentMem = mem.current; - var currentCpu = cpu; - - var items = []; - - items.push({ - label: 'CPU', - stats: currentCpu.cpuPercentUsage + '%', - value: currentCpu.cpuPercentUsage, - classNames: getColorForIndex(0, currentCpu.cpuPercentUsage), - maxData: maxData[0], - hostName: hostName - }); - - var memPercentage = Math.floor((currentMem.memoryUsage * 100.0) / currentMem.memoryLimit); - items.push({ - label: 'Memory', - stats: currentMem.memoryUsageDescription + ' / ' + currentMem.memoryLimitDescription, - value: memPercentage, - classNames: getColorForIndex(1, memPercentage), - maxData: maxData[1], - hostName: hostName - }); - - for (var i = 0; i < fsDataArray.length; i++) { - var f = fsDataArray[i]; - - items.push({ - label: 'Filesystem #' + f.filesystemNumber, - stats: f.usageDescription + ' / ' + f.capacityDescription, - value: f.totalUsage, - classNames: getColorForIndex(2 + i, f.totalUsage), - maxData: maxData[2 + i], - hostName: hostName - - }); - } - - var a = []; - var segments = { - segments: items - }; - a.push(segments); - return a; - }; - - // end d3 - var promise = $interval($scope.getData, 3000); - - // Cancel interval on page changes - $scope.$on('$destroy', function() { - if (angular.isDefined(promise)) { - $interval.cancel(promise); - promise = undefined; - } - }); - - $scope.getData(); - - } -]); - -/**========================================================= - * Module: Dashboard - * Visualizer for clusters - =========================================================*/ - -app.controller('DashboardCtrl', ['$scope', function($scope) {}]); - -/**========================================================= - * Module: Group - * Visualizer for groups - =========================================================*/ - -app.controller('GroupCtrl', [ - '$scope', - '$route', - '$interval', - '$routeParams', - 'k8sApi', - '$rootScope', - '$location', - 'lodash', - function($scope, $route, $interval, $routeParams, k8sApi, $rootScope, $location, _) { - 'use strict'; - $scope.doTheBack = function() { window.history.back(); }; - - $scope.capitalize = function(s) { return _.capitalize(s); }; - - $rootScope.doTheBack = $scope.doTheBack; - - $scope.resetGroupLayout = function(group) { delete group.settings; }; - - $scope.handlePath = function(path) { - var parts = path.split("/"); - // split leaves an empty string at the beginning. - parts = parts.slice(1); - - if (parts.length === 0) { - return; - } - this.handleGroups(parts.slice(1)); - }; - - $scope.getState = function(obj) { return Object.keys(obj)[0]; }; - - $scope.clearSelector = function(grouping) { $location.path("/dashboard/groups/" + grouping + "/selector/"); }; - - $scope.changeGroupBy = function() { - var grouping = encodeURIComponent($scope.selectedGroupBy); - - var s = _.clone($location.search()); - if ($scope.routeParams.grouping != grouping) - $location.path("/dashboard/groups/" + grouping + "/selector/").search(s); - }; - - $scope.createBarrier = function(count, callback) { - var barrier = count; - var barrierFunction = angular.bind(this, function(data) { - // JavaScript is single threaded so this is safe. - barrier--; - if (barrier === 0) { - if (callback) { - callback(); - } - } - }); - return barrierFunction; - }; - - $scope.handleGroups = function(parts, selector) { - $scope.groupBy = parts; - $scope.loading = true; - $scope.selector = selector; - $scope.selectorName = decodeURIComponent(selector); - var args = []; - var type = ""; - var selectedHost = ""; - if (selector && selector.length > 0) { - $scope.selectorPieces = selector.split(","); - var labels = []; - var fields = []; - for (var i = 0; i < $scope.selectorPieces.length; i++) { - var piece = decodeURIComponent($scope.selectorPieces[i]); - if (piece[0] == '$') { - fields.push(piece.slice(2)); - } else { - if (piece.indexOf("type=") === 0) { - var labelParts = piece.split("="); - if (labelParts.length > 1) { - type = labelParts[1]; - } - } - else if (piece.indexOf("host=") === 0){ - var labelParts = piece.split("="); - if (labelParts.length > 1) { - selectedHost = labelParts[1]; - } - } - else { - labels.push(piece); - } - } - } - - if (labels.length > 0) { - args.push("labelSelector=" + encodeURI(labels.join(","))); - } - if (fields.length > 0) { - args.push("fields=" + encodeURI(fields.join(","))); - } - } - var query = "?" + args.join("&"); - var list = []; - var count = type.length > 0 ? 1 : 3; - - $scope.selectedGroupByName = decodeURIComponent($routeParams.grouping) - - var barrier = $scope.createBarrier(count, function() { - $scope.groups = $scope.groupData(list, 0); - $scope.loading = false; - $scope.groupByOptions = buildGroupByOptions(); - $scope.selectedGroupBy = $routeParams.grouping; - }); - - if (type === "" || type == "pod") { - k8sApi.getPods(query).success(function(data) { - $scope.addLabel("type", "pod", data.items); - for (var i = 0; data.items && i < data.items.length; ++i) { - data.items[i].metadata.labels.host = data.items[i].spec.nodeName; - if(selectedHost.length == 0 || selectedHost == data.items[i].metadata.labels.host) - list.push(data.items[i]); - } - barrier(); - }).error($scope.handleError); - } - if (type === "" || type == "service") { - k8sApi.getServices(query).success(function(data) { - $scope.addLabel("type", "service", data.items); - for (var i = 0; data.items && i < data.items.length; ++i) { - list.push(data.items[i]); - } - barrier(); - }).error($scope.handleError); - } - if (type === "" || type == "replicationController") { - k8sApi.getReplicationControllers(query).success(angular.bind(this, function(data) { - $scope.addLabel("type", "replicationController", data.items); - for (var i = 0; data.items && i < data.items.length; ++i) { - list.push(data.items[i]); - } - barrier(); - })).error($scope.handleError); - } - }; - - $scope.addLabel = function(key, value, items) { - if (!items) { - return; - } - for (var i = 0; i < items.length; i++) { - if (!items[i].metadata.labels) { - items[i].metadata.labels = {}; - } - items[i].metadata.labels[key] = value; - } - }; - - $scope.groupData = function(items, index) { - var result = { - "items": {}, - "kind": "grouping" - }; - for (var i = 0; i < items.length; i++) { - key = items[i].metadata.labels[decodeURIComponent($scope.groupBy[index])]; - if (!key) { - key = ""; - } - var list = result.items[key]; - if (!list) { - list = []; - result.items[key] = list; - } - list.push(items[i]); - } - - if (index + 1 < $scope.groupBy.length) { - for (var key in result.items) { - result.items[key] = $scope.groupData(result.items[key], index + 1); - } - } - return result; - }; - $scope.getGroupColor = function(type) { - if (type === 'pod') { - return '#6193F0'; - } else if (type === 'replicationController') { - return '#E008FE'; - } else if (type === 'service') { - return '#7C43FF'; - } - }; - - var groups = $routeParams.grouping; - if (!groups) { - groups = ''; - } - - $scope.routeParams = $routeParams; - $scope.route = $route; - - $scope.handleGroups(groups.split('/'), $routeParams.selector); - - $scope.handleError = function(data, status, headers, config) { - console.log("Error (" + status + "): " + data); - $scope_.loading = false; - }; - - function getDefaultGroupByOptions() { return [{name: 'Type', value: 'type'}, {name: 'Name', value: 'name'}]; } - - function buildGroupByOptions() { - var g = $scope.groups; - var options = getDefaultGroupByOptions(); - var newOptions = _.map(g.items, function(vals) { return _.map(vals, function(v) { return _.keys(v.metadata.labels); }); }); - newOptions = - _.reject(_.uniq(_.flattenDeep(newOptions)), function(o) { return o == 'name' || o == 'type' || o == ""; }); - newOptions = _.map(newOptions, function(o) { - return { - name: o, - value: o - }; - }); - - options = options.concat(newOptions); - return options; - } - - $scope.changeFilterBy = function(selector) { - var grouping = $scope.selectedGroupBy; - - var s = _.clone($location.search()); - if ($scope.routeParams.selector != selector) - $location.path("/dashboard/groups/" + $scope.routeParams.grouping + "/selector/" + selector).search(s); - }; - } -]); - -/**========================================================= - * Module: Header - * Visualizer for clusters - =========================================================*/ - -angular.module('kubernetesApp.components.dashboard', []) - .controller('HeaderCtrl', [ - '$scope', - '$location', - function($scope, $location) { - 'use strict'; - $scope.$watch('Pages', function(newValue, oldValue) { - if (typeof newValue !== 'undefined') { - $location.path(newValue); - } - }); - - $scope.subPages = [ - {category: 'dashboard', name: 'Explore', value: '/dashboard/groups/type/selector/'}, - {category: 'dashboard', name: 'Pods', value: '/dashboard/pods'}, - {category: 'dashboard', name: 'Nodes', value: '/dashboard/nodes'}, - {category: 'dashboard', name: 'Replication Controllers', value: '/dashboard/replicationcontrollers'}, - {category: 'dashboard', name: 'Services', value: '/dashboard/services'}, - {category: 'dashboard', name: 'Events', value: '/dashboard/events'} - ]; - } - ]); - -/**========================================================= - * Module: List Events - * Visualizer list events - =========================================================*/ - -app.controller('ListEventsCtrl', [ - '$scope', - '$routeParams', - 'k8sApi', - '$location', - '$filter', - function($scope, $routeParams, k8sApi, $location, $filter) { - 'use strict'; - $scope.getData = getData; - $scope.loading = true; - $scope.k8sApi = k8sApi; - $scope.pods = null; - $scope.groupedPods = null; - $scope.serverView = false; - - $scope.headers = [ - {name: 'Last Seen', field: 'lastSeen'}, - {name: 'First Seen', field: 'firstSeen'}, - {name: 'Count', field: 'count'}, - {name: 'Name', field: 'name'}, - {name: 'Kind', field: 'kind'}, - {name: 'SubObject', field: 'subObject'}, - {name: 'Reason', field: 'reason'}, - {name: 'Source', field: 'source'}, - {name: 'Message', field: 'message'} - ]; - - - $scope.sortable = ['lastSeen', 'firstSeen', 'count', 'name', 'kind', 'subObject', 'reason', 'source', 'message']; - $scope.count = 50; - function handleError(data, status, headers, config) { - console.log("Error (" + status + "): " + data); - $scope.loading = false; - } - - $scope.content = []; - - function getData() { - $scope.loading = true; - k8sApi.getEvents().success(function(data) { - $scope.loading = false; - - var _fixComma = function(str) { - if (str.substring(0, 1) == ',') { - return str.substring(1); - } else { - return str; - } - }; - - data.items.forEach(function(event) { - var _sources = ''; - if (event.source) { - _sources = event.source.component + ' ' + event.source.host; - } - - - $scope.content.push({ - firstSeen: $filter('date')(event.firstTimestamp, 'medium'), - lastSeen: $filter('date')(event.lastTimestamp, 'medium'), - count: event.count, - name: event.involvedObject.name, - kind: event.involvedObject.kind, - subObject: event.involvedObject.fieldPath, - reason: event.reason, - source: _sources, - message: event.message - }); - - - - }); - - $scope.content = _.sortBy($scope.content, function(e){ - return e.lastSeen; - }).reverse(); - - - }).error($scope.handleError); - } - - getData(); - - } -]); - -/**========================================================= - * Module: Minions - * Visualizer for minions - =========================================================*/ - -app.controller('ListMinionsCtrl', [ - '$scope', - '$routeParams', - 'k8sApi', - '$location', - function($scope, $routeParams, k8sApi, $location) { - 'use strict'; - $scope.getData = getData; - $scope.loading = true; - $scope.k8sApi = k8sApi; - $scope.pods = null; - $scope.groupedPods = null; - $scope.serverView = false; - - $scope.headers = [{name: 'Name', field: 'name'}, {name: 'Addresses', field: 'addresses'}, {name: 'Status', field: 'status'}]; - - $scope.custom = { - name: '', - status: 'grey', - ip: 'grey' - }; - $scope.sortable = ['name', 'status', 'addresses']; - $scope.thumbs = 'thumb'; - $scope.count = 50; - - $scope.go = function(d) { $location.path('/dashboard/nodes/' + d.name); }; - - - function handleError(data, status, headers, config) { - console.log("Error (" + status + "): " + data); - $scope.loading = false; - } - - $scope.content = []; - - function getData() { - $scope.loading = true; - k8sApi.getMinions().success(function(data) { - $scope.loading = false; - - var _fixComma = function(str) { - if (str.substring(0, 1) == ',') { - return str.substring(1); - } else { - return str; - } - }; - - data.items.forEach(function(minion) { - var _statusType = ''; - - if (minion.status.conditions) { - Object.keys(minion.status.conditions) - .forEach(function(key) { _statusType += minion.status.conditions[key].type; }); - } - - - $scope.content.push({name: minion.metadata.name, addresses: _.map(minion.status.addresses, function(a) { return a.address }).join(', '), status: _statusType}); - }); - - }).error($scope.handleError); - } - - getData(); - - } -]); - - - -app.controller('ListPodsCtrl', [ - '$scope', - '$routeParams', - 'k8sApi', - 'lodash', - '$location', - function($scope, $routeParams, k8sApi, lodash, $location) { - var _ = lodash; - $scope.getData = getData; - $scope.loading = true; - $scope.k8sApi = k8sApi; - $scope.pods = null; - $scope.groupedPods = null; - $scope.serverView = false; - - $scope.headers = [ - {name: 'Pod', field: 'pod'}, - {name: 'IP', field: 'ip'}, - {name: 'Status', field: 'status'}, - {name: 'Containers', field: 'containers'}, - {name: 'Images', field: 'images'}, - {name: 'Host', field: 'host'}, - {name: 'Labels', field: 'labels'} - ]; - - $scope.custom = { - pod: '', - ip: 'grey', - containers: 'grey', - images: 'grey', - host: 'grey', - labels: 'grey', - status: 'grey' - }; - $scope.sortable = ['pod', 'ip', 'status','containers','images','host','labels']; - $scope.count = 50; - - $scope.go = function(data) { $location.path('/dashboard/pods/' + data.pod); }; - - var orderedPodNames = []; - - function handleError(data, status, headers, config) { - console.log("Error (" + status + "): " + data); - $scope.loading = false; - }; - - function getPodName(pod) { return _.has(pod.metadata.labels, 'name') ? pod.metadata.labels.name : pod.metadata.name; } - - $scope.content = []; - - function getData() { - $scope.loading = true; - k8sApi.getPods().success(angular.bind(this, function(data) { - $scope.loading = false; - - var _fixComma = function(str) { - if (str.substring(0, 1) == ',') { - return str.substring(1); - } else { - return str; - } - }; - - data.items.forEach(function(pod) { - var _containers = '', _images = '', _labels = '', _uses = ''; - - if (pod.spec) { - Object.keys(pod.spec.containers) - .forEach(function(key) { - _containers += ', ' + pod.spec.containers[key].name; - _images += ', ' + pod.spec.containers[key].image; - }); - } - - if (pod.metadata.labels) { - _labels = _.map(pod.metadata.labels, function(v, k) { return k + ': ' + v }).join(', '); - } - - $scope.content.push({ - pod: pod.metadata.name, - ip: pod.status.podIP, - containers: _fixComma(_containers), - images: _fixComma(_images), - host: pod.spec.nodeName, - labels: _labels, - status: pod.status.phase - }); - - }); - - })).error(angular.bind(this, handleError)); - }; - - $scope.getPodRestarts = function(pod) { - var r = null; - var container = _.first(pod.spec.containers); - if (container) r = pod.status.containerStatuses[container.name].restartCount; - return r; - }; - - $scope.otherLabels = function(labels) { return _.omit(labels, 'name') }; - - $scope.podStatusClass = function(pod) { - - var s = pod.status.phase.toLowerCase(); - - if (s == 'running' || s == 'succeeded') - return null; - else - return "status-" + s; - }; - - $scope.podIndexFromName = function(pod) { - var name = getPodName(pod); - return _.indexOf(orderedPodNames, name) + 1; - }; - - getData(); - - } -]); - -/**========================================================= - * Module: Replication Controllers - * Visualizer for replication controllers - =========================================================*/ - -app.controller('ListReplicationControllersCtrl', [ - '$scope', - '$routeParams', - 'k8sApi', - '$location', - function($scope, $routeParams, k8sApi, $location) { - 'use strict'; - $scope.getData = getData; - $scope.loading = true; - $scope.k8sApi = k8sApi; - $scope.pods = null; - $scope.groupedPods = null; - $scope.serverView = false; - - $scope.headers = [ - {name: 'Controller', field: 'controller'}, - {name: 'Containers', field: 'containers'}, - {name: 'Images', field: 'images'}, - {name: 'Selector', field: 'selector'}, - {name: 'Replicas', field: 'replicas'} - ]; - - $scope.custom = { - controller: '', - containers: 'grey', - images: 'grey', - selector: 'grey', - replicas: 'grey' - }; - $scope.sortable = ['controller', 'containers', 'images', 'selector', 'replicas']; - $scope.thumbs = 'thumb'; - $scope.count = 50; - - $scope.go = function(data) { $location.path('/dashboard/replicationcontrollers/' + data.controller); }; - - function handleError(data, status, headers, config) { - console.log("Error (" + status + "): " + data); - $scope.loading = false; - } - - $scope.content = []; - - function getData() { - $scope.loading = true; - k8sApi.getReplicationControllers().success(function(data) { - $scope.loading = false; - - var _fixComma = function(str) { - if (str.substring(0, 1) == ',') { - return str.substring(1); - } else { - return str; - } - }; - - data.items.forEach(function(replicationController) { - - var _name = '', _image = ''; - - if (replicationController.spec.template.spec.containers) { - Object.keys(replicationController.spec.template.spec.containers) - .forEach(function(key) { - _name += replicationController.spec.template.spec.containers[key].name; - _image += replicationController.spec.template.spec.containers[key].image; - }); - } - - var _selectors = ''; - - if (replicationController.spec.selector) { - _selectors = _.map(replicationController.spec.selector, function(v, k) { return k + '=' + v }).join(', '); - } - - $scope.content.push({ - controller: replicationController.metadata.name, - containers: _name, - images: _image, - selector: _selectors, - replicas: replicationController.status.replicas - }); - - }); - - }).error($scope.handleError); - } - - getData(); - - } -]); - -/**========================================================= - * Module: Services - * Visualizer for services - =========================================================*/ - -app.controller('ListServicesCtrl', [ - '$scope', - '$interval', - '$routeParams', - 'k8sApi', - '$rootScope', - '$location', - function($scope, $interval, $routeParams, k8sApi, $rootScope, $location) { - 'use strict'; - $scope.doTheBack = function() { window.history.back(); }; - - $scope.headers = [ - {name: 'Name', field: 'name'}, - {name: 'Labels', field: 'labels'}, - {name: 'Selector', field: 'selector'}, - {name: 'IP', field: 'ip'}, - {name: 'Ports', field: 'port'} - ]; - - $scope.custom = { - name: '', - ip: 'grey', - selector: 'grey', - port: 'grey', - labels: 'grey' - }; - $scope.sortable = ['name', 'ip', 'port', 'labels', 'selector']; - $scope.count = 50; - - $scope.go = function(data) { $location.path('/dashboard/services/' + data.name); }; - - $scope.content = []; - - $rootScope.doTheBack = $scope.doTheBack; - - $scope.handleError = function(data, status, headers, config) { - console.log("Error (" + status + "): " + data); - $scope_.loading = false; - }; - - $scope.getData = function() { - $scope.loading = true; - k8sApi.getServices().success(angular.bind(this, function(data) { - $scope.services = data; - $scope.loading = false; - - var _fixComma = function(str) { - if (str.substring(0, 1) == ',') { - return str.substring(1); - } else { - return str; - } - }; - - var addLabel = function(str, label) { - if (str) { - str = label + str; - } - return str; - }; - - if (data.items.constructor === Array) { - data.items.forEach(function(service) { - - var _labels = ''; - - if (service.metadata.labels) { - _labels = _.map(service.metadata.labels, function(v, k) { return k + ': ' + v }).join(', '); - } - - var _selectors = ''; - - if (service.spec.selector) { - _selectors = _.map(service.spec.selector, function(v, k) { return k + '=' + v }).join(', '); - } - - var _ports = ''; - - if (service.spec.ports) { - _ports = _.map(service.spec.ports, function(p) { - var n = ''; - if(p.name) - n = p.name + ': '; - n = n + p.port; - return n; - }).join(', '); - } - - $scope.content.push({ - name: service.metadata.name, - ip: service.spec.clusterIP, - port: _ports, - selector: _selectors, - labels: _labels - }); - }); - } - })).error($scope.handleError); - }; - - $scope.getData(); - } -]); - -/**========================================================= - * Module: Nodes - * Visualizer for nodes - =========================================================*/ - -app.controller('NodeCtrl', [ - '$scope', - '$interval', - '$routeParams', - 'k8sApi', - '$rootScope', - function($scope, $interval, $routeParams, k8sApi, $rootScope) { - 'use strict'; - $scope.doTheBack = function() { window.history.back(); }; - - $rootScope.doTheBack = $scope.doTheBack; - - $scope.handleError = function(data, status, headers, config) { - console.log("Error (" + status + "): " + data); - $scope_.loading = false; - }; - - $scope.handleNode = function(nodeId) { - $scope.loading = true; - k8sApi.getNodes(nodeId).success(angular.bind(this, function(data) { - $scope.node = data; - $scope.loading = false; - })).error($scope.handleError); - }; - - $scope.handleNode($routeParams.nodeId); - } -]); - -/**========================================================= - * Module: Pods - * Visualizer for pods - =========================================================*/ - -app.controller('PodCtrl', [ - '$scope', - '$interval', - '$routeParams', - 'k8sApi', - '$rootScope', - function($scope, $interval, $routeParams, k8sApi, $rootScope) { - 'use strict'; - $scope.doTheBack = function() { window.history.back(); }; - - $rootScope.doTheBack = $scope.doTheBack; - - $scope.handleError = function(data, status, headers, config) { - console.log("Error (" + status + "): " + data); - $scope_.loading = false; - }; - - $scope.handlePod = function(podId) { - $scope.loading = true; - k8sApi.getPods(podId).success(angular.bind(this, function(data) { - $scope.pod = data; - $scope.loading = false; - })).error($scope.handleError); - }; - - $scope.handlePod($routeParams.podId); - } -]); - -/**========================================================= - * Module: Replication - * Visualizer for replication controllers - =========================================================*/ - -function ReplicationController() { -} - -ReplicationController.prototype.getData = function(dataId) { - this.scope.loading = true; - this.k8sApi.getReplicationControllers(dataId).success(angular.bind(this, function(data) { - this.scope.replicationController = data; - this.scope.loading = false; - })).error(angular.bind(this, this.handleError)); -}; - -ReplicationController.prototype.handleError = function(data, status, headers, config) { - console.log("Error (" + status + "): " + data); - this.scope.loading = false; -}; - -app.controller('ReplicationControllerCtrl', [ - '$scope', - '$routeParams', - 'k8sApi', - function($scope, $routeParams, k8sApi) { - $scope.controller = new ReplicationController(); - $scope.controller.k8sApi = k8sApi; - $scope.controller.scope = $scope; - $scope.controller.getData($routeParams.replicationControllerId); - - $scope.doTheBack = function() { window.history.back(); }; - $scope.getSelectorUrlFragment = function(sel){ return _.map(sel, function(v, k) { return k + '=' + v }).join(','); }; - - } -]); - -/**========================================================= - * Module: Services - * Visualizer for services - =========================================================*/ - -function ServiceController() { -} - -ServiceController.prototype.getData = function(dataId) { - this.scope.loading = true; - this.k8sApi.getServices(dataId).success(angular.bind(this, function(data) { - this.scope.service = data; - this.scope.loading = false; - })).error(angular.bind(this, this.handleError)); -}; - -ServiceController.prototype.handleError = function(data, status, headers, config) { - console.log("Error (" + status + "): " + data); - this.scope.loading = false; -}; - -app.controller('ServiceCtrl', [ - '$scope', - '$routeParams', - 'k8sApi', - '$location', - function($scope, $routeParams, k8sApi, $location) { - $scope.controller = new ServiceController(); - $scope.controller.k8sApi = k8sApi; - $scope.controller.scope = $scope; - $scope.controller.getData($routeParams.serviceId); - - $scope.doTheBack = function() { window.history.back(); }; - $scope.go = function(d) { $location.path('/dashboard/services/' + d.metadata.name); } - $scope.getSelectorUrlFragment = function(sel){ return _.map(sel, function(v, k) { return k + '=' + v }).join(','); }; - - } -]); - -(function() { - 'use strict'; - - angular.module('kubernetesApp.components.dashboard') - .directive('d3MinionBarGauge', [ - 'd3DashboardService', - function(d3DashboardService) { - - return { - restrict: 'E', - scope: { - data: '=', - thickness: '@', - graphWidth: '@', - graphHeight: '@' - - }, - link: function(scope, element, attrs) { - - var draw = function(d3) { - var svg = d3.select("svg.chart"); - var legendSvg = d3.select("svg.legend"); - window.onresize = function() { return scope.$apply(); }; - - scope.$watch(function() { return angular.element(window)[0].innerWidth; }, - function() { return scope.render(scope.data); }); - - scope.$watch('data', function(newVals, oldVals) { - return initOrUpdate(newVals, oldVals); - - }, true); - - function initOrUpdate(newVals, oldVals) { - if (oldVals === null || oldVals === undefined) { - return scope.render(newVals); - } else { - return update(oldVals, newVals); - } - } - - var textOffset = 10; - var el = null; - var radius = 100; - var oldData = []; - - function init(options) { - var clone = options.data; - var preparedData = setData(clone); - setup(preparedData, options.width, options.height); - } - - function setup(data, w, h) { - svg = d3.select(element[0]).append("svg").attr("width", "100%"); - - legendSvg = d3.select(element[0]).append("svg").attr("width", "100%"); - - var chart = svg.attr("class", "chart") - .attr("width", w) - .attr("height", h - 25) - .append("svg:g") - .attr("class", "concentricchart") - .attr("transform", "translate(" + ((w / 2)) + "," + h / 4 + ")"); - - var legend = legendSvg.attr("class", "legend").attr("width", w); - - radius = Math.min(w, h) / 2; - - var hostName = legendSvg.append("text") - .attr("class", "hostName") - .attr("transform", "translate(" + ((w - 120) / 2) + "," + 15 + ")"); - - var label_legend_area = legendSvg.append("svg:g") - .attr("class", "label_legend_area") - .attr("transform", "translate(" + ((w - 215) / 2) + "," + 35 + ")"); - - var legend_group = label_legend_area.append("svg:g").attr("class", "legend_group"); - - var label_group = label_legend_area.append("svg:g") - .attr("class", "label_group") - .attr("transform", "translate(" + 25 + "," + 11 + ")"); - - var stats_group = label_legend_area.append("svg:g") - .attr("class", "stats_group") - .attr("transform", "translate(" + 115 + "," + 11 + ")"); - - var path_group = chart.append("svg:g") - .attr("class", "path_group") - .attr("transform", "translate(0," + (h / 4) + ")"); - var value_group = chart.append("svg:g") - .attr("class", "value_group") - .attr("transform", "translate(" + -(w * 0.205) + "," + -(h * 0.10) + ")"); - generateArcs(chart, data); - } - - function update(_oldData, _newData) { - if (_newData === undefined || _newData === null) { - return; - } - - var clone = jQuery.extend(true, {}, _newData); - var cloneOld = jQuery.extend(true, {}, _oldData); - var preparedData = setData(clone); - oldData = setData(cloneOld); - animate(preparedData); - } - - function animate(data) { generateArcs(null, data); } - - function setData(data) { - var diameter = 2 * Math.PI * radius; - var localData = []; - - $.each(data[0].segments, function(ri, value) { - - function calcAngles(v) { - var segmentValueSum = 200; - if (v > segmentValueSum) { - v = segmentValueSum; - } - - var segmentValue = v; - var fraction = segmentValue / segmentValueSum; - var arcBatchLength = fraction * 4 * Math.PI; - var arcPartition = arcBatchLength; - var startAngle = Math.PI * 2; - var endAngle = startAngle + arcPartition; - - return { - startAngle: startAngle, - endAngle: endAngle - }; - } - - var valueData = calcAngles(value.value); - data[0].segments[ri].startAngle = valueData.startAngle; - data[0].segments[ri].endAngle = valueData.endAngle; - - var maxData = value.maxData; - var maxTickData = calcAngles(maxData.maxValue + 0.2); - data[0].segments[ri].maxTickStartAngle = maxTickData.startAngle; - data[0].segments[ri].maxTickEndAngle = maxTickData.endAngle; - - var maxArcData = calcAngles(maxData.maxValue); - data[0].segments[ri].maxArcStartAngle = maxArcData.startAngle; - data[0].segments[ri].maxArcEndAngle = maxArcData.endAngle; - - data[0].segments[ri].index = ri; - }); - localData.push(data[0].segments); - return localData[0]; - } - - function generateArcs(_svg, data) { - var chart = svg; - var transitionTime = 750; - $.each(data, function(index, value) { - if (oldData[index] !== undefined) { - data[index].previousEndAngle = oldData[index].endAngle; - } else { - data[index].previousEndAngle = 0; - } - }); - var thickness = parseInt(scope.thickness, 10); - var ir = (parseInt(scope.graphWidth, 10) / 3); - var path_group = svg.select('.path_group'); - var arc_group = path_group.selectAll(".arc_group").data(data); - var arcEnter = arc_group.enter().append("g").attr("class", "arc_group"); - - arcEnter.append("path").attr("class", "bg-circle").attr("d", getBackgroundArc(thickness, ir)); - - arcEnter.append("path") - .attr("class", function(d, i) { return 'max_tick_arc ' + d.maxData.maxTickClassNames; }); - - arcEnter.append("path") - .attr("class", function(d, i) { return 'max_bg_arc ' + d.maxData.maxClassNames; }); - - arcEnter.append("path").attr("class", function(d, i) { return 'value_arc ' + d.classNames; }); - - var max_tick_arc = arc_group.select(".max_tick_arc"); - - max_tick_arc.transition() - .attr("class", function(d, i) { return 'max_tick_arc ' + d.maxData.maxTickClassNames; }) - .attr("d", function(d) { - var arc = maxArc(thickness, ir); - arc.startAngle(d.maxTickStartAngle); - arc.endAngle(d.maxTickEndAngle); - return arc(d); - }); - - var max_bg_arc = arc_group.select(".max_bg_arc"); - - max_bg_arc.transition() - .attr("class", function(d, i) { return 'max_bg_arc ' + d.maxData.maxClassNames; }) - .attr("d", function(d) { - var arc = maxArc(thickness, ir); - arc.startAngle(d.maxArcStartAngle); - arc.endAngle(d.maxArcEndAngle); - return arc(d); - }); - - var value_arc = arc_group.select(".value_arc"); - - value_arc.transition().ease("exp").attr("class", function(d, i) { - return 'value_arc ' + d.classNames; - }).duration(transitionTime).attrTween("d", function(d) { return arcTween(d, thickness, ir); }); - - arc_group.exit() - .select(".value_arc") - .transition() - .ease("exp") - .duration(transitionTime) - .attrTween("d", function(d) { return arcTween(d, thickness, ir); }) - .remove(); - - drawLabels(chart, data, ir, thickness); - buildLegend(chart, data); - } - - function arcTween(b, thickness, ir) { - var prev = JSON.parse(JSON.stringify(b)); - prev.endAngle = b.previousEndAngle; - var i = d3.interpolate(prev, b); - return function(t) { return getArc(thickness, ir)(i(t)); }; - } - - function maxArc(thickness, ir) { - var arc = d3.svg.arc().innerRadius(function(d) { - return getRadiusRing(ir, d.index); - }).outerRadius(function(d) { return getRadiusRing(ir + thickness, d.index); }); - return arc; - } - - function drawLabels(chart, data, ir, thickness) { - svg.select('.value_group').selectAll("*").remove(); - var counts = data.length; - var value_group = chart.select('.value_group'); - var valueLabels = value_group.selectAll("text.value").data(data); - valueLabels.enter() - .append("svg:text") - .attr("class", "value") - .attr("dx", function(d, i) { return 68; }) - .attr("dy", function(d, i) { return (thickness + 3) * i; }) - .attr("text-anchor", function(d) { return "start"; }) - .text(function(d) { return d.value; }); - valueLabels.transition().duration(300).attrTween( - "d", function(d) { return arcTween(d, thickness, ir); }); - valueLabels.exit().remove(); - } - - function buildLegend(chart, data) { - var svg = legendSvg; - svg.select('.label_group').selectAll("*").remove(); - svg.select('.legend_group').selectAll("*").remove(); - svg.select('.stats_group').selectAll("*").remove(); - - var host_name = svg.select('.hostName'); - var label_group = svg.select('.label_group'); - var stats_group = svg.select('.stats_group'); - - host_name.text(data[0].hostName); - - host_name = svg.selectAll("text.hostName").data(data); - - host_name.attr("text-anchor", function(d) { return "start"; }) - .text(function(d) { return d.hostName; }); - host_name.exit().remove(); - - var labels = label_group.selectAll("text.labels").data(data); - labels.enter() - .append("svg:text") - .attr("class", "labels") - .attr("dy", function(d, i) { return 19 * i; }) - .attr("text-anchor", function(d) { return "start"; }) - .text(function(d) { return d.label; }); - labels.exit().remove(); - - var stats = stats_group.selectAll("text.stats").data(data); - stats.enter() - .append("svg:text") - .attr("class", "stats") - .attr("dy", function(d, i) { return 19 * i; }) - .attr("text-anchor", function(d) { return "start"; }) - .text(function(d) { return d.stats; }); - stats.exit().remove(); - - var legend_group = svg.select('.legend_group'); - var legend = legend_group.selectAll("rect").data(data); - legend.enter() - .append("svg:rect") - .attr("x", 2) - .attr("y", function(d, i) { return 19 * i; }) - .attr("width", 13) - .attr("height", 13) - .attr("class", function(d, i) { return "rect " + d.classNames; }); - - legend.exit().remove(); - } - - function getRadiusRing(ir, i) { return ir - (i * 20); } - - function getArc(thickness, ir) { - var arc = d3.svg.arc() - .innerRadius(function(d) { return getRadiusRing(ir, d.index); }) - .outerRadius(function(d) { return getRadiusRing(ir + thickness, d.index); }) - .startAngle(function(d, i) { return d.startAngle; }) - .endAngle(function(d, i) { return d.endAngle; }); - return arc; - } - - function getBackgroundArc(thickness, ir) { - var arc = d3.svg.arc() - .innerRadius(function(d) { return getRadiusRing(ir, d.index); }) - .outerRadius(function(d) { return getRadiusRing(ir + thickness, d.index); }) - .startAngle(0) - .endAngle(function() { return 2 * Math.PI; }); - return arc; - } - - scope.render = function(data) { - if (data === undefined || data === null) { - return; - } - - d3.select(element[0]).select("svg.chart").remove(); - d3.select(element[0]).select("svg.legend").remove(); - - var graph = $(element[0]); - var w = scope.graphWidth; - var h = scope.graphHeight; - - var options = { - data: data, - width: w, - height: h - }; - - init(options); - }; - }; - d3DashboardService.d3().then(draw); - } - }; - } - ]); -}()); - -(function() { - 'use strict'; - - angular.module('kubernetesApp.components.dashboard') - .directive( - 'dashboardHeader', - function() { - 'use strict'; - return { - restrict: 'A', - replace: true, - scope: {user: '='}, - templateUrl: "components/dashboard/pages/header.html", - controller: [ - '$scope', - '$filter', - '$location', - 'menu', - '$rootScope', - function($scope, $filter, $location, menu, $rootScope) { - $scope.menu = menu; - $scope.$watch('page', function(newValue, oldValue) { - if (typeof newValue !== 'undefined') { - $location.path(newValue); - } - }); - $scope.subpages = [ - { - category: 'dashboard', - name: 'Explore', - value: '/dashboard/groups/type/selector/', - id: 'groupsView' - }, - {category: 'dashboard', name: 'Pods', value: '/dashboard/pods', id: 'podsView'}, - {category: 'dashboard', name: 'Nodes', value: '/dashboard/nodes', id: 'minionsView'}, - { - category: 'dashboard', - name: 'Replication Controllers', - value: '/dashboard/replicationcontrollers', - id: 'rcView' - }, - {category: 'dashboard', name: 'Services', value: '/dashboard/services', id: 'servicesView'}, - {category: 'dashboard', name: 'Events', value: '/dashboard/events', id: 'eventsView'}, - ]; - } - ] - }; - }) - .directive('dashboardFooter', - function() { - 'use strict'; - return { - restrict: 'A', - replace: true, - templateUrl: "components/dashboard/pages/footer.html", - controller: ['$scope', '$filter', function($scope, $filter) {}] - }; - }) - .directive('mdTable', function() { - 'use strict'; - return { - restrict: 'E', - scope: { - headers: '=', - content: '=', - sortable: '=', - filters: '=', - customClass: '=customClass', - thumbs: '=', - count: '=', - reverse: '=', - doSelect: '&onSelect' - }, - transclude: true, - controller: ["$scope", "$filter", "$window", "$location", function($scope, $filter, $window, $location) { - var orderBy = $filter('orderBy'); - $scope.currentPage = 0; - $scope.nbOfPages = function() { return Math.ceil($scope.content.length / $scope.count); }; - $scope.handleSort = function(field) { - if ($scope.sortable.indexOf(field) > -1) { - return true; - } else { - return false; - } - }; - $scope.order = function(predicate, reverse) { - $scope.content = orderBy($scope.content, predicate, reverse); - $scope.predicate = predicate; - }; - var reverse = false; - if($scope.reverse) - reverse = $scope.reverse; - - $scope.order($scope.sortable[0], reverse); - $scope.getNumber = function(num) { return new Array(num); }; - $scope.goToPage = function(page) { $scope.currentPage = page; }; - $scope.showMore = function() { return angular.isDefined($scope.moreClick);} - }], - templateUrl: 'views/partials/md-table.tmpl.html' - }; - }); - -}()); - -angular.module('kubernetesApp.components.dashboard') - .factory('d3DashboardService', [ - '$document', - '$q', - '$rootScope', - function($document, $q, $rootScope) { - var d = $q.defer(); - function onScriptLoad() { - // Load client in the browser - $rootScope.$apply(function() { d.resolve(window.d3); }); - } - // Create a script tag with d3 as the source - // and call our onScriptLoad callback when it - // has been loaded - var scriptTag = $document[0].createElement('script'); - scriptTag.type = 'text/javascript'; - scriptTag.async = true; - scriptTag.src = 'vendor/d3/d3.min.js'; - scriptTag.onreadystatechange = function() { - if (this.readyState == 'complete') onScriptLoad(); - }; - scriptTag.onload = onScriptLoad; - - var s = $document[0].getElementsByTagName('body')[0]; - s.appendChild(scriptTag); - - return { - d3: function() { return d.promise; } - }; - } - ]); - -(function() { - 'use strict'; - - angular.module('pods', []).service('podService', PodDataService); - - /** - * Pod DataService - * Mock async data service. - * - * @returns {{loadAll: Function}} - * @constructor - */ - function PodDataService($q) { - var pods = { - "kind": "Pod", - "apiVersion": "v1", - "metadata": { - "name": "redis-master-c0r1n", - "generateName": "redis-master-", - "namespace": "default", - "selfLink": "/api/v1/namespaces/default/pods/redis-master-c0r1n", - "uid": "f12ddfaf-ff77-11e4-8f2d-080027213276", - "resourceVersion": "39", - "creationTimestamp": "2015-05-21T05:12:14Z", - "labels": { - "name": "redis-master" - }, - "annotations": { - "kubernetes.io/created-by": "{\"kind\":\"SerializedReference\",\"apiVersion\":\"v1\",\"reference\":{\"kind\":\"ReplicationController\",\"namespace\":\"default\",\"name\":\"redis-master\",\"uid\":\"f12969e0-ff77-11e4-8f2d-080027213276\",\"apiVersion\":\"v1\",\"resourceVersion\":\"26\"}}" - } - }, - "spec": { - "volumes": [ - { - "name": "default-token-zb4rq", - "secret": { - "secretName": "default-token-zb4rq" - } - } - ], - "containers": [ - { - "name": "master", - "image": "redis", - "ports": [ - { - "containerPort": 6379, - "protocol": "TCP" - } - ], - "resources": {}, - "volumeMounts": [ - { - "name": "default-token-zb4rq", - "readOnly": true, - "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount" - } - ], - "terminationMessagePath": "/dev/termination-log", - "imagePullPolicy": "IfNotPresent", - "capabilities": {}, - "securityContext": { - "capabilities": {}, - "privileged": false - } - } - ], - "restartPolicy": "Always", - "dnsPolicy": "ClusterFirst", - "serviceAccount": "default", - "host": "127.0.0.1" - }, - "status": { - "phase": "Running", - "Condition": [ - { - "type": "Ready", - "status": "True" - } - ], - "hostIP": "127.0.0.1", - "podIP": "172.17.0.1", - "startTime": "2015-05-21T05:12:14Z", - "containerStatuses": [ - { - "name": "master", - "state": { - "running": { - "startedAt": "2015-05-21T05:12:14Z" - } - }, - "lastState": {}, - "ready": true, - "restartCount": 0, - "image": "redis", - "imageID": "docker://95af5842ddb9b03f7c6ec7601e65924cec516fcedd7e590ae31660057085cf67", - "containerID": "docker://ae2a1e0a91a8b1015191a0b8e2ce8c55a86fb1a9a2b1e8e3b29430c9d93c8c09" - } - ] - } -}; - - // Uses promises - return { - loadAll: function() { - // Simulate async call - return $q.when(pods); - } - }; - } - PodDataService.$inject = ["$q"]; - -})(); - -(function() { - 'use strict'; - - angular.module('replicationControllers', []) - .service('replicationControllerService', ReplicationControllerDataService); - - /** - * Replication Controller DataService - * Mock async data service. - * - * @returns {{loadAll: Function}} - * @constructor - */ - function ReplicationControllerDataService($q) { - var replicationControllers = { - "kind": "List", - "apiVersion": "v1", - "metadata": {}, - "items": [ - { - "kind": "ReplicationController", - "apiVersion": "v1", - "metadata": { - "name": "redis-master", - "namespace": "default", - "selfLink": "/api/v1/namespaces/default/replicationcontrollers/redis-master", - "uid": "f12969e0-ff77-11e4-8f2d-080027213276", - "resourceVersion": "28", - "creationTimestamp": "2015-05-21T05:12:14Z", - "labels": { - "name": "redis-master" - } - }, - "spec": { - "replicas": 1, - "selector": { - "name": "redis-master" - }, - "template": { - "metadata": { - "creationTimestamp": null, - "labels": { - "name": "redis-master" - } - }, - "spec": { - "containers": [ - { - "name": "master", - "image": "redis", - "ports": [ - { - "containerPort": 6379, - "protocol": "TCP" - } - ], - "resources": {}, - "terminationMessagePath": "/dev/termination-log", - "imagePullPolicy": "IfNotPresent", - "capabilities": {}, - "securityContext": { - "capabilities": {}, - "privileged": false - } - } - ], - "restartPolicy": "Always", - "dnsPolicy": "ClusterFirst", - "serviceAccount": "" - } - } - }, - "status": { - "replicas": 1 - } - } - ]}; - - // Uses promises - return { - loadAll: function() { - // Simulate async call - return $q.when(replicationControllers); - } - }; - } - ReplicationControllerDataService.$inject = ["$q"]; - -})(); - -(function() { - 'use strict'; - - angular.module('services', []).service('serviceService', ServiceDataService); - - /** - * Service DataService - * Mock async data service. - * - * @returns {{loadAll: Function}} - * @constructor - */ - function ServiceDataService($q) { - var services = { - "kind": "List", - "apiVersion": "v1", - "metadata": {}, - "items": [ - { - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "kubernetes", - "namespace": "default", - "selfLink": "/api/v1/namespaces/default/services/kubernetes", - "resourceVersion": "6", - "creationTimestamp": null, - "labels": { - "component": "apiserver", - "provider": "kubernetes" - } - }, - "spec": { - "ports": [ - { - "protocol": "TCP", - "port": 443, - "targetPort": 443 - } - ], - "portalIP": "10.0.0.2", - "sessionAffinity": "None" - }, - "status": {} - }, - { - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "kubernetes-ro", - "namespace": "default", - "selfLink": "/api/v1/namespaces/default/services/kubernetes-ro", - "resourceVersion": "8", - "creationTimestamp": null, - "labels": { - "component": "apiserver", - "provider": "kubernetes" - } - }, - "spec": { - "ports": [ - { - "protocol": "TCP", - "port": 80, - "targetPort": 80 - } - ], - "portalIP": "10.0.0.1", - "sessionAffinity": "None" - }, - "status": {} - }, - { - "kind": "Service", - "apiVersion": "v1", - "metadata": { - "name": "redis-master", - "namespace": "default", - "selfLink": "/api/v1/namespaces/default/services/redis-master", - "uid": "a6fde246-ff78-11e4-8f2d-080027213276", - "resourceVersion": "72", - "creationTimestamp": "2015-05-21T05:17:19Z", - "labels": { - "name": "redis-master" - } - }, - "spec": { - "ports": [ - { - "protocol": "TCP", - "port": 6379, - "targetPort": 6379 - } - ], - "selector": { - "name": "redis-master" - }, - "portalIP": "10.0.0.124", - "sessionAffinity": "None" - }, - "status": {} - } - ] -}; - - // Uses promises - return { - loadAll: function() { - // Simulate async call - return $q.when(services); - } - }; - } - ServiceDataService.$inject = ["$q"]; - -})(); -`) - -func www_app_assets_js_app_js_bytes() ([]byte, error) { - return _www_app_assets_js_app_js, nil -} - -func www_app_assets_js_app_js() (*asset, error) { - bytes, err := www_app_assets_js_app_js_bytes() - if err != nil { - return nil, err - } - - info := bindata_file_info{name: "www/app/assets/js/app.js", size: 91996, mode: os.FileMode(416), modTime: time.Unix(1436215736, 0)} - a := &asset{bytes: bytes, info: info} - return a, nil -} - -var _www_app_assets_js_base_js = []byte(`!function(e,t){"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){function n(e){var t=e.length,n=Z.type(e);return"function"===n||Z.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e}function r(e,t,n){if(Z.isFunction(t))return Z.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return Z.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(ae.test(t))return Z.filter(t,e,n);t=Z.filter(t,e)}return Z.grep(e,function(e){return U.call(t,e)>=0!==n})}function i(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}function o(e){var t=he[e]={};return Z.each(e.match(de)||[],function(e,n){t[n]=!0}),t}function s(){J.removeEventListener("DOMContentLoaded",s,!1),e.removeEventListener("load",s,!1),Z.ready()}function a(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=Z.expando+a.uid++}function u(e,t,n){var r;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(be,"-$1").toLowerCase(),n=e.getAttribute(r),"string"==typeof n){try{n="true"===n?!0:"false"===n?!1:"null"===n?null:+n+""===n?+n:xe.test(n)?Z.parseJSON(n):n}catch(i){}ye.set(e,t,n)}else n=void 0;return n}function l(){return!0}function c(){return!1}function f(){try{return J.activeElement}catch(e){}}function p(e,t){return Z.nodeName(e,"table")&&Z.nodeName(11!==t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function d(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function h(e){var t=Pe.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function g(e,t){for(var n=0,r=e.length;r>n;n++)ve.set(e[n],"globalEval",!t||ve.get(t[n],"globalEval"))}function m(e,t){var n,r,i,o,s,a,u,l;if(1===t.nodeType){if(ve.hasData(e)&&(o=ve.access(e),s=ve.set(t,o),l=o.events)){delete s.handle,s.events={};for(i in l)for(n=0,r=l[i].length;r>n;n++)Z.event.add(t,i,l[i][n])}ye.hasData(e)&&(a=ye.access(e),u=Z.extend({},a),ye.set(t,u))}}function v(e,t){var n=e.getElementsByTagName?e.getElementsByTagName(t||"*"):e.querySelectorAll?e.querySelectorAll(t||"*"):[];return void 0===t||t&&Z.nodeName(e,t)?Z.merge([e],n):n}function y(e,t){var n=t.nodeName.toLowerCase();"input"===n&&Ne.test(e.type)?t.checked=e.checked:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}function x(t,n){var r,i=Z(n.createElement(t)).appendTo(n.body),o=e.getDefaultComputedStyle&&(r=e.getDefaultComputedStyle(i[0]))?r.display:Z.css(i[0],"display");return i.detach(),o}function b(e){var t=J,n=$e[e];return n||(n=x(e,t),"none"!==n&&n||(We=(We||Z("