diff --git a/.gitignore b/.gitignore
index 8634f93d0..18a9ba4fd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -69,9 +69,6 @@ depcomp
/cockpit-askpass
/cockpit-session
/cockpit-ssh
-/cockpit-stub
-/cockpit-kube-auth
-/cockpit-kube-launch
/test-session
/cockpit-bridge
/remotectl
@@ -160,8 +157,6 @@ po*.js.gz
/pkg/*/cockpit-components-*.js
/pkg/*/cockpit-components-*.js
-/pkg/kubernetes/kubernetes-templates.js
-/pkg/kubernetes/registry-templates.js
/pkg/playground/react-demo-*.js
/pkg/selinux/setroubleshoot-view.js
/pkg/tuned/change-profile.js
diff --git a/Makefile.am b/Makefile.am
index 78514950f..b7e5df42b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -154,7 +154,6 @@ WEBPACK_PACKAGES = \
dashboard \
docker \
kdump \
- kubernetes \
machines \
networkmanager \
pcp \
diff --git a/Vagrantfile b/Vagrantfile
index ce132bdcc..4c23e638a 100644
--- a/Vagrantfile
+++ b/Vagrantfile
@@ -48,7 +48,6 @@ Vagrant.configure(2) do |config|
etcd \
firewalld \
git \
- kubernetes \
NetworkManager \
pcp \
qemu \
diff --git a/bots/npm-update b/bots/npm-update
index 6551fdd5d..7a1f13d6d 100755
--- a/bots/npm-update
+++ b/bots/npm-update
@@ -20,16 +20,12 @@
# To use this example add a line to an issue with the "bot" label
#
-# * [ ] npm-update angular
+# * [ ] npm-update patternfly
#
# Dependencies that are either fragile (minor updates break)
# or are part of our public Javascript API and need caution
FRAGILE = [
- "angular",
- "angular-bootstrap-npm",
- "angular-gettext",
- "angular-route",
"jquery",
"patternfly",
"paternfly-bootstrap-combobox",
diff --git a/doc/guide/Makefile-guide.am b/doc/guide/Makefile-guide.am
index 941b1745f..4fc702902 100644
--- a/doc/guide/Makefile-guide.am
+++ b/doc/guide/Makefile-guide.am
@@ -26,7 +26,6 @@ GUIDE_INCLUDES = \
doc/guide/feature-docker.xml \
doc/guide/feature-firewall.xml \
doc/guide/feature-journal.xml \
- doc/guide/feature-kubernetes.xml \
doc/guide/feature-machines.xml \
doc/guide/feature-networkmanager.xml \
doc/guide/feature-packagekit.xml \
diff --git a/doc/guide/cockpit-guide.xml b/doc/guide/cockpit-guide.xml
index ebf224222..30ed58543 100644
--- a/doc/guide/cockpit-guide.xml
+++ b/doc/guide/cockpit-guide.xml
@@ -45,7 +45,6 @@
-
diff --git a/doc/guide/feature-kubernetes.xml b/doc/guide/feature-kubernetes.xml
deleted file mode 100644
index 61d81143b..000000000
--- a/doc/guide/feature-kubernetes.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
- Kubernetes
-
- Cockpit has a dashboard that interacts with a
- Kubernetes cluster or an
- Openshift v3 cluster . This
- functionality is in the Cockpit kubernetes package.
-
- The dashboard is part of a normal authenticated Cockpit session. Cockpit
- communicates with Kubernetes via its REST API.
-
- Usually some form of authentication is necessary to access the Kubernetes REST API.
- Like the kubectl and oc commands, Cockpit uses
- the authentication and server information in the ~/.kube/config
file for
- the logged in user.
-
- If a user is able to use kubectl
successfully when at their shell terminal,
- then that same user will able to use Kubernetes dashboard when logged into Cockpit:
-
-
-$ kubectl get pods
-NAME READY STATUS RESTARTS AGE
-docker-registry-1-l4pyh 1/1 Running 10 23d
-...
-
-
- When running Openshift one can use the oc login
command to configure the
- ~/.kube/config
file correctly. This in turn allows Cockpit to use that
- login information.
-
-
diff --git a/package.json b/package.json
index 8c6510fbf..c900e9430 100644
--- a/package.json
+++ b/package.json
@@ -5,10 +5,6 @@
"dependencies": {
"@babel/polyfill": "7.4.4",
"@patternfly/react-console": "1.10.50",
- "angular": "1.3.20",
- "angular-bootstrap-npm": "0.13.4",
- "angular-gettext": "2.3.11",
- "angular-route": "1.3.20",
"bootstrap": "3.4.1",
"bootstrap-datepicker": "1.9.0",
"c3": "0.4.23",
@@ -17,12 +13,8 @@
"jquery-flot": "0.8.3",
"js-sha1": "0.6.0",
"json-stable-stringify-without-jsonify": "1.0.1",
- "kubernetes-container-terminal": "1.0.3",
- "kubernetes-object-describer": "1.1.4",
- "kubernetes-topology-graph": "0.0.25",
"moment": "2.24.0",
"mustache": "3.0.1",
- "object-describer": "git+https://github.com/kubernetes-ui/object-describer.git#v1.0.4",
"patternfly": "3.58.0",
"patternfly-bootstrap-combobox": "1.1.7",
"patternfly-react": "2.34.3",
@@ -64,7 +56,6 @@
"eslint-plugin-promise": "^4.0.1",
"eslint-plugin-react": "7.13.0",
"eslint-plugin-standard": "^4.0.0",
- "exports-loader": "~0.6.3",
"extend": "~3.0.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"html-webpack-plugin": "^3.2.0",
diff --git a/pkg/Makefile.am b/pkg/Makefile.am
index 322ff0713..846696ac4 100644
--- a/pkg/Makefile.am
+++ b/pkg/Makefile.am
@@ -34,39 +34,3 @@ EXTRA_DIST += \
$(metainfo_DATA) \
$(pixmaps_DATA) \
$(NULL)
-
-if WITH_GOLANG
-
-AM_V_GO = $(am__v_GO_@AM_V@)
-am__v_GO_ = $(am__v_GO_@AM_DEFAULT_V@)
-am__v_GO_0 = @echo " GO " $@;
-
-GO_BUILD_RULE = \
- GOPATH=$(abs_srcdir)/pkg/kubernetes/standalone $(GOLANG) build \
- -ldflags "-B 0x"`head -c20 /dev/urandom|od -An -tx1|tr -d ' \n'` "$@"
-
-COCKPIT_KUBE_HELPERS = \
- pkg/kubernetes/standalone/src/cockpit-kube-auth/helpers/creds.go \
- pkg/kubernetes/standalone/src/cockpit-kube-auth/helpers/client.go \
- $(NULL)
-
-COCKPIT_KUBE_AUTH = $(COCKPIT_KUBE_HELPERS) \
- pkg/kubernetes/standalone/src/cockpit-kube-auth/main.go \
- $(NULL)
-
-COCKPIT_KUBE_LAUNCH = $(COCKPIT_KUBE_HELPERS) \
- pkg/kubernetes/standalone/src/cockpit-kube-launch/main.go \
- $(NULL)
-
-cockpit-kube-auth$(EXEEXT): $(COCKPIT_KUBE_AUTH)
- $(AM_V_GO) $(GO_BUILD_RULE)
-
-cockpit-kube-launch$(EXEEXT): $(COCKPIT_KUBE_LAUNCH)
- $(AM_V_GO) $(GO_BUILD_RULE)
-
-libexec_PROGRAMS += cockpit-kube-auth cockpit-kube-launch
-
-cockpit_kube_auth_SOURCES = $(COCKPIT_KUBE_AUTH)
-cockpit_kube_launch_SOURCES = $(COCKPIT_KUBE_LAUNCH)
-
-endif
diff --git a/pkg/kubernetes/README.md b/pkg/kubernetes/README.md
deleted file mode 100644
index 885e3bdc5..000000000
--- a/pkg/kubernetes/README.md
+++ /dev/null
@@ -1,22 +0,0 @@
-Developing the kubernetes component
------------------------------------
-
-This component adds functionality to Cockpit to perform admin tasks on
-Kubernetes or Openshift. You'll see a "Cluster" tab listed in Cockpit.
-
-### Running a test instance
-
-There's a test instance of Openshift (and also Kubernetes) that's you
-can run using the following command:
-
- $ bots/vm-run openshift
-
-To then access that it run the following in another terminal:
-
- $ sudo yum install kubernetes-client
- $ mkdir -p ~/.kube
- $ cp bots/images/files/openshift.kubeconfig ~/.kube/config
-
-You should now be able to use the kubectl command to access the cluster:
-
- $ kubectl get pods
diff --git a/pkg/kubernetes/index.html b/pkg/kubernetes/index.html
deleted file mode 100644
index 07dd948ed..000000000
--- a/pkg/kubernetes/index.html
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
-
-
-
- Kubernetes Cluster
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Connecting...
-
Couldn't connect to server
-
{{curtains.message}}
-
- Reconnect
- Troubleshoot
-
-
-
-
diff --git a/pkg/kubernetes/manifest.json.in b/pkg/kubernetes/manifest.json.in
deleted file mode 100644
index b0ffab22f..000000000
--- a/pkg/kubernetes/manifest.json.in
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "version": "@VERSION@",
- "requires": {
- "cockpit": "137.x"
- },
-
- "dashboard": {
- "index": {
- "label": "Cluster",
- "order": 20,
- "icon": "pficon-cluster"
- }
- }
-}
diff --git a/pkg/kubernetes/override.json b/pkg/kubernetes/override.json
deleted file mode 100644
index 73a28e673..000000000
--- a/pkg/kubernetes/override.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "dashboard": {
- "registry": {
- "label": "Image Registry",
- "order": 30,
- "icon": "pficon-registry"
- }
- }
-}
diff --git a/pkg/kubernetes/registry.html b/pkg/kubernetes/registry.html
deleted file mode 100644
index 96fcb5dc3..000000000
--- a/pkg/kubernetes/registry.html
+++ /dev/null
@@ -1,80 +0,0 @@
-
-
-
-
-
-Image Registry
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Connecting...
-
Couldn't connect to server
-
{{curtains.message}}
-
- Reconnect
-
-
-
-
-
diff --git a/pkg/kubernetes/scripts/app.js b/pkg/kubernetes/scripts/app.js
deleted file mode 100644
index f9cbfa864..000000000
--- a/pkg/kubernetes/scripts/app.js
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
- require('angular-bootstrap-npm/dist/angular-bootstrap.js');
-
- require('./kube-client');
- require('./kube-client-cockpit');
- require('./connection');
-
- require('../views/auth-dialog.html');
- require('../views/filter-bar.html');
- require('../views/filter-project.html');
-
- angular.module('kubernetes.app', [
- 'ui.bootstrap',
- 'kubeClient',
- 'kubeClient.cockpit',
- 'kubernetes.connection'
- ])
-
- .controller('MainCtrl', [
- '$scope',
- '$location',
- '$rootScope',
- '$timeout',
- '$modal',
- 'kubeLoader',
- 'kubeSelect',
- 'KubeDiscoverSettings',
- 'filterService',
- 'connectionActions',
- function($scope, $location, $rootScope, $timeout, $modal,
- loader, select, discoverSettings, filter, connectionActions) {
- $scope.settings = { };
-
- /* Used to set detect which route is active */
- $scope.viewActive = function(segment) {
- var url = $location.url() || "/";
- var parts = url.split('?')[0].split("/");
- if (!segment && !parts[1])
- return true;
- if (segment === parts[1])
- return true;
- return false;
- };
-
- /* Used to build simple route URLs */
- $scope.viewUrl = function(segment, forceQS) {
- var namespace = loader.limits.namespace;
- var path;
- var parts = [];
- if (angular.isArray(namespace))
- namespace = null;
-
- if (segment)
- parts.push(segment);
- else
- forceQS = true;
-
- if (!forceQS && namespace)
- parts.push(namespace);
-
- path = "/" + parts.map(encodeURIComponent).join("/");
- if (namespace && forceQS)
- return path + "?namespace=" + encodeURIComponent(namespace);
- else
- return path;
- };
-
- /* Used while debugging */
- $scope.console = console;
-
- /* Show the body when ready */
- function visible() {
- document.getElementsByTagName("body")[0].removeAttribute("hidden");
- }
-
- /* Show after some seconds whether ready or not */
- $timeout(visible, 3000);
-
- /* Curtains related logic */
- function connect(force) {
- $scope.curtains = { };
- discoverSettings(force).then(function(settings) {
- $scope.settings = settings;
- $scope.curtains = null;
- filter.globals(settings.isAdmin);
- filter.load().then(visible);
- }, function(resp) {
- $scope.curtains = {
- status: resp.status,
- resp: resp,
- message: resp.message || resp.statusText,
- };
- $scope.settings = null;
- visible();
- });
- }
-
- /* Connect automatically initially */
- connect();
-
- /* Used by reconnect buttons */
- $scope.reconnect = function(force) {
- if (force === undefined)
- force = true;
-
- discoverSettings(force);
- loader.reset();
- connect();
- };
-
- /* When the loader changes digest */
- loader.listen(function() {
- $rootScope.$applyAsync();
- }, $rootScope);
-
- $scope.changeAuth = function(ex) {
- var promise = $modal.open({
- animation: false,
- controller: 'ChangeAuthCtrl',
- templateUrl: 'views/auth-dialog.html',
- resolve: {
- dialogData: function() {
- return connectionActions.load(ex);
- }
- },
- }).result;
-
- /* If the change is successful, reconnect */
- promise.then(function(force) {
- $scope.reconnect(force);
- });
- return promise;
- };
- }
- ])
-
- .directive('filterBar', [
- 'filterService',
- function(filter) {
- return {
- restrict: 'E',
- scope: true,
- transclude: true,
- link: function(scope, element, attrs) {
- scope.filter = filter;
- },
- templateUrl: 'views/filter-bar.html'
- };
- }
- ])
-
- .directive('filterProject', [
- 'filterService',
- function(filter) {
- return {
- restrict: 'E',
- scope: true,
- link: function(scope, element, attrs) {
- scope.filter = filter;
- },
- templateUrl: 'views/filter-project.html'
- };
- }
- ])
-
- .factory('filterService', [
- '$q',
- '$route',
- '$rootScope',
- 'kubeLoader',
- 'kubeSelect',
- 'KubeDiscoverSettings',
- function($q, $route, $rootScope, loader, select, discoverSettings) {
- /*
- * We have the following cases to account for:
- *
- * Openshift:
- * - Have Project objects
- * - Project objects are listable by any user, only accessilbe returned
- *
- * Kubernetes and Openshift
- * - Namespace objects are only accessible to all users
- *
- * The globals variable is set based on this.
- */
-
- var globals = true;
-
- var promise = discoverSettings().then(function(settings) {
- var ret = [];
- if (settings.flavor === "openshift") {
- ret.push(loader.watch("projects", $rootScope));
- ret.push(loader.load("projects"));
- }
- if (settings.isAdmin)
- ret.push(loader.watch("namespaces", $rootScope));
- return $q.all(ret);
- });
-
- /*
- * When either a Namespace or Project is loaded we'll want to reinterpret
- * how we look at the current namespace. This helps to handle cases where
- * the user can't see all projects, and one is loaded.
- */
- loader.listen(function(present) {
- var link, object;
- for (link in present) {
- object = present[link];
- if (object.kind == "Namespace" || object.kind == "Project") {
- loadNamespace($route.current);
- return;
- }
- }
- });
-
- function calcAvailable() {
- var all;
- if (globals)
- all = select().kind("Namespace");
- if (!all || all.length === 0)
- all = select().kind("Project")
- .statusPhase("Active");
-
- var link, meta;
- var ret = [];
- for (link in all) {
- meta = all[link].metadata || { };
- if (meta.name)
- ret.push(meta.name);
- }
-
- return ret;
- }
-
- function loadNamespace(route) {
- var value = null;
- if (route)
- value = route.params["namespace"] || null;
-
- /*
- * When we can't see globals, we tell the loader about
- * all namespaces that we can see. It'll open up individual
- * watches about those namespaces.
- */
- if (value === null && !globals) {
- value = calcAvailable();
- /* We might not be global, but the projects may not
- * be loaded yet */
- if (value.length < 1)
- value = null;
- }
-
- if (!angular.equals(value, loader.limits.namespaces)) {
- loader.limit({ namespace: value });
- }
- }
-
- $rootScope.$on("$routeChangeSuccess", function (event, current, prev) {
- loadNamespace(current);
- });
-
- $rootScope.$on("$routeUpdate", function (event, current, prev) {
- loadNamespace(current);
- });
-
- if ($route.current)
- loadNamespace($route.current);
-
- return {
- load: function() {
- return promise;
- },
- globals: function(value) {
- if (arguments.length === 0)
- return globals;
- value = !!value;
- if (globals !== value) {
- globals = value;
- loadNamespace($route.current);
- }
- },
- namespaces: calcAvailable,
- namespace: function(value) {
- if (arguments.length === 0)
- return $route.current.params["namespace"];
- var copy = angular.copy($route.current.params);
- copy["namespace"] = value || undefined;
- copy["target"] = null;
- $route.updateParams(copy);
- }
- };
- }
- ])
-
- /* The default orderBy filter doesn't work on objects */
- .filter('orderObjectBy', function() {
- return function(items, field) {
- var i;
- var sorted = [];
- for (i in items)
- sorted.push(items[i]);
- if (!angular.isArray(field))
- field = [ String(field) ];
- var criteria = field.map(function(v) {
- return v.split('.');
- });
- function value(obj, x) {
- return obj ? obj[x] : undefined;
- }
- sorted.sort(function(a, b) {
- var ra, rb, i;
- var len = criteria.length;
- for (i = 0; i < len; i++) {
- ra = criteria[i].reduce(value, a);
- rb = criteria[i].reduce(value, b);
- if (ra === rb)
- continue;
- return (ra > rb ? 1 : -1);
- }
- return 0;
- });
- return sorted;
- };
- })
-
- .filter("formatBytes", [
- "KubeFormat",
- function(format) {
- return function(num) {
- if (typeof num == "number")
- return format.formatBytes(num);
- return num;
- };
- }]);
-}());
diff --git a/pkg/kubernetes/scripts/charts.js b/pkg/kubernetes/scripts/charts.js
deleted file mode 100644
index 032232a93..000000000
--- a/pkg/kubernetes/scripts/charts.js
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
- require('angular-bootstrap-npm/dist/angular-bootstrap.js');
-
- var d3 = require('d3');
-
- var focusedClasses = {
- "chart-focused": true,
- "chart-unfocused": false
- };
- var unfocusedClasses = {
- "chart-focused": false,
- "chart-unfocused": true
- };
- var focusResetClasses = {
- "chart-focused": false,
- "chart-unfocused": false
- };
-
- function parsePXVal(val) {
- var n;
- if (val)
- n = parseInt(val.slice(0, val.length - 2), 10);
-
- if (!n || isNaN(n))
- n = 0;
-
- return n;
- }
-
- function getPadding(el) {
- // May return null on FF when iframe is hidden.
- var style = window.getComputedStyle(el, null);
- if (style) {
- return {
- left: parsePXVal(style.getPropertyValue('padding-left')),
- right: parsePXVal(style.getPropertyValue('padding-right')),
- top: parsePXVal(style.getPropertyValue('padding-top')),
- bottom: parsePXVal(style.getPropertyValue('padding-bottom'))
- };
- } else {
- return {
- left: 0,
- right: 0,
- top: 0,
- bottom: 0
- };
- }
- }
-
- function getSize(el) {
- var p = getPadding(el);
- var width = el.clientWidth - p.left - p.right;
- var height = el.clientHeight - p.top - p.bottom;
-
- if (width < 0)
- width = 0;
- if (height < 0)
- height = 0;
-
- return {
- width: width,
- height: height
- };
- }
-
- angular.module('ui.charts', [
- 'ui.bootstrap',
- ])
-
- .directive('thresholdHeatMap', [
- "$window",
- "KubeTranslate",
- "$timeout",
- function ($window, translate, $timeout) {
- const _ = translate.gettext;
-
- return {
- restrict: 'A',
- scope: {
- data: '=?',
- legendLabels: '=?',
- thresholds: '=?',
- colors: '=?',
- },
- link: function($scope, element, attributes) {
- var data;
- var padding = 2;
- var thresholdDefaults = [0, 0.7, 0.8, 0.9];
- var heatmapColorDefaults = ['#bbbbbb', '#d4f0fa', '#F9D67A', '#EC7A08', '#CE0000'];
- var legendLabelDefaults = [_("Unavailable"), '< 70%', '70-80%', '80-90%', '> 90%'];
-
- var maxSize = attributes['maxBlockSize'];
- if (!maxSize || isNaN(maxSize)) {
- maxSize = 64;
- } else {
- maxSize = parseInt(maxSize, 10);
- if (maxSize < 5)
- maxSize = 5;
- else if (maxSize > 64)
- maxSize = 64;
- }
-
- if (!$scope.thresholds)
- $scope.thresholds = thresholdDefaults;
-
- if (!$scope.colors)
- $scope.colors = heatmapColorDefaults;
-
- if (!$scope.legendLabels)
- $scope.legendLabels = legendLabelDefaults;
-
- var svg = d3.select(element[0]).append("svg")
- .classed("heatmap-pf-svg", true)
- .style("width", "100%");
-
- if (attributes['legend'])
- buildLegend();
-
- function getBlockSize(n, x, y) {
- if (x < 1 || y < 1)
- return 0;
-
- if (n === 0)
- return maxSize;
-
- var px = Math.ceil(Math.sqrt(n * x / y));
- var py = Math.ceil(Math.sqrt(n * y / x));
- var sx, sy;
-
- if (Math.floor(px * y / x) * px < n)
- sx = y / Math.ceil(px * y / x);
- else
- sx = x / px;
-
- if (Math.floor(py * x / y) * py < n)
- sy = x / Math.ceil(x * py / y);
- else
- sy = y / py;
-
- return Math.max(sx, sy);
- }
-
- function getSizeInfo() {
- var length = data ? data.length : 0;
- var size = getSize(element[0]);
- var h = size.height;
- var w = size.width;
-
- var rows;
-
- var blockSize = getBlockSize(length, w, h);
- if ((blockSize - padding) > maxSize) {
- blockSize = padding + maxSize;
-
- // Attempt to square off the area, check if square fits
- rows = Math.ceil(Math.sqrt(length));
- if (blockSize * rows > w ||
- blockSize * rows > h) {
- rows = (blockSize === 0) ? 0 : Math.floor(h / blockSize);
- }
- } else {
- rows = (blockSize === 0) ? 0 : Math.floor(h / blockSize);
- }
- return {
- rows: rows,
- block: blockSize
- };
- }
-
- function buildLegend() {
- var colors = $scope.colors.slice(0);
- var labels = $scope.legendLabels.slice(0);
-
- labels.reverse();
- colors.reverse();
-
- var legend = d3.select("#" + attributes['legend'])
- .append('ul')
- .classed('chart-legend', true);
-
- var li = legend.selectAll("li").data(labels);
-
- var newLi = li.enter().append("li")
- .classed('chart-legend-item', true)
- .on("mouseover", function(d, i) {
- var color = colors[i];
- var rsel = "rect[data-color='" + color + "']";
- var lsel = "li[data-color='" + color + "']";
-
- legend.selectAll("li").classed(unfocusedClasses);
- legend.select(lsel).classed(focusedClasses);
-
- svg.selectAll("rect").classed(unfocusedClasses);
- svg.selectAll(rsel).classed(focusedClasses);
- })
- .on("mouseout", function (d, i) {
- svg.selectAll("rect").classed(focusResetClasses);
- legend.selectAll("li").classed(focusResetClasses);
- });
-
- newLi.append("span")
- .classed('legend-pf-color-box', true);
-
- newLi.append("span")
- .classed('legend-pf-text', true);
-
- li.attr("data-color", function (d, i) {
- return colors[i];
- });
-
- li.select("span.legend-pf-color-box")
- .style("background-color", function (d, i) {
- return colors[i];
- });
-
- li.select("span.legend-pf-text")
- .text(function (d) {
- return d;
- });
- }
-
- function getcolor(d, colorFunc) {
- var value = d;
- if (d && d.value !== undefined)
- value = d.value;
-
- if (isNaN(value))
- value = -1;
-
- return colorFunc(value);
- }
-
- function refresh() {
- var colorFunc = d3.scale.threshold()
- .domain($scope.thresholds)
- .range($scope.colors);
-
- var size = getSizeInfo();
- if (!data)
- data = [ ];
-
- var fillSize = size.block - padding;
- if (fillSize < 1)
- return;
-
- svg.attr("height", size.block * size.rows);
- var blocks = svg.selectAll('rect').data(data);
-
- blocks.enter().append('rect')
- .on("mouseover", function(d, i) {
- svg.selectAll('rect').classed(unfocusedClasses);
- d3.select(this).classed(focusedClasses);
- })
- .on("mouseout", function (d, i) {
- svg.selectAll('rect').classed(focusResetClasses);
- })
- .append("title");
-
- blocks
- .attr('x', function (d, i) {
- return Math.floor(i / size.rows) * size.block;
- })
- .attr('y', function (d, i) {
- return i % size.rows * size.block;
- })
- .attr('width', fillSize)
- .attr('height', fillSize)
- .attr('data-color', function (d) {
- return getcolor(d, colorFunc);
- })
- .style('fill', function (d) {
- return getcolor(d, colorFunc);
- })
- .on('click', function (d) {
- if (d && d.name)
- $scope.$emit("boxClick", d.name);
- })
- .select("title")
- .text(function(d) {
- return d.tooltip;
- });
-
- blocks.exit().remove();
- }
-
- $scope.$watchCollection('data', function(newValue) {
- data = newValue;
- refresh();
- });
-
- angular.element($window).bind('resize', function () {
- refresh();
- });
-
- $scope.$watch(
- function () {
- return [element[0].offsetWidth, element[0].offsetHeight].join('x');
- },
- function (value) {
- refresh();
- }
- );
- }
- };
- }
- ])
-
- .directive('donutPctChart', [
- "$window",
- function ($window) {
- return {
- restrict: 'A',
- scope: {
- data: '=?',
- largeTitle: '=?',
- smallTitle: '=?',
- },
- link: function($scope, element, attributes) {
- var arc, selectedArc, data;
- var colors = d3.scale.category20();
-
- var pie = d3.layout.pie().value(function (d) {
- if (typeof d === 'object')
- return d.value;
- else
- return d;
- });
-
- var legend;
- if (attributes['legend']) {
- legend = d3.select("#" + attributes['legend'])
- .append('ul')
- .classed('chart-legend', true);
- }
-
- var svg = d3.select(element[0]).append("svg");
- svg.style("width", "100%");
- svg.style("height", "100%");
-
- var g = svg.append("g");
- g.append('text').attr('class', "chart-title");
-
- function updateSize() {
- var size = getSize(element[0]);
- var width = size.width;
- var height = size.height;
- var c;
- var radius = Math.min(width, height) / 2;
- var barSize = parseInt(attributes['barSize'], 10);
- if (isNaN(barSize))
- barSize = 20;
-
- if ((barSize * 2) > radius)
- barSize = radius;
-
- arc = d3.svg.arc()
- .innerRadius(radius - (barSize * 2))
- .outerRadius(radius - barSize);
-
- selectedArc = d3.svg.arc()
- .innerRadius(radius - (barSize * 2))
- .outerRadius(radius - (barSize - 2));
-
- c = (radius - barSize - 2) * 2;
- g.attr('data-innersize', Math.sqrt((c * c) / 2));
- updateTitle();
-
- g.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
- refresh();
- }
-
- function calFontSize() {
- var width = this.getComputedTextLength();
- var inner = parseInt(g.attr("data-innersize"), 10);
- var style = window.getComputedStyle(this, null);
- var size, ratio;
-
- if (style && width) {
- size = style.getPropertyValue('font-size');
- ratio = inner / width;
- } else {
- width = 0;
- }
-
- if (!isNaN(inner) && width > inner)
- return "calc(" + size + " * " + ratio + ")";
- }
-
- function updateTitle() {
- var title = g.select('text.chart-title');
- var size = parseInt(g.attr("data-innersize"), 10);
- if (isNaN(size))
- return;
-
- title.selectAll('tspan').remove();
- if ($scope.largeTitle) {
- title.insert('tspan').text($scope.largeTitle)
- .classed('donut-title-big-pf', true)
- .attr('dy', 0)
- .attr('x', 0)
- .style("font-size", calFontSize);
- }
-
- if ($scope.smallTitle) {
- title.insert('tspan').text($scope.smallTitle)
- .classed('donut-title-small-pf', true)
- .attr('dy', 20)
- .attr('x', 0)
- .style("font-size", calFontSize);
- }
- }
-
- function select(id) {
- var sel = "path[data-id='" + id + "']";
- var lsel = "li[data-id='" + id + "']";
- g.selectAll("path").classed(unfocusedClasses);
-
- g.select(sel).attr("d", function (d, i) {
- return selectedArc(d, i);
- });
- g.select(sel).classed(focusedClasses);
-
- if (legend) {
- legend.selectAll("li").classed(unfocusedClasses);
- legend.select(lsel).classed(focusedClasses);
- }
- }
-
- function unselect() {
- g.selectAll("path")
- .classed(focusResetClasses)
- .attr("d", arc);
- if (legend) {
- legend.selectAll("li")
- .classed(focusResetClasses);
- }
- }
-
- function refreshLegend() {
- var li = legend.selectAll("li").data(data);
-
- var newLi = li.enter().append("li")
- .classed('chart-legend-item', true)
- .on("mouseover", function() {
- select(this.getAttribute('data-id'));
- })
- .on("mouseout", unselect);
-
- newLi.append("span").classed('legend-pf-color-box', true);
- newLi.append("span").classed('legend-pf-text', true);
-
- li.attr("data-id", function (d, i) {
- return i;
- });
-
- li.select("span.legend-pf-color-box")
- .style("background-color", function (d, i) {
- if (d && d.color)
- return d.color;
- else
- return colors(i);
- });
-
- li.select("span.legend-pf-text")
- .text(function (d) {
- if (d && d.label)
- return d.label;
- else
- return d;
- });
-
- li.exit().remove();
- }
-
- function refresh() {
- if (!data)
- data = [];
-
- var path = g.selectAll("path")
- .data(pie(data));
-
- path.enter().append("path")
- .on("mouseover", function(i) {
- select(this.getAttribute('data-id'));
- })
- .on("mouseout", unselect)
- .append("title");
-
- path.attr("fill", function(d, i) {
- if (d.data && d.data.color)
- return d.data.color;
- else
- return colors(i);
- })
- .attr("d", arc)
- .attr("data-id", function (d, i) {
- return i;
- })
- .select("title")
- .text(function(d) {
- if (d.data && d.data.tooltip)
- return d.data.tooltip;
- });
-
- path.exit().remove();
-
- if (legend)
- refreshLegend();
- }
-
- $scope.$watchCollection('data', function(newValue) {
- data = newValue;
- refresh();
- });
-
- /* Watch the selection for changes */
- $scope.$watchGroup(["largeTitle", "smallTitle"], function() {
- updateTitle();
- });
-
- angular.element($window).bind('resize', function () {
- updateSize();
- });
-
- $scope.$watch(
- function () {
- return [element[0].offsetWidth, element[0].offsetHeight].join('x');
- },
- function (value) {
- updateSize();
- }
- );
- }
- };
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/connection.js b/pkg/kubernetes/scripts/connection.js
deleted file mode 100644
index 19f6fc53e..000000000
--- a/pkg/kubernetes/scripts/connection.js
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
-
- require('angular-dialog.js');
- require('./kube-client-cockpit');
- require('./utils');
-
- require('../views/auth-form.html');
- require('../views/auth-rejected-cert.html');
- require('../views/container-page.html');
- require('../views/containers-page.html');
- require('../views/containers-listing.html');
- require('../views/container-page-inline.html');
- require('../views/container-body.html');
- require('../views/pod-body.html');
-
- angular.module('kubernetes.connection', [
- 'ui.cockpit',
- 'kubeClient',
- 'kubeClient.cockpit',
- 'kubeUtils',
- ])
-
- .factory("sessionCertificates", [
- "cockpitKubectlConfig",
- function (kubectl) {
- var trustedCerts = {};
-
- function trustCert(cluster, pem) {
- var options = kubectl.generateKubeOptions(cluster);
- var address = options.address || "localhost";
- trustedCerts[address] = pem;
- }
-
- function getCert(address) {
- address = address || "localhost";
- return trustedCerts[address];
- }
-
- return {
- getCert: getCert,
- trustCert: trustCert
- };
- }
- ])
-
- .factory("connectionActions", [
- "$q",
- "cockpitKubeDiscover",
- "cockpitKubectlConfig",
- "cockpitRunCommand",
- "cockpitConnectionInfo",
- "CockpitKubeRequest",
- "KubeMapNamedArray",
- "CockpitTranslate",
- "sessionCertificates",
- function($q, cockpitKubeDiscover, kubectl, runCommand,
- cockpitConnectionInfo, CockpitKubeRequest,
- mapNamedArray, translate, sessionCertificates) {
- var DEFAULT_ADDRESS = "http://localhost:8080";
- const _ = translate.gettext;
-
- function kubectlError(ex) {
- // Because angular warns about all throws
- console.warn("Unexpected Kubectl Error", ex);
- return $q.reject(new Error(_("Error writing kubectl config")));
- }
-
- function kubectlData() {
- return kubectl.read().then(function(data) {
- var config;
- try {
- config = JSON.parse(data);
- } catch (ex) {
- console.warn("received invalid kubectl config", ex);
- config = {};
- }
- return config;
- });
- }
-
- function loadConfigData(config, useConfig) {
- var user, cluster, context;
- var contexts = mapNamedArray(config.contexts);
- var users = mapNamedArray(config.users);
- var clusters = mapNamedArray(config.clusters);
-
- if (useConfig)
- context = contexts[useConfig["current-context"]];
- else
- context = contexts[config["current-context"]];
-
- if (context && context.context) {
- if (context.context.user)
- user = users[context.context.user];
- if (context.context.cluster)
- cluster = clusters[context.context.cluster];
- }
-
- return {
- users: users,
- clusters: clusters,
- contexts: contexts,
- currentUser: user,
- currentCluster: cluster,
- currentContext: context,
- config: config
- };
- }
-
- function load(error) {
- var defer = $q.defer();
- var promise;
-
- var result = {
- haveKubectl: false,
- defaultAddress: DEFAULT_ADDRESS,
- error: error,
- users: undefined,
- clusters: undefined,
- contexts: undefined,
- currentUser: undefined,
- currentCluster: undefined,
- currentContext: undefined,
- config: undefined
- };
-
- if (!error) {
- promise = cockpitKubeDiscover().then(function(options) {
- var address = "localhost";
- if (options.address)
- address = options.address;
-
- if (options.tls)
- result.defaultAddress = "https://" + address + ":" + options.port;
- else
- result.defaultAddress = "http://" + address + ":" + options.port;
-
- return kubectlData();
- }, function(ex) {
- result.error = ex;
- return kubectlData();
- });
- } else {
- promise = kubectlData();
- }
-
- promise.then(function(config) {
- var useConfig;
-
- result.haveKubectl = true;
-
- if (cockpitConnectionInfo.type && cockpitConnectionInfo.type != "open")
- useConfig = cockpitConnectionInfo.kubeConfig;
-
- angular.extend(result, loadConfigData(config, useConfig));
- defer.resolve(result);
- }, function(ex) {
- if (cockpitConnectionInfo.kubeConfig)
- angular.extend(result, loadConfigData(cockpitConnectionInfo.kubeConfig));
- defer.resolve(result);
- });
- return defer.promise;
- }
-
- function prepareData(config, cluster, user) {
- var i;
- var contexts, context;
- var default_cluster = {
- cluster: { server: DEFAULT_ADDRESS }
- };
-
- config = config || {};
- cluster = cluster || default_cluster;
-
- function ensureValid(name, options) {
- var added;
- var chars = "abcdefghijklmnopqrstuvwxyz";
- name = name.toLowerCase().replace(/[^a-z0-9:/-]/g, "-");
- while (options[name]) {
- var length = 0;
- if (!added)
- name = name + "/";
-
- added = "";
-
- while (length < 4) {
- added += chars[Math.floor(Math.random() * chars.length)];
- length++;
- }
-
- name = name + added;
- }
- return name;
- }
-
- function generateClusterName(cluster) {
- var a = document.createElement("a");
- a.href = cluster.cluster.server;
-
- var name = a.hostname;
-
- if (a.port)
- name = name + ":" + a.port;
-
- return ensureValid(name, mapNamedArray(config.clusters));
- }
-
- function generateUserName(user, clusterName) {
- var name;
- if (user.user && user.user.username)
- name = user.user.username;
- else
- name = "user";
- name = name + "/" + clusterName;
- return ensureValid(name, mapNamedArray(config.users));
- }
-
- function generateContextName(userName, clusterName) {
- var name = clusterName + "/" + userName;
- return ensureValid(name, mapNamedArray(config.contexts));
- }
-
- if (!cluster.name)
- cluster.name = generateClusterName(cluster);
-
- if (user && !user.name)
- user.name = generateUserName(user, cluster.name);
-
- contexts = config.contexts || [];
- for (i = 0; i < contexts.length; i++) {
- var c = contexts[i];
- if (c.context) {
- var inner = c.context || {};
- if (inner.cluster == cluster.name &&
- ((user && inner.user == user.name) || (!user && !inner.user))) {
- context = { name: c.name };
- break;
- }
- }
- }
-
- if (!context) {
- context = {
- name: generateContextName(user ? user.name : "noauth", cluster.name),
- context: {
- user: user ? user.name : undefined,
- cluster: cluster.name,
- }
- };
- }
-
- return {
- cluster: cluster,
- user: user,
- context: context
- };
- }
-
- /* Openshift returns token information in the hash of a Location URL */
- function parseBearerToken(url) {
- var token = null;
- var parser = document.createElement('a');
- parser.href = url;
- var hash = parser.hash;
- if (hash[0] == "#")
- hash = hash.substr(1);
- hash.split("&").forEach(function(part) {
- var item = part.split("=");
- if (item.shift() == "access_token")
- token = item.join("=");
- });
- return token;
- }
-
- /* Retrieve a bearer token using basic auth if possible */
- function populateBearerToken(cluster, user) {
- /* The user data without any token */
- var data = angular.extend({ }, user ? user.user : null);
-
- /* If no password is set, just skip this step */
- if (!data.password)
- return $q.when();
-
- delete data.token;
-
- /* Build an Openshift OAuth WWW-Authenticate request */
- var config = kubectl.generateKubeOptions(cluster.cluster, data);
- var trust = sessionCertificates.getCert(config.address);
- if (config.tls && trust)
- config.tls["authority"] = { data: trust };
-
- if (!config.headers)
- config.headers = { };
- config.headers["X-CSRF-Token"] = "1"; /* Any value will do */
- var path = '/oauth/authorize?response_type=token&client_id=openshift-challenging-client';
- var request = new CockpitKubeRequest("GET", path, "", config);
-
- return request.then(function(response) {
- /* Shouldn't return success. Not OAuth capable */
- return "";
- }, function(response) {
- if (response.status == 302) {
- var token;
- var header = response.headers["Location"];
- if (header) {
- /*
- * When OAuth is in play (ie: Openshift, Origin, Atomic, then
- * user/password basic auth doesn't work for accessing the API.
- *
- * Unfortunately kubectl won't let us save both user/password and
- * the token (if we wanted it for future use). So we have to remove
- * the user and password data.
- */
- token = parseBearerToken(header);
- if (token) {
- delete user.user.username;
- delete user.user.password;
- user.user.token = token;
- }
- }
- return "";
- } else if (response.status == 404) {
- return ""; /* Not OAuth capable */
- } else {
- return $q.reject(response);
- }
- });
- }
-
- function writeKubectlConfig(cluster, user, context) {
- var cluster_args, user_args, cmd_args;
- var commands = [];
- var promise;
-
- // Everything here must run serially
- if (user && user.user) {
- user_args = [ "kubectl", "config", "set-credentials", user.name ];
-
- if (user.user.username) {
- user_args.push("--username=" + user.user.username);
- user_args.push("--password=" + (user.user.password || ""));
- }
-
- if (user.user.token)
- user_args.push("--token=" + user.user.token);
-
- commands.push(user_args);
- }
-
- if (cluster && cluster.cluster) {
- cluster_args = [ "kubectl", "config", "set-cluster",
- cluster.name, "--server=" + cluster.cluster.server,
- "--insecure-skip-tls-verify=" + !!cluster.cluster["insecure-skip-tls-verify"]
- ];
- commands.push(cluster_args);
- }
-
- if (context) {
- cmd_args = [ "kubectl", "config", "set-context", context.name ];
-
- angular.forEach(["namespace", "user", "cluster"], function(value, key) {
- if (context.context && context.context[value])
- cmd_args.push("--" + value + "=" + context.context[value]);
- });
- commands.push(cmd_args);
- commands.push([ "kubectl", "config", "use-context", context.name ]);
- }
-
- promise = $q.when();
- angular.forEach(commands, function(command) {
- promise = promise.then(function (result) {
- return runCommand(command);
- });
- });
-
- return promise.then(function () {
- return kubectlData().then(function(data) {
- return loadConfigData(data);
- });
- }).catch(kubectlError);
- }
-
- return {
- prepareData: prepareData,
- load: load,
- writeKubectlConfig: writeKubectlConfig,
- populateBearerToken: populateBearerToken
- };
- }
- ])
-
- .controller("ChangeAuthCtrl", [
- "$q",
- "$scope",
- "$modalInstance",
- "dialogData",
- "connectionActions",
- "CockpitKubeRequest",
- "cockpitKubectlConfig",
- "sessionCertificates",
- function($q, $scope, instance, dialogData, connectionActions,
- CockpitKubeRequest, kubectl, sessionCertificates) {
- angular.extend($scope, dialogData);
-
- function connect(data) {
- var cluster = data.currentCluster ? data.currentCluster.cluster : null;
- var user = data.currentUser ? data.currentUser.user : null;
-
- var options = kubectl.generateKubeOptions(cluster, user);
- var trust = sessionCertificates.getCert(options.address);
-
- var force = $scope.haveKubectl ? "kubectl" : options;
- if (options.tls && trust) {
- options.tls["authority"] = { data: trust };
- force = options;
- }
-
- var promise = new CockpitKubeRequest("GET", "/api", "", options);
- return promise.then(function() {
- return force;
- }).catch(function (ex) {
- data.error = ex;
- angular.extend($scope, data);
- $scope.$broadcast("loadData");
-
- return $q.reject([]);
- });
- }
-
- $scope.$on("selectUser", function (ev, user) {
- var users = $scope.users || {};
- if (user && user.name && !users[user.name])
- delete user.name;
-
- $scope.currentUser = user;
- });
-
- $scope.$on("selectCluster", function (ev, cluster) {
- var clusters = $scope.clusters || {};
- if (cluster && cluster.name && !clusters[cluster.name])
- delete cluster.name;
-
- $scope.currentCluster = cluster;
- });
-
- $scope.saveAndConnect = function (data) {
- return connectionActions.populateBearerToken(data.cluster, data.user)
- .then(function () {
- if ($scope.haveKubectl) {
- return connectionActions.writeKubectlConfig(data.cluster, data.user, data.context);
- } else {
- return $q.when({
- currentUser: data.user,
- currentCluster: data.cluster,
- });
- }
- }, function (ex) {
- $scope.currentUser = data.user;
- $scope.currentCluster = data.cluster;
- $scope.error = ex;
-
- $scope.$broadcast("loadData");
- return $q.reject([]);
- })
- .then(connect);
- };
- }
- ])
-
- .directive("authForm", [
- "$q",
- "connectionActions",
- "CockpitTranslate",
- "CockpitFormat",
- function($q, connectionActions, translate, format) {
- const _ = translate.gettext;
- return {
- restrict: "E",
- scope: true,
- link: function($scope, element, attrs) {
- $scope.fields = {};
-
- function loadData() {
- if ($scope.error) {
- var msg = $scope.error.statusText;
- if (!msg)
- msg = $scope.error.problem;
-
- if (msg == "not-found")
- msg = _("Couldn't find running API server");
-
- $scope.failure(format.format(_("Connection Error: $0"), msg));
- }
-
- if ($scope.currentCluster)
- $scope.selectCluster($scope.currentCluster);
- else
- $scope.fields.address = $scope.defaultAddress;
-
- if ($scope.currentUser)
- $scope.selectUser($scope.currentUser);
-
- $scope.useAuth = !!$scope.currentUser;
- }
-
- function validate() {
- var errors = [];
- var ex;
- var address_re = /^[a-z0-9:/.-]+$/i;
- var address = $scope.fields.address;
- var cluster = { cluster: {} };
- var user;
-
- if (!$scope.fields.address || !address_re.test(address.toLowerCase())) {
- ex = new Error(_("Please provide a valid address"));
- ex.target = "#kubernetes-address";
- errors.push(ex);
- ex = null;
- } else if (address.indexOf("http://") !== 0 &&
- address.indexOf("https://") !== 0) {
- address = "http://" + address;
- }
-
- user = $scope.useAuth ? $scope.currentUser : null;
- if (!user && $scope.useAuth)
- user = { user: {} };
-
- if (user && !$scope.fields.username &&
- (!user.name || user.user.username)) {
- ex = new Error(_("Please provide a username"));
- ex.target = "#kubernetes-username";
- errors.push(ex);
- ex = null;
- }
-
- if ($scope.currentCluster)
- cluster = $scope.currentCluster;
-
- cluster.cluster.server = address;
- cluster.cluster["insecure-skip-tls-verify"] = !!$scope.fields.skipVerify;
-
- if (user) {
- if ($scope.fields.username) {
- user.user.username = $scope.fields.username;
- user.user.password = $scope.fields.password;
- } else {
- delete user.user.username;
- delete user.user.password;
- }
- if ($scope.fields.token)
- user.user.token = $scope.fields.token;
- else
- delete user.user.token;
- }
-
- if (errors.length > 0)
- return $q.reject(errors);
-
- var data = connectionActions.prepareData($scope.config, cluster, user);
- return $q.when(data);
- }
-
- $scope.selectCluster = function selectCluster(cluster) {
- var inner = cluster && cluster.cluster ? cluster.cluster : {};
- $scope.fields.address = inner.server;
- $scope.fields.skipVerify = !!inner["insecure-skip-tls-verify"];
- $scope.$emit("selectCluster", cluster);
- };
-
- $scope.selectUser = function selectUser(user) {
- var inner = user && user.user ? user.user : {};
- $scope.fields.username = inner.username;
- $scope.fields.password = inner.password;
- $scope.fields.token = inner.token;
- $scope.$emit("selectUser", user);
- };
-
- $scope.hasCert = function hasCert(user) {
- if (user && user.user) return user.user["client-key"] || user.user["client-key-data"];
- return false;
- };
-
- $scope.toggleAuth = function toggleAuth() {
- $scope.useAuth = !$scope.useAuth;
- };
-
- $scope.update = function() {
- return validate().then(function (data) {
- return $scope.saveAndConnect(data);
- });
- };
-
- $scope.$on("loadData", loadData);
- loadData();
- },
- templateUrl: "views/auth-form.html"
- };
- }
- ])
-
- .directive("authRejectedCert", [
- "$q",
- "connectionActions",
- "sessionCertificates",
- "cockpitRunCommand",
- "CockpitTranslate",
- "CockpitFormat",
- function($q, connectionActions, sessionCertificates,
- runCommand, translate, format) {
- const _ = translate.gettext;
- return {
- restrict: "E",
- scope: true,
- link: function($scope, element, attrs) {
- var pem = null;
- $scope.address = null;
-
- function getCertDetails() {
- var options = $scope.error ? $scope.error.options : {};
- var cmd = runCommand([ "openssl", "x509", "-noout", "-text" ]);
- options = options || {};
- pem = options["rejected-certificate"];
- cmd.then(function(data) {
- $scope.details = data;
- }, function(ex) {
- var msg = format.format(_("Error getting certificate details: $0"), ex.problem);
- $scope.failure(msg);
- });
- cmd.send(pem);
- cmd.send("\n\n");
- }
-
- function loadData() {
- if ($scope.currentCluster)
- $scope.address = $scope.currentCluster.cluster.server;
- else
- $scope.address = $scope.defaultAddress;
-
- $scope.action = "skip";
- $scope.details = null;
- getCertDetails();
- }
-
- $scope.update = function update() {
- var cluster = { cluster: { server: $scope.address } };
- if ($scope.currentCluster)
- cluster = $scope.currentCluster;
-
- var data = connectionActions.prepareData($scope.config, cluster, $scope.currentUser);
- if ($scope.action == "pem")
- sessionCertificates.trustCert(data.cluster.cluster, pem);
-
- if ($scope.action != "pem")
- data.cluster.cluster['insecure-skip-tls-verify'] = true;
-
- return $scope.saveAndConnect(data);
- };
-
- $scope.$on("loadData", loadData);
- loadData();
- },
- templateUrl: "views/auth-rejected-cert.html"
- };
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/containers.js b/pkg/kubernetes/scripts/containers.js
deleted file mode 100644
index c58a86ce6..000000000
--- a/pkg/kubernetes/scripts/containers.js
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
- require('angular-route');
- require('angular-dialog.js');
- require('./kube-client');
- require('./listing');
-
- require('kubernetes-container-terminal/dist/container-terminal.js');
-
- angular.module('kubernetes.containers', [
- 'ngRoute',
- 'ui.cockpit',
- 'kubernetesUI',
- 'kubeClient',
- 'kubernetes.listing'
- ])
-
- .config([
- '$routeProvider',
- function($routeProvider) {
- $routeProvider
- .when('/pods/:pod_namespace/:pod_name/:container_name', {
- templateUrl: 'views/container-page.html',
- controller: 'ContainerCtrl'
- })
- .when('/pods/:pod_namespace/:pod_name', {
- redirectTo: '/pods'
- })
- .when('/pods/:pod_namespace?', {
- templateUrl: 'views/containers-page.html',
- controller: 'ContainersCtrl'
- });
- }
- ])
-
- /*
- * The controller for the containers view.
- */
- .controller('ContainersCtrl', [
- '$scope',
- 'KubeContainers',
- 'kubeLoader',
- 'kubeSelect',
- 'ListingState',
- '$routeParams',
- '$location',
- function($scope, containers, loader, select, ListingState, $routeParams, $location) {
- var selector = {};
- var qs = $location.search();
- for (var key in qs) {
- if (key !== "namespace")
- selector[key] = qs[key];
- }
-
- loader.listen(function() {
- var pods = select().kind("Pod");
- if ($routeParams.pod_namespace)
- pods.namespace($routeParams.pod_namespace);
- if (!angular.equals({}, selector))
- pods.label(selector);
-
- $scope.pods = pods;
- }, $scope);
-
- loader.watch("Pod", $scope);
-
- $scope.listing = new ListingState($scope);
-
- $scope.containers = containers;
-
- $scope.$on("activate", function(ev, id) {
- ev.preventDefault();
- $location.path(id);
- });
-
- $scope.should_mask = function(name) {
- return name.toLowerCase().indexOf("password") !== -1;
- };
- }
- ])
-
- /*
- * The controller for the containers view.
- */
- .controller('ContainerCtrl', [
- '$scope',
- 'KubeContainers',
- 'kubeLoader',
- 'kubeSelect',
- '$routeParams',
- '$route',
- function($scope, containers, loader, select, $routeParams, $route) {
- var target = $routeParams["container_name"] || "";
- $scope.target = target;
-
- loader.listen(function() {
- $scope.pod = select().kind("Pod")
- .namespace($routeParams.pod_namespace || "")
- .name($routeParams.pod_name || "")
- .one();
- if ($scope.pod) {
- angular.forEach(containers($scope.pod) || [], function (con) {
- if (con.spec && con.spec.name === target)
- $scope.container = con;
- });
- }
- }, $scope);
-
- loader.watch("Pod", $scope);
-
- $scope.back = function() {
- $route.updateParams({ "container_name" : undefined });
- };
-
- $scope.should_mask = function(name) {
- return name.toLowerCase().indexOf("password") !== -1;
- };
- }
- ])
-
- /**
- * Build an array of container objects where each object contains the data from both
- * the spec and status sections of the pod. Looks like this:
- * { id: id, spec: pod.spec.containers[n], status: pod.status.containerStatuses[n] }
- *
- * The returned array will not change once created for a given pod item.
- */
- .factory('KubeContainers', [
- 'KubeMapNamedArray',
- function(mapNamedArray) {
- return function (item) {
- var specs, statuses, pod_id;
- if (!item.containers) {
- pod_id = "pods/" + item.metadata.namespace + "/" + item.metadata.name;
- if (item.spec)
- specs = mapNamedArray(item.spec.containers);
- else
- specs = { };
-
- if (item.status)
- statuses = mapNamedArray(item.status.containerStatuses);
- else
- statuses = { };
-
- item.containers = Object.keys(specs).map(function(name) {
- var key = pod_id + "/" + name;
- return { spec: specs[name], status: statuses[name], key: key };
- });
- }
- return item.containers;
- };
- }
- ])
-
- .directive('containersListing',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/containers-listing.html'
- };
- }
- )
-
- .directive('containerPageInline',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/container-page-inline.html'
- };
- }
- )
-
- .directive('kubeContainerBody',
- function() {
- return {
- restrict: 'E',
- templateUrl: 'views/container-body.html'
- };
- }
- )
-
- .directive('kubePodBody',
- function() {
- return {
- restrict: 'E',
- templateUrl: 'views/pod-body.html'
- };
- }
- )
-
- /*
- * Displays a container console.
- *
- *
- */
- .directive('kubeConsole', [
- 'kubernetesContainerSocket',
- function(socket) {
- return {
- restrict: 'E',
- scope: {
- pod: '&',
- container: '&',
- command: '@',
- prevent: '='
- },
- link: function(scope, element, attrs) {
- var limit = 64 * 1024;
-
- var outer = angular.element("");
- outer.addClass("console-ct");
- element.append(outer);
- var pre = angular.element("
");
- outer.append(pre);
- var wait = null;
- var ws = null;
-
- function connect() {
- pre.empty();
-
- var url = "";
- var pod = scope.pod();
- if (pod.metadata)
- url += pod.metadata.selfLink;
- else
- url += pod;
- url += "/log";
- if (url.indexOf('?') === -1)
- url += '?';
- url += "follow=1";
-
- var container = scope.container ? scope.container() : null;
- if (container)
- url += "&container=" + encodeURIComponent(container);
-
- var writing = [];
- var count = 0;
-
- function drain() {
- wait = null;
- var at_bottom = pre[0].scrollHeight - pre[0].scrollTop <= pre[0].offsetHeight;
- var text = writing.join("");
-
- /*
- * Stay under the limit. I wish we could use some other mechanism
- * for limiting the log output, such as:
- *
- * https://github.com/kubernetes/kubernetes/issues/12447
- */
- count += text.length;
- var children, first, removed;
- while (count > limit) {
- children = pre.children();
- if (children.length < 1)
- break;
-
- first = angular.element(children[0]);
- removed = first.text().length;
- first.remove();
- count -= removed;
- }
-
- /* And add our text */
- var span = angular.element("").text(text);
- writing.length = 0;
- pre.append(span);
- if (at_bottom)
- pre[0].scrollTop = pre[0].scrollHeight;
- }
-
- ws = socket(url);
- ws.onclose = function(ev) {
- writing.push(ev.reason);
- drain();
- disconnect();
- ws = null;
- };
- ws.onmessage = function(ev) {
- writing.push(ev.data);
- if (wait === null)
- wait = window.setTimeout(drain, 50);
- };
- }
-
- function disconnect() {
- if (ws) {
- ws.onopen = ws.onmessage = ws.onerror = ws.onclose = null;
- if (ws.readyState < 2) // CLOSING
- ws.close();
- ws = null;
- }
- window.clearTimeout(wait);
- wait = null;
- }
-
- scope.$watch("prevent", function(prevent) {
- if (!prevent && !ws)
- connect();
- });
-
- scope.$on("$destroy", disconnect);
- }
- };
- }
- ])
-
- /*
- * Filter to display short docker ids
- *
- * {{ myid | kube-identifier }}
- *
- * Removes docker:// prefix and shortens.
- */
- .filter('kubeIdentifier', function() {
- var regex = /docker:\/\/([\w]{12})\w+/;
- return function(item) {
- var match = regex.exec(item);
- if (match)
- return match[1];
- return item;
- };
- });
-}());
diff --git a/pkg/kubernetes/scripts/dashboard.js b/pkg/kubernetes/scripts/dashboard.js
deleted file mode 100644
index 863a8e31b..000000000
--- a/pkg/kubernetes/scripts/dashboard.js
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
- require('angular-route');
-
- require('./details');
- require('./app');
- require('./graphs');
- require('./nodes');
- require('./volumes');
-
- require('../views/dashboard-page.html');
- require('../views/deploy.html');
- require('../views/file-button.html');
-
- angular.module('kubernetes.dashboard', [
- 'ngRoute',
- 'kubernetes.details',
- 'kubernetes.app',
- 'kubernetes.graph',
- 'kubernetes.nodes'
- ])
-
- .config(['$routeProvider', function($routeProvider) {
- $routeProvider.when('/', {
- templateUrl: 'views/dashboard-page.html',
- controller: 'DashboardCtrl',
- reloadOnSearch: false,
- });
- }])
-
- .controller('DashboardCtrl', [
- '$scope',
- 'kubeLoader',
- 'kubeSelect',
- 'dashboardData',
- 'dashboardActions',
- 'itemActions',
- 'nodeActions',
- 'nodeData',
- '$location',
- function($scope, loader, select, data, actions, itemActions,
- nodeActions, nodeData, $location) {
- loader.listen(function() {
- $scope.services = select().kind("Service");
- $scope.nodes = select().kind("Node");
- $scope.pods = select().kind("Pod");
- $scope.volumes = select().kind("PersistentVolume");
- $scope.pvcs = select().kind("PersistentVolumeClaim");
-
- $scope.status = {
- pods: {
- Pending: $scope.pods.statusPhase("Pending"),
- Failed: $scope.pods.statusPhase("Failed"),
- Unknown: $scope.pods.statusPhase("Unknown"),
- },
- nodes: {
- Pending: $scope.nodes.statusPhase("Pending"),
- Terminated: $scope.nodes.statusPhase("Terminated"),
- NotReady: $scope.nodes.conditionNotTrue("Ready"),
- OutOfDisk: $scope.nodes.conditionTrue("OutOfDisk"),
- },
- volumes: {
- Pending: $scope.volumes.statusPhase("Pending"),
- PendingClaims: $scope.pvcs.statusPhase("Pending"),
- Available: $scope.volumes.statusPhase("Available"),
- Released: $scope.volumes.statusPhase("Released"),
- Failed: $scope.volumes.statusPhase("Failed"),
- },
- };
- }, $scope);
-
- loader.watch("Node", $scope);
- loader.watch("Service", $scope);
- loader.watch("ReplicationController", $scope);
- loader.watch("Pod", $scope);
- loader.watch("PersistentVolume", $scope);
- loader.watch("PersistentVolumeClaim", $scope);
-
- $scope.editServices = false;
- $scope.toggleServiceChange = function toggleServiceChange() {
- $scope.editServices = !$scope.editServices;
- };
-
- $scope.jumpService = function jumpService(ev, service) {
- if ($scope.editServices)
- return;
-
- var meta = service.metadata || {};
- var spec = service.spec || {};
- if (spec.selector && !angular.equals({}, spec.selector) && meta.namespace)
- $location.path("/pods/" + encodeURIComponent(meta.namespace)).search(spec.selector);
- };
-
- $scope.navigateNode = function(node) {
- var meta = node.metadata || {};
- if (meta.name)
- $location.path("/nodes/" + encodeURIComponent(meta.name));
- };
-
- /* All the actions available on the $scope */
- angular.extend($scope, actions);
- angular.extend($scope, data);
- angular.extend($scope, nodeData);
- $scope.modifyService = itemActions.modifyService;
- $scope.addNode = nodeActions.addNode;
-
- /* Highlighting */
-
- $scope.highlighted = null;
- $scope.$on("highlight", function(ev, uid) {
- $scope.highlighted = uid;
- });
- $scope.highlight = function highlight(uid) {
- $scope.$broadcast("highlight", uid);
- };
-
- $scope.servicesState = function services_state() {
- if ($scope.failure)
- return 'failed';
- var service;
- for (service in $scope.services)
- break;
- return service ? 'ready' : 'empty';
- };
- }])
-
- .directive('kubernetesAddress', function() {
- return {
- restrict: 'E',
- link: function($scope, element, attributes) {
- $scope.$watchGroup(["item.spec.clusterIP", "item.spec.ports"], function(values) {
- var address = values[0];
- var ports = values[1];
- var href = null;
- var text = null;
-
- /* No ports */
- if (!ports || !ports.length) {
- text = address;
-
- /* One single HTTP or HTTPS port */
- } else if (ports.length == 1) {
- text = address + ":" + ports[0].port;
- if (ports[0].protocol === "TCP") {
- if (ports[0].port === 80)
- href = "http://" + encodeURIComponent(address);
- else if (ports[0].port === 443)
- href = "https://" + encodeURIComponent(address);
- } else {
- text += "/" + ports[0].protocol;
- }
- } else {
- text = " " + address + " " + ports.map(function(p) {
- if (p.protocol === "TCP")
- return p.port;
- else
- return p.port + "/" + p.protocol;
- }).join(" ");
- }
-
- var el;
- element.empty();
- if (href) {
- el = angular.element("")
- .attr("href", href)
- .attr("target", "_blank")
- .on("click", function(ev) { ev.stopPropagation() });
- element.append(el);
- } else {
- el = element;
- }
- el.text(text);
- });
- }
- };
- })
-
- .factory('dashboardActions', [
- '$modal',
- function($modal) {
- function deploy() {
- return $modal.open({
- animation: false,
- controller: 'DeployCtrl',
- templateUrl: 'views/deploy.html',
- resolve: {},
- }).result;
- }
-
- return {
- deploy: deploy,
- };
- }
- ])
-
- .factory('dashboardData', [
- 'kubeSelect',
- function(select) {
- function conditionDigest(arg, match) {
- if (typeof arg == "string")
- return [ arg ];
- var conditions = (arg.status || { }).conditions || [ ];
- var result = [ ];
- conditions.forEach(function(condition) {
- if ((match && condition.status == "True") ||
- (!match && condition.status != "True")) {
- result.push(condition.type);
- }
- });
- return result;
- }
-
- select.register({
- name: "conditionTrue",
- digests: function(arg) {
- return conditionDigest(arg, true);
- }
- });
-
- select.register({
- name: "conditionNotTrue",
- digests: function(arg) {
- return conditionDigest(arg, false);
- }
- });
-
- return {
- nodeContainers: function nodeContainers(node) {
- var count = 0;
- var meta = node.metadata || { };
- angular.forEach(select().kind("Pod")
- .host(meta.name), function(pod) {
- var spec = pod.spec || { };
- var n = 1;
- if (spec.containers)
- n = spec.containers.length;
- count += n;
- });
- return count;
- },
-
- serviceStatus: function serviceStatus(service) {
- var spec = service.spec || { };
- var meta = service.metadata || { };
- var state = "";
-
- var pods = select().kind("Pod")
- .namespace(meta.namespace || "")
- .label(spec.selector || {});
- angular.forEach(pods, function(pod) {
- if (!pod.status || !pod.status.phase)
- return;
- switch (pod.status.phase) {
- case "Pending":
- if (!state)
- state = "wait";
- break;
- case "Running":
- break;
- case "Succeeded":
- break;
- case "Unknown":
- break;
- case "Failed":
- /* falls through */
- default: /* assume failed */
- state = "fail";
- break;
- }
- });
-
- return state;
- },
-
- serviceContainers: function serviceContainers(service) {
- var spec = service.spec || { };
- var meta = service.metadata || {};
-
- /* Calculate number of containers */
- var x = 0;
- var y = 0;
-
- /*
- * Calculate "x of y" containers, where x is the current
- * number and y is the expected number. If x==y then only
- * show x. The calculation is based on the statuses of the
- * containers within the pod. Pod states: Pending,
- * Running, Succeeded, Failed, and Unknown.
- */
- var pods = select().kind("Pod")
- .namespace(meta.namespace || "")
- .label(spec.selector || {});
- angular.forEach(pods, function(pod) {
- if (!pod.status || !pod.status.phase)
- return;
- var spec = pod.spec || { };
- var n = 1;
- if (spec.containers)
- n = spec.containers.length;
- switch (pod.status.phase) {
- case "Pending":
- y += n;
- break;
- case "Running":
- x += n;
- y += n;
- break;
- case "Succeeded": // don't increment either counter
- break;
- case "Unknown":
- y += n;
- break;
- case "Failed":
- /* falls through */
- default: /* assume failed */
- y += n;
- break;
- }
- });
-
- if (x != y)
- return x + " of " + y;
- else
- return "" + x;
- }
- };
- }
- ])
-
- .controller("DeployCtrl", [
- "$q",
- "$scope",
- "$timeout",
- "$modalInstance",
- "filterService",
- "kubeMethods",
- "KubeFormat",
- "KubeTranslate",
- function($q, $scope, $timeout, $instance, filter, methods, KubeFormat, translate) {
- const _ = translate.gettext;
-
- var file;
- var fields = {
- "filename": "",
- "namespace" : filter.namespace(),
- };
-
- function validate_manifest() {
- var defer = $q.defer();
- var ex;
- var fails = [];
-
- var ns = fields.namespace;
- if (!ns)
- ex = new Error(_("Namespace cannot be empty."));
- else if (!/^[a-z0-9]+$/i.test(ns))
- ex = new Error(_("Please provide a valid namespace."));
- if (ex) {
- ex.target = "#deploy-app-namespace-group";
- fails.push(ex);
- ex = null;
- }
-
- if (!file)
- ex = new Error(_("No metadata file was selected. Please select a Kubernetes metadata file."));
- else if (file.type && !file.type.match("json.*"))
- ex = new Error(_("The selected file is not a valid Kubernetes application manifest."));
- if (ex) {
- ex.target = "#deploy-app-manifest-file-button";
- fails.push(ex);
- ex = null;
- }
-
- var reader;
-
- if (fails.length) {
- defer.reject(fails);
- } else {
- reader = new window.FileReader();
- reader.onerror = function(event) {
- ex = new Error(KubeFormat.format(_("Unable to read the Kubernetes application manifest. Code $0."),
- event.target.error.code));
- ex.target = "#deploy-app-manifest-file-button";
- defer.reject(ex);
- };
- reader.onload = function() {
- try {
- defer.resolve({
- objects : JSON.parse(reader.result),
- namespace : ns
- });
- } catch (err) {
- ex = new Error(KubeFormat.format(_("Unable to decode Kubernetes application manifest.")));
- ex.target = "#deploy-app-manifest-file-button";
- defer.reject(ex);
- }
- };
- reader.readAsText(file);
- }
-
- return defer.promise;
- }
-
- function deploy_manifest() {
- var defer = $q.defer();
-
- validate_manifest().then(function(data) {
- methods.create(data.objects, data.namespace)
- .then(function() {
- if ($scope.namespace && data.namespace != $scope.namespace)
- filter.namespace(data.namespace);
- defer.resolve();
- })
- .catch(function(response) {
- var ex;
- var resp = response.data;
-
- /* Interpret this code as a conflict, so suggest user creates a new namespace */
- if (response && response.code === 409) {
- ex = new Error(KubeFormat.format(_("Please create another namespace for $0 \"$1\""),
- response.details.kind, response.details.id));
- ex.target = "#deploy-app-namespace-field";
- } else {
- ex = resp || response;
- }
-
- defer.reject(ex);
- });
- }, function(ex) {
- defer.reject(ex);
- });
-
- return defer.promise;
- }
-
- $scope.types = [
- {
- name: _("Manifest"),
- type: "manifest",
- }
- ];
-
- $scope.selected = $scope.types[0];
- $scope.fields = fields;
- $scope.namespaces = filter.namespaces();
- $scope.namespace = filter.namespace();
-
- $scope.$on("file", function(ev, newFile) {
- $scope.$applyAsync(function() {
- file = newFile;
- fields.filename = file ? file.name : "";
- });
- });
-
- $scope.performDeploy = function performDeploy() {
- if ($scope.selected.type == 'manifest') {
- return deploy_manifest();
- }
- };
-
- $scope.select = function(type) {
- $scope.selected = type;
- };
- }
- ])
-
- .directive('fileButton', function() {
- return {
- templateUrl: 'views/file-button.html',
- restrict: 'A',
- link: function($scope, element, attributes) {
- var button, file_input;
- if (element[0].children.length == 2) {
- button = element[0].children[1];
- file_input = element[0].children[0];
- button.onclick = function () {
- file_input.click();
- };
- file_input.onchange = function () {
- var files = file_input.files || [];
- $scope.$emit('file', files[0]);
- };
- }
-
- element.on('$destroy', function() {
- if (file_input)
- file_input.onchange = null;
-
- if (button)
- button.onclick = null;
- });
- }
- };
- });
-}());
diff --git a/pkg/kubernetes/scripts/date.js b/pkg/kubernetes/scripts/date.js
deleted file mode 100644
index c71cc46db..000000000
--- a/pkg/kubernetes/scripts/date.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
- var moment = require('moment');
-
- require('./kube-client');
-
- angular.module('kubernetes.date', [
- "kubeClient"
- ])
-
- .factory('momentLib', [
- function() {
- return moment;
- }
- ])
-
- .factory('refreshEveryMin', [
- "$rootScope",
- "$window",
- "kubeLoader",
- function($rootScope, $window, loader) {
- var last = 0;
- var interval = 60000;
- var tol = 500;
-
- loader.listen(function() {
- last = (new Date()).getTime();
- });
-
- $window.setInterval(function() {
- var now = (new Date()).getTime();
- if ((now - last) + tol >= interval)
- $rootScope.$applyAsync();
- last = now;
- }, interval);
-
- return {};
- }
- ])
-
- .filter('dateRelative', [
- "refreshEveryMin",
- function() {
- function dateRelative(timestamp) {
- if (!timestamp) {
- return timestamp;
- }
- return moment(timestamp).fromNow();
- }
- dateRelative.$stateful = true;
- return dateRelative;
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/details.js b/pkg/kubernetes/scripts/details.js
deleted file mode 100644
index 394573991..000000000
--- a/pkg/kubernetes/scripts/details.js
+++ /dev/null
@@ -1,736 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
- require('object-describer/dist/object-describer.js');
- require('kubernetes-object-describer/dist/object-describer.js');
- require('angular-dialog.js');
-
- require('./containers');
- require('./date');
- require('./kube-client');
- require('./listing');
- require('./utils');
- require('./volumes');
-
- require('../views/details-page.html');
- require('../views/pod-container.html');
- require('../views/details-page.html');
- require('../views/item-delete.html');
- require('../views/route-modify.html');
- require('../views/replicationcontroller-modify.html');
- require('../views/service-modify.html');
- require('../views/deploymentconfig-body.html');
- require('../views/replicationcontroller-pods.html');
- require('../views/replicationcontroller-body.html');
- require('../views/route-body.html');
- require('../views/service-body.html');
- require('../views/service-endpoint.html');
-
- require('../views/pod-page.html');
- require('../views/image-page.html');
- require('../views/registry-dashboard-page.html');
- require('../views/details-page.html');
- require('../views/project-page.html');
- require('../views/topology-page.html');
- require('../views/node-page.html');
- require('../views/dashboard-page.html');
- require('../views/nodes-page.html');
- require('../views/deploymentconfig-page.html');
- require('../views/pv-page.html');
- require('../views/container-page.html');
- require('../views/service-page.html');
- require('../views/group-page.html');
- require('../views/containers-page.html');
- require('../views/projects-page.html');
- require('../views/user-page.html');
- require('../views/images-page.html');
- require('../views/replicationcontroller-page.html');
- require('../views/route-page.html');
- require('../views/imagestream-page.html');
- require('../views/volumes-page.html');
-
- function validItem(item, type) {
- var valid = (item && (!type || item.kind === type) &&
- item.spec && item.metadata);
- var type_name = type || "Object";
-
- if (!valid)
- console.warn("Invalid " + type_name, item);
-
- return valid;
- }
-
- function format_addresses_with_ports(addresses, ports) {
- var text = addresses.join(", ");
-
- if (ports && ports.length) {
- text = text + ":" + ports.map(function(p) {
- if (p.protocol === "TCP")
- return p.port;
- else
- return p.port + "/" + p.protocol;
- }).join(", ");
- }
-
- return text;
- }
-
- angular.module('kubernetes.details', [
- 'ngRoute',
- 'ui.cockpit',
- 'kubernetesUI',
- 'kubeClient',
- 'kubeUtils',
- 'kubernetes.listing',
- 'kubernetes.date',
- 'kubernetes.volumes',
- 'kubernetes.containers',
- ])
-
- .config([
- '$routeProvider',
- function($routeProvider) {
- $routeProvider
- .when('/list/:namespace?', {
- templateUrl: 'views/details-page.html',
- controller: 'DetailsCtrl'
- })
- .when('/l/pods/:pod_namespace/:pod_name/:container_name', {
- templateUrl: 'views/pod-container.html',
- controller: 'ContainerCtrl',
- })
- .when('/l/:target_type/:target_namespace/:target', {
- templateUrl: function (params) {
- var re = /s$/;
- var kind = params.target_type || "";
-
- return 'views/' + kind.replace(re, "") + "-page.html";
- },
- controller: 'DetailCtrl',
- resolve: {
- 'kindData': [
- 'kindData',
- function (kindData) {
- return kindData();
- }
- ]
- }
- })
- .when('/l/:target_type', {
- templateUrl: 'views/details-page.html',
- controller: 'DetailCtrl',
- resolve: {
- 'kindData': [
- 'kindData',
- function (kindData) {
- return kindData();
- }
- ]
- }
- });
- }
- ])
-
- .factory("kindData", [
- "$q",
- "$route",
- "$location",
- function($q, $route, $location) {
- var typesToKinds = {
- 'services': 'Service',
- 'routes': 'Route',
- 'deploymentconfigs': 'DeploymentConfig',
- 'replicationcontrollers': 'ReplicationController',
- 'pods': 'Pod',
- };
-
- return function() {
- var current = $route.current.params['target_type'];
- var kind;
- if (current)
- kind = typesToKinds[current];
-
- if (!kind) {
- $location.path('/');
- return $q.reject();
- }
-
- return $q.when({
- 'kind' : kind,
- 'type' : current,
- });
- };
- }
- ])
-
- .factory("detailsWatch", [
- "kubeLoader",
- "KubeDiscoverSettings",
- function (loader, settings) {
- return function(until) {
- loader.watch("Pod", until);
- loader.watch("Service", until);
- loader.watch("ReplicationController", until);
- loader.watch("Endpoints", until);
- loader.watch("PersistentVolumeClaim", until);
- settings().then(function(settings) {
- if (settings.flavor === "openshift") {
- loader.watch("DeploymentConfig", until);
- loader.watch("Route", until);
- }
- });
- };
- }
- ])
-
- .factory("detailsData", [
- 'kubeSelect',
- 'volumeData',
- 'KubeContainers',
- "KubeTranslate",
- function (select, volumeData, containers, translate) {
- const _ = translate.gettext;
- var names = {
- 'services': {
- 'name' : _("Services")
- },
- 'routes': {
- 'name' : _("Routes"),
- 'flavor': "openshift"
- },
- 'deploymentconfigs': {
- 'name': _("Deployment Configs"),
- 'flavor': "openshift"
- },
- 'replicationcontrollers': {
- 'name' : _("Replication Controllers")
- },
- 'pods': {
- 'name' : _("Pods")
- }
- };
-
- function item_identifier(item) {
- var meta = item.metadata || { };
- var id = item.kind.toLowerCase() + "s/";
- if (meta.namespace)
- id = id + meta.namespace + "/";
- return id + meta.name;
- }
-
- function service_endpoint(service) {
- return select().kind("Endpoints")
- .namespace(service.metadata.namespace)
- .name(service.metadata.name)
- .one();
- }
-
- function replicationcontroller_pods(item) {
- var meta = item.metadata || {};
- var spec = item.spec || {};
- return select().kind("Pod")
- .namespace(meta.namespace || "")
- .label(spec.selector || {});
- }
-
- function podStatus(item) {
- var status = item.status || {};
- var meta = item.metadata || {};
-
- if (meta.deletionTimestamp)
- return "Terminating";
- else
- return status.phase;
- }
-
- return {
- itemIdentifier: item_identifier,
- serviceEndpoint: service_endpoint,
- replicationcontrollerPods: replicationcontroller_pods,
- podStatus: podStatus,
- volumesForPod: volumeData.volumesForPod,
- claimFromVolumeSource: volumeData.claimFromVolumeSource,
- containers: containers,
- names: names
- };
- }
- ])
-
- /*
- * The controller for the details view.
- */
- .controller('DetailsCtrl', [
- '$scope',
- 'kubeLoader',
- 'kubeSelect',
- 'KubeDiscoverSettings',
- 'ListingState',
- '$location',
- 'itemActions',
- 'detailsData',
- 'detailsWatch',
- function($scope, loader, select, discoverSettings, ListingState,
- $location, actions, detailsData, detailsWatch) {
- loader.listen(function() {
- $scope.pods = select().kind("Pod");
- $scope.services = select().kind("Service");
- $scope.replicationcontrollers = select().kind("ReplicationController");
- $scope.deploymentconfigs = select().kind("DeploymentConfig");
- $scope.routes = select().kind("Route");
- }, $scope);
-
- detailsWatch($scope);
- $scope.listing = new ListingState($scope);
- $scope.showAll = true;
-
- $scope.$on("activate", function(ev, id) {
- ev.preventDefault();
- actions.navigate(id);
- });
-
- /* All the data and actions available on the $scope */
- angular.extend($scope, detailsData);
- angular.extend($scope, actions);
- }
- ])
-
- .controller('DetailCtrl', [
- '$scope',
- 'kindData',
- 'kubeLoader',
- 'kubeSelect',
- 'ListingState',
- '$routeParams',
- '$location',
- 'itemActions',
- 'detailsData',
- 'detailsWatch',
- function($scope, kindData, loader, select, ListingState, $routeParams,
- $location, actions, detailsData, detailsWatch) {
- var target = $routeParams["target"] || "";
- $scope.target = target;
- $scope.name = detailsData.names[kindData.type].name;
-
- loader.listen(function() {
- if (kindData.type)
- $scope[kindData.type] = select().kind(kindData.kind);
-
- if (target && $routeParams.target_namespace) {
- $scope.item = select().kind(kindData.kind)
- .namespace($routeParams.target_namespace)
- .name(target)
- .one();
- }
- }, $scope);
-
- detailsWatch($scope);
- $scope.listing = new ListingState($scope);
- $scope.listing.inline = true;
-
- $scope.$on("activate", function(ev, id) {
- ev.preventDefault();
- actions.navigate(id);
- });
-
- /* All the data and actions available on the $scope */
- angular.extend($scope, detailsData);
- angular.extend($scope, actions);
- angular.extend($scope, kindData);
- }
- ])
-
- .directive('kubernetesServiceCluster', function() {
- return {
- restrict: 'E',
- link: function($scope, element, attributes) {
- $scope.$watchGroup(["item.spec.clusterIP",
- "item.spec.ports"], function(values) {
- var text = format_addresses_with_ports([values[0]],
- values[1]);
- element.text(text);
- });
- }
- };
- })
-
- .factory('itemActions', [
- '$modal',
- '$location',
- function($modal, $location) {
- function deleteItem(item) {
- return $modal.open({
- animation: false,
- controller: 'ItemDeleteCtrl',
- templateUrl: 'views/item-delete.html',
- resolve: {
- dialogData: function() {
- return { item: item };
- }
- },
- }).result;
- }
-
- function modifyRoute(item) {
- return $modal.open({
- animation: false,
- controller: 'RouteModifyCtrl',
- templateUrl: 'views/route-modify.html',
- resolve: {
- dialogData: function() {
- return { item: item };
- }
- },
- }).result;
- }
-
- function modifyRC(item) {
- return $modal.open({
- animation: false,
- controller: 'RCModifyCtrl',
- templateUrl: 'views/replicationcontroller-modify.html',
- resolve: {
- dialogData: function() {
- return { item: item };
- }
- },
- }).result;
- }
-
- function modifyService(item) {
- return $modal.open({
- animation: false,
- controller: 'ServiceModifyCtrl',
- templateUrl: 'views/service-modify.html',
- resolve: {
- dialogData: function() {
- return { item: item };
- }
- },
- }).result;
- }
-
- function navigate(path) {
- var prefix = '/l';
- path = path || "";
- if (!path)
- prefix = "/list";
-
- if (path && path.indexOf('/') !== 0)
- prefix = prefix + '/';
-
- $location.path(prefix + path);
- }
-
- return {
- modifyRC: modifyRC,
- modifyRoute: modifyRoute,
- deleteItem: deleteItem,
- modifyService: modifyService,
- navigate: navigate,
- };
- }
- ])
-
- .controller("ItemDeleteCtrl", [
- "$scope",
- "$modalInstance",
- "dialogData",
- "kubeMethods",
- function($scope, $instance, dialogData, methods) {
- angular.extend($scope, dialogData);
-
- $scope.performDelete = function performDelete() {
- return methods.delete($scope.item).catch(function(ex) {
- /* HACK: While debugging delete issues */
- console.log(JSON.stringify(ex));
- });
- };
- }
- ])
-
- .controller("RCModifyCtrl", [
- "$q",
- "$scope",
- "$modalInstance",
- "dialogData",
- "kubeMethods",
- "KubeTranslate",
- function($q, $scope, $instance, dialogData, methods, translate) {
- const _ = translate.gettext;
- var item = dialogData.item;
- var fields = {};
-
- if (!validItem(item, "ReplicationController")) {
- $scope.$applyAsync(function () {
- $scope.$dismiss();
- });
- return;
- }
-
- fields.replicas = item.spec ? item.spec.replicas : 1;
-
- function validate() {
- var defer = $q.defer();
- var replicas = Number(fields.replicas.trim());
- var ex;
-
- if (isNaN(replicas) || replicas < 0)
- ex = new Error(_("Not a valid number of replicas"));
- else if (replicas > 128)
- ex = new Error(_("The maximum number of replicas is 128"));
-
- if (ex) {
- ex.target = "#replicas";
- defer.reject(ex);
- } else {
- defer.resolve({ spec: { replicas: replicas } });
- }
-
- return defer.promise;
- }
-
- $scope.fields = fields;
- $scope.item = item;
-
- $scope.performModify = function performModify() {
- return validate().then(function(data) {
- return methods.patch($scope.item, data);
- });
- };
- }
- ])
-
- .controller("RouteModifyCtrl", [
- "$q",
- "$scope",
- "$modalInstance",
- "dialogData",
- "kubeMethods",
- "KubeTranslate",
- function($q, $scope, $instance, dialogData, methods, translate) {
- const _ = translate.gettext;
- var fields = {};
-
- if (!validItem(dialogData.item, "Route")) {
- $scope.$applyAsync(function () {
- $scope.$dismiss();
- });
- return;
- }
-
- fields.host = dialogData.item.spec.host;
-
- function validate() {
- var defer = $q.defer();
- var host = fields.host.trim();
- var ex;
-
- if (!host) {
- ex = new Error(_("Not a valid value for Host"));
- ex.target = "#host-value";
- defer.reject(ex);
- } else {
- defer.resolve({ spec: { host: fields.host.trim() } });
- }
-
- return defer.promise;
- }
-
- $scope.fields = fields;
- angular.extend($scope, dialogData);
-
- $scope.performModify = function performModify() {
- return validate().then(function(data) {
- return methods.patch($scope.item, data);
- });
- };
- }
- ])
-
- .controller("ServiceModifyCtrl", [
- "$q",
- "$scope",
- "$modalInstance",
- "dialogData",
- 'kubeLoader',
- 'kubeSelect',
- "KubeRequest",
- "KubeTranslate",
- "KubeFormat",
- function($q, $scope, $instance, dialogData, loader, select, KubeRequest, translate, format) {
- const _ = translate.gettext;
- var fields = {};
- var key;
-
- if (!validItem(dialogData.item, "Service")) {
- $scope.$applyAsync(function () {
- $scope.$dismiss();
- });
- return;
- }
-
- $scope.rcs = select().kind("ReplicationController")
- .namespace(dialogData.item.metadata.namespace || "")
- .label(dialogData.item.spec.selector || {});
-
- for (key in $scope.rcs) {
- var item = $scope.rcs[key];
- fields[key] = {
- name: item.metadata.name,
- replicas: item.spec.replicas,
- };
- }
-
- $scope.service = dialogData.item;
- $scope.fields = fields;
- angular.extend($scope, dialogData);
-
- function validate() {
- var defer = $q.defer();
- var link;
- var objects = [];
- var failures = [];
-
- for (link in fields) {
- var ex;
- var replicas = Number(fields[link].replicas);
- var name = fields[link].name;
-
- if (isNaN(replicas) || replicas < 0)
- ex = new Error(_("Not a valid number of replicas"));
- else if (replicas > 128)
- ex = new Error(_("The maximum number of replicas is 128"));
-
- if (ex) {
- ex.target = "#" + name;
- failures.push(ex);
- } else {
- objects.push({
- link: link,
- name: name,
- data: { spec: { replicas: replicas } }
- });
- }
- }
-
- if (failures.length > 0) {
- defer.reject(failures);
- } else
- defer.resolve(objects);
-
- return defer.promise;
- }
-
- $scope.performModify = function performModify() {
- var defer = $q.defer();
- var req;
-
- validate().then(function (objects) {
- function step() {
- var obj = objects.shift();
- if (!obj) {
- defer.resolve();
- return;
- }
-
- defer.notify(format.format(_("Updating $0..."), obj.name));
-
- var config = { headers: { "Content-Type": "application/strategic-merge-patch+json" } };
- new KubeRequest("PATCH", obj.link, JSON.stringify(obj.data), config)
- .then(function(response) {
- step();
- }, function(response) {
- var resp = response.data;
- return defer.reject(resp || response);
- });
- }
-
- step();
- })
- .catch(function(exs) {
- defer.reject(exs);
- });
-
- var promise = defer.promise;
- promise.cancel = function cancel() {
- if (req && req.cancel)
- req.cancel();
- };
-
- return promise;
- };
- }
- ])
-
- .directive('deploymentconfigBody',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/deploymentconfig-body.html'
- };
- }
- )
-
- .directive('replicationcontrollerPods',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/replicationcontroller-pods.html'
- };
- }
- )
-
- .directive('replicationcontrollerBody',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/replicationcontroller-body.html'
- };
- }
- )
-
- .directive('routeBody',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/route-body.html'
- };
- }
- )
-
- .directive('serviceBody',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/service-body.html'
- };
- }
- )
-
- .directive('serviceEndpoint',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/service-endpoint.html'
- };
- }
- );
-}());
diff --git a/pkg/kubernetes/scripts/fixture-basic.js b/pkg/kubernetes/scripts/fixture-basic.js
deleted file mode 100644
index 5b2594f1d..000000000
--- a/pkg/kubernetes/scripts/fixture-basic.js
+++ /dev/null
@@ -1,233 +0,0 @@
-export const FIXTURE_BASIC = {
- "nodes/127.0.0.1": {
- "kind": "Node",
- "metadata": {
- "name": "127.0.0.1",
- "uid": "f530580d-a169-11e4-8651-10c37bdb8410",
- "creationTimestamp": "2015-01-21T13:35:18+01:00",
- "resourceVersion": 1,
- },
- "spec": {
- "capacity": {
- "cpu": "1k",
- "memory": "3Gi",
- }
- },
- "status": {
- "hostIP": "127.0.0.1",
- "conditions": [
- {
- "kind": "Ready",
- "status": "Full",
- "lastTransitionTime": null
- }
- ]
- }
- },
- "namespaces/default/pods/database-1": {
- "kind": "Pod",
- "metadata": {
- "name": "wordpress",
- "resourceVersion": 5,
- "uid": "0b547d64-ab8a-11e4-9a7c-080027300d85",
- "namespace": "default",
- "labels": {
- "name": "wordpressreplica"
- },
- },
- "spec": {
- "volumes": null,
- "containers": [
- {
- "name": "slave",
- "image": "jbfink/wordpress",
- "ports": [
- {
- "hostPort": 81,
- "containerPort": 80,
- "protocol": "TCP"
- }
- ],
- "imagePullPolicy": "IfNotPresent"
- }
- ],
- "restartPolicy": {
- "always": {}
- },
- "dnsPolicy": "ClusterFirst",
- "nodeName": "127.0.0.1"
- },
- "status": {
- "phase": "Running",
- "conditions": [
- {
- "kind": "Ready",
- "status": "Full"
- }
- ],
- "hostIP": "127.0.0.1",
- "podIP": "172.17.4.173",
- "info": {
- "POD": {
- "state": {
- "running": {
- "startedAt": "2015-02-13T16:21:35Z"
- }
- },
- "ready": false,
- "restartCount": 0,
- "containerID": "docker://9031b6aef7829ec029955377bd53642760899d4eed37738830756d0ce092a01d",
- "podIP": "172.17.4.173",
- "image": "kubernetes/pause:0.8.0",
- "imageID": "docker://6c4579af347b649857e915521132f15a06186d73faa62145e3eeeb6be0e97c27"
- },
- "slave": {
- "state": {
- "running": {
- "startedAt": "2015-02-13T16:27:49Z"
- }
- },
- "ready": true,
- "restartCount": 0,
- "containerID": "docker://dc70bd24ecc7fd86a385d67bdbc2a60b219cf34fdd215f8f599c95ba93b1a82b",
- "image": "jbfink/wordpress",
- "imageID": "docker://0beee7f478c860c8444aa6a3966e1cb0cd574a01c874fc5dcc48585bd45dba52"
- }
- }
- }
- },
- "namespaces/default/pods/apache": {
- "kind": "Pod",
- "metadata": {
- "name": "apache",
- "uid": "11768037-ab8a-11e4-9a7c-080027300d85",
- "resourceVersion": 5,
- "namespace": "default",
- "labels": {
- "name": "apache"
- },
- },
- "spec": {
- "volumes": null,
- "containers": [
- {
- "name": "slave",
- "image": "fedora/apache",
- "ports": [
- {
- "hostPort": 8084,
- "containerPort": 80,
- "protocol": "TCP"
- }
- ],
- "imagePullPolicy": "IfNotPresent"
- }
- ],
- "restartPolicy": {
- "always": {}
- },
- "dnsPolicy": "ClusterFirst"
- },
- },
- "namespaces/other/pods/apache": {
- "kind": "Pod",
- "metadata": {
- "name": "apache",
- "uid": "9f1a316f-4db6-11e5-971a-525400e58104",
- "resourceVersion": 5,
- "namespace": "other",
- "labels": {
- "name": "apache"
- },
- },
- "spec": {
- "volumes": null,
- "containers": [
- {
- "name": "slave",
- "image": "fedora/apache",
- "ports": [
- {
- "hostPort": 8084,
- "containerPort": 80,
- "protocol": "TCP"
- }
- ],
- "imagePullPolicy": "IfNotPresent"
- }
- ],
- "restartPolicy": {
- "always": {}
- },
- "dnsPolicy": "ClusterFirst"
- },
- },
- "namespaces/default/services/kubernetes": {
- "kind": "Service",
- "metadata": {
- "name": "kubernetes",
- "namespace": "default",
- "uid": "9750385b-7fa4-11e4-91e3-10c37bdb8410",
- "resourceVersion": "15",
- },
- "spec": {
- "port": 443,
- "protocol": "TCP",
- "selector": {
- "component": "apiserver",
- "provider": "kubernetes"
- },
- "clusterIP": "10.254.224.238",
- "containerPort": 0,
- "sessionAffinity": "None"
- },
- "status": {}
- },
- "namespaces/default/services/kubernetes-ro": {
- "kind": "Service",
- "apiVersion": "v1",
- "metadata": {
- "name": "kubernetes-ro",
- "namespace": "default",
- "selfLink": "/api/v1/namespaces/default/services/kubernetes-ro",
- "uid": "97504104-7fa4-11e4-91e3-10c37bdb8410",
- "resourceVersion": "16",
- },
- "spec": {
- "port": 80,
- "protocol": "TCP",
- "selector": {
- "component": "apiserver",
- "provider": "kubernetes"
- },
- "clusterIP": "10.254.117.100",
- "containerPort": 0,
- "sessionAffinity": "None"
- },
- "status": {}
- },
- "namespaces/default/imagestreams/mock-image-stream": {
- "kind": "ImageStream",
- "apiVersion": "v1",
- "metadata": {
- "name": "mock-image-stream",
- "namespace":"default",
- "uid":"c216455b-4cc5-11e5-8a7f-0e5582eacc27"
- },
- "spec": {
- "dockerImageRepository": "mock/image",
- "tags": [
- {
- "name": "latest",
- "annotations": {
- "description": "Mock Image",
- "iconClass": "icon-mock",
- "tags": "builder,mock",
- "version": "3.0"
- }
- }
- ]
- },
- "status": {}
- },
-};
diff --git a/pkg/kubernetes/scripts/fixture-large.js b/pkg/kubernetes/scripts/fixture-large.js
deleted file mode 100644
index 4e75c9b1b..000000000
--- a/pkg/kubernetes/scripts/fixture-large.js
+++ /dev/null
@@ -1,16041 +0,0 @@
-export const FIXTURE_LARGE = {
- "namespaces/default/pods/mock-0": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-0",
- "number": "0",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-0",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000000",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-1": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-1",
- "number": "1",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-1",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000001",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-2": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-2",
- "number": "2",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-2",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000002",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-3": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-3",
- "number": "3",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-3",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000003",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-4": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-4",
- "number": "4",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-4",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000004",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-5": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-5",
- "number": "5",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-5",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000005",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-6": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-6",
- "number": "6",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-6",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000006",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-7": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-7",
- "number": "7",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-7",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000007",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-8": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-8",
- "number": "8",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-8",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000008",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-9": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-9",
- "number": "9",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-9",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000009",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-10": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-10",
- "number": "10",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-10",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000010",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-11": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-11",
- "number": "11",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-11",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000011",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-12": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-12",
- "number": "12",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-12",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000012",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-13": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-13",
- "number": "13",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-13",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000013",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-14": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-14",
- "number": "14",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-14",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000014",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-15": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-15",
- "number": "15",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-15",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000015",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-16": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-16",
- "number": "16",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-16",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000016",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-17": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-17",
- "number": "17",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-17",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000017",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-18": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-18",
- "number": "18",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-18",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000018",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-19": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-19",
- "number": "19",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-19",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000019",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-20": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-20",
- "number": "20",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-20",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000020",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-21": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-21",
- "number": "21",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-21",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000021",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-22": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-22",
- "number": "22",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-22",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000022",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-23": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-23",
- "number": "23",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-23",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000023",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-24": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-24",
- "number": "24",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-24",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000024",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-25": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-25",
- "number": "25",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-25",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000025",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-26": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-26",
- "number": "26",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-26",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000026",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-27": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-27",
- "number": "27",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-27",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000027",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-28": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-28",
- "number": "28",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-28",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000028",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-29": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-29",
- "number": "29",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-29",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000029",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-30": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-30",
- "number": "30",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-30",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000030",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-31": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-31",
- "number": "31",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-31",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000031",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-32": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-32",
- "number": "32",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-32",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000032",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-33": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-33",
- "number": "33",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-33",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000033",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-34": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-34",
- "number": "34",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-34",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000034",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-35": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-35",
- "number": "35",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-35",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000035",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-36": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-36",
- "number": "36",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-36",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000036",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-37": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-37",
- "number": "37",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-37",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000037",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-38": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-38",
- "number": "38",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-38",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000038",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-39": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-39",
- "number": "39",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-39",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000039",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-40": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-40",
- "number": "40",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-40",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000040",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-41": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-41",
- "number": "41",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-41",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000041",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-42": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-42",
- "number": "42",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-42",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000042",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-43": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-43",
- "number": "43",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-43",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000043",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-44": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-44",
- "number": "44",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-44",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000044",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-45": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-45",
- "number": "45",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-45",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000045",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-46": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-46",
- "number": "46",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-46",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000046",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-47": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-47",
- "number": "47",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-47",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000047",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-48": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-48",
- "number": "48",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-48",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000048",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-49": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-49",
- "number": "49",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-49",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000049",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-50": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-50",
- "number": "50",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-50",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000050",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-51": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-51",
- "number": "51",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-51",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000051",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-52": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-52",
- "number": "52",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-52",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000052",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-53": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-53",
- "number": "53",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-53",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000053",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-54": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-54",
- "number": "54",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-54",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000054",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-55": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-55",
- "number": "55",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-55",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000055",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-56": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-56",
- "number": "56",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-56",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000056",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-57": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-57",
- "number": "57",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-57",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000057",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-58": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-58",
- "number": "58",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-58",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000058",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-59": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-59",
- "number": "59",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-59",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000059",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-60": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-60",
- "number": "60",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-60",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000060",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-61": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-61",
- "number": "61",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-61",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000061",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-62": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-62",
- "number": "62",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-62",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000062",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-63": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-63",
- "number": "63",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-63",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000063",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-64": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-64",
- "number": "64",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-64",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000064",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-65": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-65",
- "number": "65",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-65",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000065",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-66": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-66",
- "number": "66",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-66",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000066",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-67": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-67",
- "number": "67",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-67",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000067",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-68": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-68",
- "number": "68",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-68",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000068",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-69": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-69",
- "number": "69",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-69",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000069",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-70": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-70",
- "number": "70",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-70",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000070",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-71": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-71",
- "number": "71",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-71",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000071",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-72": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-72",
- "number": "72",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-72",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000072",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-73": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-73",
- "number": "73",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-73",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000073",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-74": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-74",
- "number": "74",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-74",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000074",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-75": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-75",
- "number": "75",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-75",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000075",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-76": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-76",
- "number": "76",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-76",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000076",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-77": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-77",
- "number": "77",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-77",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000077",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-78": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-78",
- "number": "78",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-78",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000078",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-79": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-79",
- "number": "79",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-79",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000079",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-80": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-80",
- "number": "80",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-80",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000080",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-81": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-81",
- "number": "81",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-81",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000081",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-82": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-82",
- "number": "82",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-82",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000082",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-83": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-83",
- "number": "83",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-83",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000083",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-84": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-84",
- "number": "84",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-84",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000084",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-85": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-85",
- "number": "85",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-85",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000085",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-86": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-86",
- "number": "86",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-86",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000086",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-87": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-87",
- "number": "87",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-87",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000087",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-88": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-88",
- "number": "88",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-88",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000088",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-89": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-89",
- "number": "89",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-89",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000089",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-90": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-90",
- "number": "90",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-90",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000090",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-91": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-91",
- "number": "91",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-91",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000091",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-92": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-92",
- "number": "92",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-92",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000092",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-93": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-93",
- "number": "93",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-93",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000093",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-94": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-94",
- "number": "94",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-94",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000094",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-95": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-95",
- "number": "95",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-95",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000095",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-96": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-96",
- "number": "96",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-96",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000096",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-97": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-97",
- "number": "97",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-97",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000097",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-98": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-98",
- "number": "98",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-98",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000098",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-99": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-99",
- "number": "99",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-99",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000099",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-100": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-100",
- "number": "100",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-100",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000100",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-101": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-101",
- "number": "101",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-101",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000101",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-102": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-102",
- "number": "102",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-102",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000102",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-103": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-103",
- "number": "103",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-103",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000103",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-104": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-104",
- "number": "104",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-104",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000104",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-105": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-105",
- "number": "105",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-105",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000105",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-106": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-106",
- "number": "106",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-106",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000106",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-107": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-107",
- "number": "107",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-107",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000107",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-108": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-108",
- "number": "108",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-108",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000108",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-109": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-109",
- "number": "109",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-109",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000109",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-110": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-110",
- "number": "110",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-110",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000110",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-111": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-111",
- "number": "111",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-111",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000111",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-112": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-112",
- "number": "112",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-112",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000112",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-113": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-113",
- "number": "113",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-113",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000113",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-114": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-114",
- "number": "114",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-114",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000114",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-115": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-115",
- "number": "115",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-115",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000115",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-116": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-116",
- "number": "116",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-116",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000116",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-117": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-117",
- "number": "117",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-117",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000117",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-118": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-118",
- "number": "118",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-118",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000118",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-119": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-119",
- "number": "119",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-119",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000119",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-120": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-120",
- "number": "120",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-120",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000120",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-121": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-121",
- "number": "121",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-121",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000121",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-122": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-122",
- "number": "122",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-122",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000122",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-123": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-123",
- "number": "123",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-123",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000123",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-124": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-124",
- "number": "124",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-124",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000124",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-125": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-125",
- "number": "125",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-125",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000125",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-126": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-126",
- "number": "126",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-126",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000126",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-127": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-127",
- "number": "127",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-127",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000127",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-128": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-128",
- "number": "128",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-128",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000128",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-129": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-129",
- "number": "129",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-129",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000129",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-130": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-130",
- "number": "130",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-130",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000130",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-131": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-131",
- "number": "131",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-131",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000131",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-132": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-132",
- "number": "132",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-132",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000132",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-133": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-133",
- "number": "133",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-133",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000133",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-134": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-134",
- "number": "134",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-134",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000134",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-135": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-135",
- "number": "135",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-135",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000135",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-136": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-136",
- "number": "136",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-136",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000136",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-137": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-137",
- "number": "137",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-137",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000137",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-138": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-138",
- "number": "138",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-138",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000138",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-139": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-139",
- "number": "139",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-139",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000139",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-140": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-140",
- "number": "140",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-140",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000140",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-141": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-141",
- "number": "141",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-141",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000141",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-142": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-142",
- "number": "142",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-142",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000142",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-143": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-143",
- "number": "143",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-143",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000143",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-144": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-144",
- "number": "144",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-144",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000144",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-145": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-145",
- "number": "145",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-145",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000145",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-146": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-146",
- "number": "146",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-146",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000146",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-147": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-147",
- "number": "147",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-147",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000147",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-148": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-148",
- "number": "148",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-148",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000148",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-149": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-149",
- "number": "149",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-149",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000149",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-150": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-150",
- "number": "150",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-150",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000150",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-151": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-151",
- "number": "151",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-151",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000151",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-152": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-152",
- "number": "152",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-152",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000152",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-153": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-153",
- "number": "153",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-153",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000153",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-154": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-154",
- "number": "154",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-154",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000154",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-155": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-155",
- "number": "155",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-155",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000155",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-156": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-156",
- "number": "156",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-156",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000156",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-157": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-157",
- "number": "157",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-157",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000157",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-158": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-158",
- "number": "158",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-158",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000158",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-159": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-159",
- "number": "159",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-159",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000159",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-160": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-160",
- "number": "160",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-160",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000160",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-161": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-161",
- "number": "161",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-161",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000161",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-162": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-162",
- "number": "162",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-162",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000162",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-163": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-163",
- "number": "163",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-163",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000163",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-164": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-164",
- "number": "164",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-164",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000164",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-165": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-165",
- "number": "165",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-165",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000165",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-166": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-166",
- "number": "166",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-166",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000166",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-167": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-167",
- "number": "167",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-167",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000167",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-168": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-168",
- "number": "168",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-168",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000168",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-169": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-169",
- "number": "169",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-169",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000169",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-170": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-170",
- "number": "170",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-170",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000170",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-171": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-171",
- "number": "171",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-171",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000171",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-172": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-172",
- "number": "172",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-172",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000172",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-173": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-173",
- "number": "173",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-173",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000173",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-174": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-174",
- "number": "174",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-174",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000174",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-175": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-175",
- "number": "175",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-175",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000175",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-176": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-176",
- "number": "176",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-176",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000176",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-177": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-177",
- "number": "177",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-177",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000177",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-178": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-178",
- "number": "178",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-178",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000178",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-179": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-179",
- "number": "179",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-179",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000179",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-180": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-180",
- "number": "180",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-180",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000180",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-181": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-181",
- "number": "181",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-181",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000181",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-182": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-182",
- "number": "182",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-182",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000182",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-183": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-183",
- "number": "183",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-183",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000183",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-184": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-184",
- "number": "184",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-184",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000184",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-185": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-185",
- "number": "185",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-185",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000185",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-186": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-186",
- "number": "186",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-186",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000186",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-187": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-187",
- "number": "187",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-187",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000187",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-188": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-188",
- "number": "188",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-188",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000188",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-189": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-189",
- "number": "189",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-189",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000189",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-190": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-190",
- "number": "190",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-190",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000190",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-191": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-191",
- "number": "191",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-191",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000191",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-192": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-192",
- "number": "192",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-192",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000192",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-193": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-193",
- "number": "193",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-193",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000193",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-194": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-194",
- "number": "194",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-194",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000194",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-195": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-195",
- "number": "195",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-195",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000195",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-196": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-196",
- "number": "196",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-196",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000196",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-197": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-197",
- "number": "197",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-197",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000197",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-198": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-198",
- "number": "198",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-198",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000198",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-199": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-199",
- "number": "199",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-199",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000199",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-200": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-200",
- "number": "200",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-200",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000200",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-201": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-201",
- "number": "201",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-201",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000201",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-202": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-202",
- "number": "202",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-202",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000202",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-203": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-203",
- "number": "203",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-203",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000203",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-204": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-204",
- "number": "204",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-204",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000204",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-205": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-205",
- "number": "205",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-205",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000205",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-206": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-206",
- "number": "206",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-206",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000206",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-207": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-207",
- "number": "207",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-207",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000207",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-208": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-208",
- "number": "208",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-208",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000208",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-209": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-209",
- "number": "209",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-209",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000209",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-210": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-210",
- "number": "210",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-210",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000210",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-211": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-211",
- "number": "211",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-211",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000211",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-212": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-212",
- "number": "212",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-212",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000212",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-213": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-213",
- "number": "213",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-213",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000213",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-214": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-214",
- "number": "214",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-214",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000214",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-215": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-215",
- "number": "215",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-215",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000215",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-216": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-216",
- "number": "216",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-216",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000216",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-217": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-217",
- "number": "217",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-217",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000217",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-218": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-218",
- "number": "218",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-218",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000218",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-219": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-219",
- "number": "219",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-219",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000219",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-220": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-220",
- "number": "220",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-220",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000220",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-221": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-221",
- "number": "221",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-221",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000221",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-222": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-222",
- "number": "222",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-222",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000222",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-223": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-223",
- "number": "223",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-223",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000223",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-224": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-224",
- "number": "224",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-224",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000224",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-225": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-225",
- "number": "225",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-225",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000225",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-226": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-226",
- "number": "226",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-226",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000226",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-227": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-227",
- "number": "227",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-227",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000227",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-228": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-228",
- "number": "228",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-228",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000228",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-229": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-229",
- "number": "229",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-229",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000229",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-230": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-230",
- "number": "230",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-230",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000230",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-231": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-231",
- "number": "231",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-231",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000231",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-232": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-232",
- "number": "232",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-232",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000232",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-233": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-233",
- "number": "233",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-233",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000233",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-234": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-234",
- "number": "234",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-234",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000234",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-235": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-235",
- "number": "235",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-235",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000235",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-236": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-236",
- "number": "236",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-236",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000236",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-237": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-237",
- "number": "237",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-237",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000237",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-238": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-238",
- "number": "238",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-238",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000238",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-239": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-239",
- "number": "239",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-239",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000239",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-240": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-240",
- "number": "240",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-240",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000240",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-241": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-241",
- "number": "241",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-241",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000241",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-242": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-242",
- "number": "242",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-242",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000242",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-243": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-243",
- "number": "243",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-243",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000243",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-244": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-244",
- "number": "244",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-244",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000244",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-245": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-245",
- "number": "245",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-245",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000245",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-246": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-246",
- "number": "246",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-246",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000246",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-247": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-247",
- "number": "247",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-247",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000247",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-248": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-248",
- "number": "248",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-248",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000248",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-249": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-249",
- "number": "249",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-249",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000249",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-250": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-250",
- "number": "250",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-250",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000250",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-251": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-251",
- "number": "251",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-251",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000251",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-252": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-252",
- "number": "252",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-252",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000252",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-253": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-253",
- "number": "253",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-253",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000253",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-254": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-254",
- "number": "254",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-254",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000254",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-255": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-255",
- "number": "255",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-255",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000255",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-256": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-256",
- "number": "256",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-256",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000256",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-257": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-257",
- "number": "257",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-257",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000257",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-258": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-258",
- "number": "258",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-258",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000258",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-259": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-259",
- "number": "259",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-259",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000259",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-260": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-260",
- "number": "260",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-260",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000260",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-261": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-261",
- "number": "261",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-261",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000261",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-262": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-262",
- "number": "262",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-262",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000262",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-263": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-263",
- "number": "263",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-263",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000263",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-264": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-264",
- "number": "264",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-264",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000264",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-265": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-265",
- "number": "265",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-265",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000265",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-266": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-266",
- "number": "266",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-266",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000266",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-267": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-267",
- "number": "267",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-267",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000267",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-268": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-268",
- "number": "268",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-268",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000268",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-269": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-269",
- "number": "269",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-269",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000269",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-270": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-270",
- "number": "270",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-270",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000270",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-271": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-271",
- "number": "271",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-271",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000271",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-272": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-272",
- "number": "272",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-272",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000272",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-273": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-273",
- "number": "273",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-273",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000273",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-274": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-274",
- "number": "274",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-274",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000274",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-275": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-275",
- "number": "275",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-275",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000275",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-276": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-276",
- "number": "276",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-276",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000276",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-277": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-277",
- "number": "277",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-277",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000277",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-278": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-278",
- "number": "278",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-278",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000278",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-279": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-279",
- "number": "279",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-279",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000279",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-280": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-280",
- "number": "280",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-280",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000280",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-281": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-281",
- "number": "281",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-281",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000281",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-282": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-282",
- "number": "282",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-282",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000282",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-283": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-283",
- "number": "283",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-283",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000283",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-284": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-284",
- "number": "284",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-284",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000284",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-285": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-285",
- "number": "285",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-285",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000285",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-286": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-286",
- "number": "286",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-286",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000286",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-287": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-287",
- "number": "287",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-287",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000287",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-288": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-288",
- "number": "288",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-288",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000288",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-289": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-289",
- "number": "289",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-289",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000289",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-290": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-290",
- "number": "290",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-290",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000290",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-291": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-291",
- "number": "291",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-291",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000291",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-292": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-292",
- "number": "292",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-292",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000292",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-293": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-293",
- "number": "293",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-293",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000293",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-294": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-294",
- "number": "294",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-294",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000294",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-295": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-295",
- "number": "295",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-295",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000295",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-296": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-296",
- "number": "296",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-296",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000296",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-297": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-297",
- "number": "297",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-297",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000297",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-298": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-298",
- "number": "298",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-298",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000298",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-299": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-299",
- "number": "299",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-299",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000299",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-300": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-300",
- "number": "300",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-300",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000300",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-301": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-301",
- "number": "301",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-301",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000301",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-302": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-302",
- "number": "302",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-302",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000302",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-303": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-303",
- "number": "303",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-303",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000303",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-304": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-304",
- "number": "304",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-304",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000304",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-305": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-305",
- "number": "305",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-305",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000305",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-306": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-306",
- "number": "306",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-306",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000306",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-307": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-307",
- "number": "307",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-307",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000307",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-308": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-308",
- "number": "308",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-308",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000308",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-309": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-309",
- "number": "309",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-309",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000309",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-310": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-310",
- "number": "310",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-310",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000310",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-311": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-311",
- "number": "311",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-311",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000311",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-312": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-312",
- "number": "312",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-312",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000312",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-313": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-313",
- "number": "313",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-313",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000313",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-314": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-314",
- "number": "314",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-314",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000314",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-315": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-315",
- "number": "315",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-315",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000315",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-316": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-316",
- "number": "316",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-316",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000316",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-317": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-317",
- "number": "317",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-317",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000317",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-318": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-318",
- "number": "318",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-318",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000318",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-319": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-319",
- "number": "319",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-319",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000319",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-320": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-320",
- "number": "320",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-320",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000320",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-321": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-321",
- "number": "321",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-321",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000321",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-322": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-322",
- "number": "322",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-322",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000322",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-323": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-323",
- "number": "323",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-323",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000323",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-324": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-324",
- "number": "324",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-324",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000324",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-325": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-325",
- "number": "325",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-325",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000325",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-326": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-326",
- "number": "326",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-326",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000326",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-327": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-327",
- "number": "327",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-327",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000327",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-328": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-328",
- "number": "328",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-328",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000328",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-329": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-329",
- "number": "329",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-329",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000329",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-330": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-330",
- "number": "330",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-330",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000330",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-331": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-331",
- "number": "331",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-331",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000331",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-332": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-332",
- "number": "332",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-332",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000332",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-333": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-333",
- "number": "333",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-333",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000333",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-334": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-334",
- "number": "334",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-334",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000334",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-335": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-335",
- "number": "335",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-335",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000335",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-336": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-336",
- "number": "336",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-336",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000336",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-337": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-337",
- "number": "337",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-337",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000337",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-338": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-338",
- "number": "338",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-338",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000338",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-339": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-339",
- "number": "339",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-339",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000339",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-340": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-340",
- "number": "340",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-340",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000340",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-341": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-341",
- "number": "341",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-341",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000341",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-342": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-342",
- "number": "342",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-342",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000342",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-343": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-343",
- "number": "343",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-343",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000343",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-344": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-344",
- "number": "344",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-344",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000344",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-345": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-345",
- "number": "345",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-345",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000345",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-346": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-346",
- "number": "346",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-346",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000346",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-347": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-347",
- "number": "347",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-347",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000347",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-348": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-348",
- "number": "348",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-348",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000348",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-349": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-349",
- "number": "349",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-349",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000349",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-350": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-350",
- "number": "350",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-350",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000350",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-351": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-351",
- "number": "351",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-351",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000351",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-352": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-352",
- "number": "352",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-352",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000352",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-353": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-353",
- "number": "353",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-353",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000353",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-354": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-354",
- "number": "354",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-354",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000354",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-355": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-355",
- "number": "355",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-355",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000355",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-356": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-356",
- "number": "356",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-356",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000356",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-357": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-357",
- "number": "357",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-357",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000357",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-358": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-358",
- "number": "358",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-358",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000358",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-359": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-359",
- "number": "359",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-359",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000359",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-360": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-360",
- "number": "360",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-360",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000360",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-361": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-361",
- "number": "361",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-361",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000361",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-362": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-362",
- "number": "362",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-362",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000362",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-363": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-363",
- "number": "363",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-363",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000363",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-364": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-364",
- "number": "364",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-364",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000364",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-365": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-365",
- "number": "365",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-365",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000365",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-366": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-366",
- "number": "366",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-366",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000366",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-367": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-367",
- "number": "367",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-367",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000367",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-368": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-368",
- "number": "368",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-368",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000368",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-369": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-369",
- "number": "369",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-369",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000369",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-370": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-370",
- "number": "370",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-370",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000370",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-371": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-371",
- "number": "371",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-371",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000371",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-372": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-372",
- "number": "372",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-372",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000372",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-373": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-373",
- "number": "373",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-373",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000373",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-374": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-374",
- "number": "374",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-374",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000374",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-375": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-375",
- "number": "375",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-375",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000375",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-376": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-376",
- "number": "376",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-376",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000376",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-377": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-377",
- "number": "377",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-377",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000377",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-378": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-378",
- "number": "378",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-378",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000378",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-379": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-379",
- "number": "379",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-379",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000379",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-380": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-380",
- "number": "380",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-380",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000380",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-381": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-381",
- "number": "381",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-381",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000381",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-382": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-382",
- "number": "382",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-382",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000382",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-383": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-383",
- "number": "383",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-383",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000383",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-384": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-384",
- "number": "384",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-384",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000384",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-385": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-385",
- "number": "385",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-385",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000385",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-386": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-386",
- "number": "386",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-386",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000386",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-387": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-387",
- "number": "387",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-387",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000387",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-388": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-388",
- "number": "388",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-388",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000388",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-389": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-389",
- "number": "389",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-389",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000389",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-390": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-390",
- "number": "390",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-390",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000390",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-391": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-391",
- "number": "391",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-391",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000391",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-392": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-392",
- "number": "392",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-392",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000392",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-393": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-393",
- "number": "393",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-393",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000393",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-394": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-394",
- "number": "394",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-394",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000394",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-395": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-395",
- "number": "395",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-395",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000395",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-396": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-396",
- "number": "396",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-396",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000396",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-397": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-397",
- "number": "397",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-397",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000397",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-398": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-398",
- "number": "398",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-398",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000398",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-399": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-399",
- "number": "399",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-399",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000399",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-400": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-400",
- "number": "400",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-400",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000400",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-401": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-401",
- "number": "401",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-401",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000401",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-402": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-402",
- "number": "402",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-402",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000402",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-403": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-403",
- "number": "403",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-403",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000403",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-404": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-404",
- "number": "404",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-404",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000404",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-405": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-405",
- "number": "405",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-405",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000405",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-406": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-406",
- "number": "406",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-406",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000406",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-407": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-407",
- "number": "407",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-407",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000407",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-408": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-408",
- "number": "408",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-408",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000408",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-409": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-409",
- "number": "409",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-409",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000409",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-410": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-410",
- "number": "410",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-410",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000410",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-411": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-411",
- "number": "411",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-411",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000411",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-412": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-412",
- "number": "412",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-412",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000412",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-413": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-413",
- "number": "413",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-413",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000413",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-414": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-414",
- "number": "414",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-414",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000414",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-415": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-415",
- "number": "415",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-415",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000415",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-416": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-416",
- "number": "416",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-416",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000416",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-417": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-417",
- "number": "417",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-417",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000417",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-418": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-418",
- "number": "418",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-418",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000418",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-419": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-419",
- "number": "419",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-419",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000419",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-420": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-420",
- "number": "420",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-420",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000420",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-421": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-421",
- "number": "421",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-421",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000421",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-422": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-422",
- "number": "422",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-422",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000422",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-423": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-423",
- "number": "423",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-423",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000423",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-424": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-424",
- "number": "424",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-424",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000424",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-425": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-425",
- "number": "425",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-425",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000425",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-426": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-426",
- "number": "426",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-426",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000426",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-427": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-427",
- "number": "427",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-427",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000427",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-428": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-428",
- "number": "428",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-428",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000428",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-429": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-429",
- "number": "429",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-429",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000429",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-430": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-430",
- "number": "430",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-430",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000430",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-431": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-431",
- "number": "431",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-431",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000431",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-432": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-432",
- "number": "432",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-432",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000432",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-433": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-433",
- "number": "433",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-433",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000433",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-434": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-434",
- "number": "434",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-434",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000434",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-435": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-435",
- "number": "435",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-435",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000435",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-436": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-436",
- "number": "436",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-436",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000436",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-437": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-437",
- "number": "437",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-437",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000437",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-438": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-438",
- "number": "438",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-438",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000438",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-439": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-439",
- "number": "439",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-439",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000439",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-440": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-440",
- "number": "440",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-440",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000440",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-441": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-441",
- "number": "441",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-441",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000441",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-442": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-442",
- "number": "442",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-442",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000442",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-443": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-443",
- "number": "443",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-443",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000443",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-444": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-444",
- "number": "444",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-444",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000444",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-445": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-445",
- "number": "445",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-445",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000445",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-446": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-446",
- "number": "446",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-446",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000446",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-447": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-447",
- "number": "447",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-447",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000447",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-448": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-448",
- "number": "448",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-448",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000448",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-449": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-449",
- "number": "449",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-449",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000449",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-450": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-450",
- "number": "450",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-450",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000450",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-451": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-451",
- "number": "451",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-451",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000451",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-452": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-452",
- "number": "452",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-452",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000452",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-453": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-453",
- "number": "453",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-453",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000453",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-454": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-454",
- "number": "454",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-454",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000454",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-455": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-455",
- "number": "455",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-455",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000455",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-456": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-456",
- "number": "456",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-456",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000456",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-457": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-457",
- "number": "457",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-457",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000457",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-458": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-458",
- "number": "458",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-458",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000458",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-459": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-459",
- "number": "459",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-459",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000459",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-460": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-460",
- "number": "460",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-460",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000460",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-461": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-461",
- "number": "461",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-461",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000461",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-462": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-462",
- "number": "462",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-462",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000462",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-463": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-463",
- "number": "463",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-463",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000463",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-464": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-464",
- "number": "464",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-464",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000464",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-465": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-465",
- "number": "465",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-465",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000465",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-466": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-466",
- "number": "466",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-466",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000466",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-467": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-467",
- "number": "467",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-467",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000467",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-468": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-468",
- "number": "468",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-468",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000468",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-469": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-469",
- "number": "469",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-469",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000469",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-470": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-470",
- "number": "470",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-470",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000470",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-471": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-471",
- "number": "471",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-471",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000471",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-472": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-472",
- "number": "472",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-472",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000472",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-473": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-473",
- "number": "473",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-473",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000473",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-474": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-474",
- "number": "474",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-474",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000474",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-475": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-475",
- "number": "475",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-475",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000475",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-476": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-476",
- "number": "476",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-476",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000476",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-477": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-477",
- "number": "477",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-477",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000477",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-478": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-478",
- "number": "478",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-478",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000478",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-479": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-479",
- "number": "479",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-479",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000479",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-480": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-480",
- "number": "480",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-480",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000480",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-481": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-481",
- "number": "481",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-481",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000481",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-482": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-482",
- "number": "482",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-482",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000482",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-483": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-483",
- "number": "483",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-483",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000483",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-484": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-484",
- "number": "484",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-484",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000484",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-485": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-485",
- "number": "485",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-485",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000485",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-486": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-486",
- "number": "486",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-486",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000486",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-487": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-487",
- "number": "487",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-487",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000487",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-488": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-488",
- "number": "488",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-488",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000488",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-489": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-489",
- "number": "489",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-489",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000489",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-490": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-490",
- "number": "490",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-490",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000490",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-491": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-491",
- "number": "491",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-491",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000491",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-492": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-492",
- "number": "492",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-492",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000492",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-493": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-493",
- "number": "493",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-493",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000493",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-494": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-494",
- "number": "494",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-494",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000494",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-495": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-495",
- "number": "495",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-495",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000495",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-496": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-496",
- "number": "496",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-496",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000496",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-497": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-497",
- "number": "497",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-497",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000497",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-498": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-498",
- "number": "498",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-498",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000498",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-499": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-499",
- "number": "499",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-499",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000499",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-500": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-500",
- "number": "500",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-500",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000500",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-501": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-501",
- "number": "501",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-501",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000501",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-502": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-502",
- "number": "502",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-502",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000502",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-503": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-503",
- "number": "503",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-503",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000503",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-504": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-504",
- "number": "504",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-504",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000504",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-505": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-505",
- "number": "505",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-505",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000505",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-506": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-506",
- "number": "506",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-506",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000506",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-507": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-507",
- "number": "507",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-507",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000507",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-508": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-508",
- "number": "508",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-508",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000508",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-509": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-509",
- "number": "509",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-509",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000509",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-510": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-510",
- "number": "510",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-510",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000510",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-511": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-511",
- "number": "511",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-511",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000511",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-512": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-512",
- "number": "512",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-512",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000512",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-513": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-513",
- "number": "513",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-513",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000513",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-514": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-514",
- "number": "514",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-514",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000514",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-515": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-515",
- "number": "515",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-515",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000515",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-516": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-516",
- "number": "516",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-516",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000516",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-517": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-517",
- "number": "517",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-517",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000517",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-518": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-518",
- "number": "518",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-518",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000518",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-519": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-519",
- "number": "519",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-519",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000519",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-520": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-520",
- "number": "520",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-520",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000520",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-521": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-521",
- "number": "521",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-521",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000521",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-522": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-522",
- "number": "522",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-522",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000522",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-523": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-523",
- "number": "523",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-523",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000523",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-524": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-524",
- "number": "524",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-524",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000524",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-525": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-525",
- "number": "525",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-525",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000525",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-526": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-526",
- "number": "526",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-526",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000526",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-527": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-527",
- "number": "527",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-527",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000527",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-528": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-528",
- "number": "528",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-528",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000528",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-529": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-529",
- "number": "529",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-529",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000529",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-530": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-530",
- "number": "530",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-530",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000530",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-531": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-531",
- "number": "531",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-531",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000531",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-532": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-532",
- "number": "532",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-532",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000532",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-533": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-533",
- "number": "533",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-533",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000533",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-534": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-534",
- "number": "534",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-534",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000534",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-535": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-535",
- "number": "535",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-535",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000535",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-536": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-536",
- "number": "536",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-536",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000536",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-537": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-537",
- "number": "537",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-537",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000537",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-538": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-538",
- "number": "538",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-538",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000538",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-539": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-539",
- "number": "539",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-539",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000539",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-540": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-540",
- "number": "540",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-540",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000540",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-541": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-541",
- "number": "541",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-541",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000541",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-542": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-542",
- "number": "542",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-542",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000542",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-543": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-543",
- "number": "543",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-543",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000543",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-544": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-544",
- "number": "544",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-544",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000544",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-545": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-545",
- "number": "545",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-545",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000545",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-546": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-546",
- "number": "546",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-546",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000546",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-547": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-547",
- "number": "547",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-547",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000547",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-548": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-548",
- "number": "548",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-548",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000548",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-549": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-549",
- "number": "549",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-549",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000549",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-550": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-550",
- "number": "550",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-550",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000550",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-551": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-551",
- "number": "551",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-551",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000551",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-552": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-552",
- "number": "552",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-552",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000552",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-553": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-553",
- "number": "553",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-553",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000553",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-554": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-554",
- "number": "554",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-554",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000554",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-555": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-555",
- "number": "555",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-555",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000555",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-556": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-556",
- "number": "556",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-556",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000556",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-557": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-557",
- "number": "557",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-557",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000557",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-558": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-558",
- "number": "558",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-558",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000558",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-559": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-559",
- "number": "559",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-559",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000559",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-560": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-560",
- "number": "560",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-560",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000560",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-561": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-561",
- "number": "561",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-561",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000561",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-562": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-562",
- "number": "562",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-562",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000562",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-563": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-563",
- "number": "563",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-563",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000563",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-564": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-564",
- "number": "564",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-564",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000564",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-565": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-565",
- "number": "565",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-565",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000565",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-566": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-566",
- "number": "566",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-566",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000566",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-567": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-567",
- "number": "567",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-567",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000567",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-568": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-568",
- "number": "568",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-568",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000568",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-569": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-569",
- "number": "569",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-569",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000569",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-570": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-570",
- "number": "570",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-570",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000570",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-571": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-571",
- "number": "571",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-571",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000571",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-572": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-572",
- "number": "572",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-572",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000572",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-573": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-573",
- "number": "573",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-573",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000573",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-574": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-574",
- "number": "574",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-574",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000574",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-575": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-575",
- "number": "575",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-575",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000575",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-576": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-576",
- "number": "576",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-576",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000576",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-577": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-577",
- "number": "577",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-577",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000577",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-578": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-578",
- "number": "578",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-578",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000578",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-579": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-579",
- "number": "579",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-579",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000579",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-580": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-580",
- "number": "580",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-580",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000580",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-581": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-581",
- "number": "581",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-581",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000581",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-582": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-582",
- "number": "582",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-582",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000582",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-583": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-583",
- "number": "583",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-583",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000583",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-584": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-584",
- "number": "584",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-584",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000584",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-585": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-585",
- "number": "585",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-585",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000585",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-586": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-586",
- "number": "586",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-586",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000586",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-587": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-587",
- "number": "587",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-587",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000587",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-588": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-588",
- "number": "588",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-588",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000588",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-589": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-589",
- "number": "589",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-589",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000589",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-590": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-590",
- "number": "590",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-590",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000590",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-591": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-591",
- "number": "591",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-591",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000591",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-592": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-592",
- "number": "592",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-592",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000592",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-593": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-593",
- "number": "593",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-593",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000593",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-594": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-594",
- "number": "594",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-594",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000594",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-595": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-595",
- "number": "595",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-595",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000595",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-596": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-596",
- "number": "596",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-596",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000596",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-597": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-597",
- "number": "597",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-597",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000597",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-598": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-598",
- "number": "598",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-598",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000598",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-599": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-599",
- "number": "599",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-599",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000599",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-600": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-600",
- "number": "600",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-600",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000600",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-601": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-601",
- "number": "601",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-601",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000601",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-602": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-602",
- "number": "602",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-602",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000602",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-603": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-603",
- "number": "603",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-603",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000603",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-604": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-604",
- "number": "604",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-604",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000604",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-605": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-605",
- "number": "605",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-605",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000605",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-606": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-606",
- "number": "606",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-606",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000606",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-607": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-607",
- "number": "607",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-607",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000607",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-608": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-608",
- "number": "608",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-608",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000608",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-609": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-609",
- "number": "609",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-609",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000609",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-610": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-610",
- "number": "610",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-610",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000610",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-611": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-611",
- "number": "611",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-611",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000611",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-612": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-612",
- "number": "612",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-612",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000612",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-613": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-613",
- "number": "613",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-613",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000613",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-614": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-614",
- "number": "614",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-614",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000614",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-615": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-615",
- "number": "615",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-615",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000615",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-616": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-616",
- "number": "616",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-616",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000616",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-617": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-617",
- "number": "617",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-617",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000617",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-618": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-618",
- "number": "618",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-618",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000618",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-619": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-619",
- "number": "619",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-619",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000619",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-620": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-620",
- "number": "620",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-620",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000620",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-621": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-621",
- "number": "621",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-621",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000621",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-622": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-622",
- "number": "622",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-622",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000622",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-623": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-623",
- "number": "623",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-623",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000623",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-624": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-624",
- "number": "624",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-624",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000624",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-625": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-625",
- "number": "625",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-625",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000625",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-626": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-626",
- "number": "626",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-626",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000626",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-627": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-627",
- "number": "627",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-627",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000627",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-628": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-628",
- "number": "628",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-628",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000628",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-629": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-629",
- "number": "629",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-629",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000629",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-630": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-630",
- "number": "630",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-630",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000630",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-631": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-631",
- "number": "631",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-631",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000631",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-632": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-632",
- "number": "632",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-632",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000632",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-633": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-633",
- "number": "633",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-633",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000633",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-634": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-634",
- "number": "634",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-634",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000634",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-635": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-635",
- "number": "635",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-635",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000635",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-636": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-636",
- "number": "636",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-636",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000636",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-637": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-637",
- "number": "637",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-637",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000637",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-638": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-638",
- "number": "638",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-638",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000638",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-639": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-639",
- "number": "639",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-639",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000639",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-640": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-640",
- "number": "640",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-640",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000640",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-641": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-641",
- "number": "641",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-641",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000641",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-642": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-642",
- "number": "642",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-642",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000642",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-643": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-643",
- "number": "643",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-643",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000643",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-644": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-644",
- "number": "644",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-644",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000644",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-645": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-645",
- "number": "645",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-645",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000645",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-646": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-646",
- "number": "646",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-646",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000646",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-647": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-647",
- "number": "647",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-647",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000647",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-648": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-648",
- "number": "648",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-648",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000648",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-649": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-649",
- "number": "649",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-649",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000649",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-650": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-650",
- "number": "650",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-650",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000650",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-651": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-651",
- "number": "651",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-651",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000651",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-652": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-652",
- "number": "652",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-652",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000652",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-653": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-653",
- "number": "653",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-653",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000653",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-654": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-654",
- "number": "654",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-654",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000654",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-655": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-655",
- "number": "655",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-655",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000655",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-656": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-656",
- "number": "656",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-656",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000656",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-657": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-657",
- "number": "657",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-657",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000657",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-658": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-658",
- "number": "658",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-658",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000658",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-659": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-659",
- "number": "659",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-659",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000659",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-660": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-660",
- "number": "660",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-660",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000660",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-661": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-661",
- "number": "661",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-661",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000661",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-662": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-662",
- "number": "662",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-662",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000662",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-663": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-663",
- "number": "663",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-663",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000663",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-664": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-664",
- "number": "664",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-664",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000664",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-665": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-665",
- "number": "665",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-665",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000665",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-666": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-666",
- "number": "666",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-666",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000666",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-667": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-667",
- "number": "667",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-667",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000667",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-668": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-668",
- "number": "668",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-668",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000668",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-669": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-669",
- "number": "669",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-669",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000669",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-670": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-670",
- "number": "670",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-670",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000670",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-671": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-671",
- "number": "671",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-671",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000671",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-672": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-672",
- "number": "672",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-672",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000672",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-673": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-673",
- "number": "673",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-673",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000673",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-674": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-674",
- "number": "674",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-674",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000674",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-675": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-675",
- "number": "675",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-675",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000675",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-676": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-676",
- "number": "676",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-676",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000676",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-677": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-677",
- "number": "677",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-677",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000677",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-678": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-678",
- "number": "678",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-678",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000678",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-679": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-679",
- "number": "679",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-679",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000679",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-680": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-680",
- "number": "680",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-680",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000680",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-681": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-681",
- "number": "681",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-681",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000681",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-682": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-682",
- "number": "682",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-682",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000682",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-683": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-683",
- "number": "683",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-683",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000683",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-684": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-684",
- "number": "684",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-684",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000684",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-685": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-685",
- "number": "685",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-685",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000685",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-686": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-686",
- "number": "686",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-686",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000686",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-687": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-687",
- "number": "687",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-687",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000687",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-688": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-688",
- "number": "688",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-688",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000688",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-689": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-689",
- "number": "689",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-689",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000689",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-690": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-690",
- "number": "690",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-690",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000690",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-691": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-691",
- "number": "691",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-691",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000691",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-692": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-692",
- "number": "692",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-692",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000692",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-693": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-693",
- "number": "693",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-693",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000693",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-694": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-694",
- "number": "694",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-694",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000694",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-695": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-695",
- "number": "695",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-695",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000695",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-696": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-696",
- "number": "696",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-696",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000696",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-697": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-697",
- "number": "697",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-697",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000697",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-698": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-698",
- "number": "698",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-698",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000698",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-699": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-699",
- "number": "699",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-699",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000699",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-700": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-700",
- "number": "700",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-700",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000700",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-701": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-701",
- "number": "701",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-701",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000701",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-702": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-702",
- "number": "702",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-702",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000702",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-703": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-703",
- "number": "703",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-703",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000703",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-704": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-704",
- "number": "704",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-704",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000704",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-705": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-705",
- "number": "705",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-705",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000705",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-706": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-706",
- "number": "706",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-706",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000706",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-707": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-707",
- "number": "707",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-707",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000707",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-708": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-708",
- "number": "708",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-708",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000708",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-709": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-709",
- "number": "709",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-709",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000709",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-710": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-710",
- "number": "710",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-710",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000710",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-711": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-711",
- "number": "711",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-711",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000711",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-712": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-712",
- "number": "712",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-712",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000712",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-713": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-713",
- "number": "713",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-713",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000713",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-714": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-714",
- "number": "714",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-714",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000714",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-715": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-715",
- "number": "715",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-715",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000715",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-716": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-716",
- "number": "716",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-716",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000716",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-717": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-717",
- "number": "717",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-717",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000717",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-718": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-718",
- "number": "718",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-718",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000718",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-719": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-719",
- "number": "719",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-719",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000719",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-720": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-720",
- "number": "720",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-720",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000720",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-721": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-721",
- "number": "721",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-721",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000721",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-722": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-722",
- "number": "722",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-722",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000722",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-723": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-723",
- "number": "723",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-723",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000723",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-724": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-724",
- "number": "724",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-724",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000724",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-725": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-725",
- "number": "725",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-725",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000725",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-726": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-726",
- "number": "726",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-726",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000726",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-727": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-727",
- "number": "727",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-727",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000727",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-728": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-728",
- "number": "728",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-728",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000728",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-729": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-729",
- "number": "729",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-729",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000729",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-730": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-730",
- "number": "730",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-730",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000730",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-731": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-731",
- "number": "731",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-731",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000731",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-732": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-732",
- "number": "732",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-732",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000732",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-733": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-733",
- "number": "733",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-733",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000733",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-734": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-734",
- "number": "734",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-734",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000734",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-735": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-735",
- "number": "735",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-735",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000735",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-736": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-736",
- "number": "736",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-736",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000736",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-737": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-737",
- "number": "737",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-737",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000737",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-738": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-738",
- "number": "738",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-738",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000738",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-739": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-739",
- "number": "739",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-739",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000739",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-740": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-740",
- "number": "740",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-740",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000740",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-741": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-741",
- "number": "741",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-741",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000741",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-742": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-742",
- "number": "742",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-742",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000742",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-743": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-743",
- "number": "743",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-743",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000743",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-744": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-744",
- "number": "744",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-744",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000744",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-745": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-745",
- "number": "745",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-745",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000745",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-746": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-746",
- "number": "746",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-746",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000746",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-747": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-747",
- "number": "747",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-747",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000747",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-748": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-748",
- "number": "748",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-748",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000748",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-749": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-749",
- "number": "749",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-749",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000749",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-750": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-750",
- "number": "750",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-750",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000750",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-751": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-751",
- "number": "751",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-751",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000751",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-752": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-752",
- "number": "752",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-752",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000752",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-753": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-753",
- "number": "753",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-753",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000753",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-754": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-754",
- "number": "754",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-754",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000754",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-755": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-755",
- "number": "755",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-755",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000755",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-756": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-756",
- "number": "756",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-756",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000756",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-757": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-757",
- "number": "757",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-757",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000757",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-758": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-758",
- "number": "758",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-758",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000758",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-759": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-759",
- "number": "759",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-759",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000759",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-760": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-760",
- "number": "760",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-760",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000760",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-761": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-761",
- "number": "761",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-761",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000761",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-762": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-762",
- "number": "762",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-762",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000762",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-763": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-763",
- "number": "763",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-763",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000763",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-764": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-764",
- "number": "764",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-764",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000764",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-765": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-765",
- "number": "765",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-765",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000765",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-766": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-766",
- "number": "766",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-766",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000766",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-767": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-767",
- "number": "767",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-767",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000767",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-768": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-768",
- "number": "768",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-768",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000768",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-769": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-769",
- "number": "769",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-769",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000769",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-770": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-770",
- "number": "770",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-770",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000770",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-771": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-771",
- "number": "771",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-771",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000771",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-772": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-772",
- "number": "772",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-772",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000772",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-773": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-773",
- "number": "773",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-773",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000773",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-774": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-774",
- "number": "774",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-774",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000774",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-775": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-775",
- "number": "775",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-775",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000775",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-776": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-776",
- "number": "776",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-776",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000776",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-777": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-777",
- "number": "777",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-777",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000777",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-778": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-778",
- "number": "778",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-778",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000778",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-779": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-779",
- "number": "779",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-779",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000779",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-780": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-780",
- "number": "780",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-780",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000780",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-781": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-781",
- "number": "781",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-781",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000781",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-782": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-782",
- "number": "782",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-782",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000782",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-783": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-783",
- "number": "783",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-783",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000783",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-784": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-784",
- "number": "784",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-784",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000784",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-785": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-785",
- "number": "785",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-785",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000785",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-786": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-786",
- "number": "786",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-786",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000786",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-787": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-787",
- "number": "787",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-787",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000787",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-788": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-788",
- "number": "788",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-788",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000788",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-789": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-789",
- "number": "789",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-789",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000789",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-790": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-790",
- "number": "790",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-790",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000790",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-791": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-791",
- "number": "791",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-791",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000791",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-792": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-792",
- "number": "792",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-792",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000792",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-793": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-793",
- "number": "793",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-793",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000793",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-794": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-794",
- "number": "794",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-794",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000794",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-795": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-795",
- "number": "795",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-795",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000795",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-796": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-796",
- "number": "796",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-796",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000796",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-797": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-797",
- "number": "797",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-797",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000797",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-798": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-798",
- "number": "798",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-798",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000798",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-799": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-799",
- "number": "799",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-799",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000799",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-800": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-800",
- "number": "800",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-800",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000800",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-801": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-801",
- "number": "801",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-801",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000801",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-802": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-802",
- "number": "802",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-802",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000802",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-803": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-803",
- "number": "803",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-803",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000803",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-804": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-804",
- "number": "804",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-804",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000804",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-805": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-805",
- "number": "805",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-805",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000805",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-806": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-806",
- "number": "806",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-806",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000806",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-807": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-807",
- "number": "807",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-807",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000807",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-808": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-808",
- "number": "808",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-808",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000808",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-809": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-809",
- "number": "809",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-809",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000809",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-810": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-810",
- "number": "810",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-810",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000810",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-811": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-811",
- "number": "811",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-811",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000811",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-812": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-812",
- "number": "812",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-812",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000812",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-813": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-813",
- "number": "813",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-813",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000813",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-814": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-814",
- "number": "814",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-814",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000814",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-815": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-815",
- "number": "815",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-815",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000815",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-816": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-816",
- "number": "816",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-816",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000816",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-817": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-817",
- "number": "817",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-817",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000817",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-818": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-818",
- "number": "818",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-818",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000818",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-819": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-819",
- "number": "819",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-819",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000819",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-820": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-820",
- "number": "820",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-820",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000820",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-821": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-821",
- "number": "821",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-821",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000821",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-822": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-822",
- "number": "822",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-822",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000822",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-823": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-823",
- "number": "823",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-823",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000823",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-824": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-824",
- "number": "824",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-824",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000824",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-825": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-825",
- "number": "825",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-825",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000825",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-826": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-826",
- "number": "826",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-826",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000826",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-827": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-827",
- "number": "827",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-827",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000827",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-828": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-828",
- "number": "828",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-828",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000828",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-829": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-829",
- "number": "829",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-829",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000829",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-830": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-830",
- "number": "830",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-830",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000830",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-831": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-831",
- "number": "831",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-831",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000831",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-832": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-832",
- "number": "832",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-832",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000832",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-833": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-833",
- "number": "833",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-833",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000833",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-834": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-834",
- "number": "834",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-834",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000834",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-835": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-835",
- "number": "835",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-835",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000835",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-836": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-836",
- "number": "836",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-836",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000836",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-837": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-837",
- "number": "837",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-837",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000837",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-838": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-838",
- "number": "838",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-838",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000838",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-839": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-839",
- "number": "839",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-839",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000839",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-840": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-840",
- "number": "840",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-840",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000840",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-841": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-841",
- "number": "841",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-841",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000841",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-842": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-842",
- "number": "842",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-842",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000842",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-843": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-843",
- "number": "843",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-843",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000843",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-844": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-844",
- "number": "844",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-844",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000844",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-845": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-845",
- "number": "845",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-845",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000845",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-846": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-846",
- "number": "846",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-846",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000846",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-847": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-847",
- "number": "847",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-847",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000847",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-848": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-848",
- "number": "848",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-848",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000848",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-849": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-849",
- "number": "849",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-849",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000849",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-850": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-850",
- "number": "850",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-850",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000850",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-851": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-851",
- "number": "851",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-851",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000851",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-852": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-852",
- "number": "852",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-852",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000852",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-853": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-853",
- "number": "853",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-853",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000853",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-854": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-854",
- "number": "854",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-854",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000854",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-855": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-855",
- "number": "855",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-855",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000855",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-856": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-856",
- "number": "856",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-856",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000856",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-857": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-857",
- "number": "857",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-857",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000857",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-858": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-858",
- "number": "858",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-858",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000858",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-859": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-859",
- "number": "859",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-859",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000859",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-860": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-860",
- "number": "860",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-860",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000860",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-861": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-861",
- "number": "861",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-861",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000861",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-862": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-862",
- "number": "862",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-862",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000862",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-863": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-863",
- "number": "863",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-863",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000863",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-864": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-864",
- "number": "864",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-864",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000864",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-865": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-865",
- "number": "865",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-865",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000865",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-866": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-866",
- "number": "866",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-866",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000866",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-867": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-867",
- "number": "867",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-867",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000867",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-868": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-868",
- "number": "868",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-868",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000868",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-869": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-869",
- "number": "869",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-869",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000869",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-870": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-870",
- "number": "870",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-870",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000870",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-871": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-871",
- "number": "871",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-871",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000871",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-872": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-872",
- "number": "872",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-872",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000872",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-873": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-873",
- "number": "873",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-873",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000873",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-874": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-874",
- "number": "874",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-874",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000874",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-875": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-875",
- "number": "875",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-875",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000875",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-876": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-876",
- "number": "876",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-876",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000876",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-877": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-877",
- "number": "877",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-877",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000877",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-878": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-878",
- "number": "878",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-878",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000878",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-879": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-879",
- "number": "879",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-879",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000879",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-880": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-880",
- "number": "880",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-880",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000880",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-881": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-881",
- "number": "881",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-881",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000881",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-882": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-882",
- "number": "882",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-882",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000882",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-883": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-883",
- "number": "883",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-883",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000883",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-884": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-884",
- "number": "884",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-884",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000884",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-885": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-885",
- "number": "885",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-885",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000885",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-886": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-886",
- "number": "886",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-886",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000886",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-887": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-887",
- "number": "887",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-887",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000887",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-888": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-888",
- "number": "888",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-888",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000888",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-889": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-889",
- "number": "889",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-889",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000889",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-890": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-890",
- "number": "890",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-890",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000890",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-891": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-891",
- "number": "891",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-891",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000891",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-892": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-892",
- "number": "892",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-892",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000892",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-893": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-893",
- "number": "893",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-893",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000893",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-894": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-894",
- "number": "894",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-894",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000894",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-895": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-895",
- "number": "895",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-895",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000895",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-896": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-896",
- "number": "896",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-896",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000896",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-897": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-897",
- "number": "897",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-897",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000897",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-898": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-898",
- "number": "898",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-898",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000898",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-899": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-899",
- "number": "899",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-899",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000899",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-900": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-900",
- "number": "900",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-900",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000900",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-901": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-901",
- "number": "901",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-901",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000901",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-902": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-902",
- "number": "902",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-902",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000902",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-903": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-903",
- "number": "903",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-903",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000903",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-904": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-904",
- "number": "904",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-904",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000904",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-905": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-905",
- "number": "905",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-905",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000905",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-906": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-906",
- "number": "906",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-906",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000906",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-907": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-907",
- "number": "907",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-907",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000907",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-908": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-908",
- "number": "908",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-908",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000908",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-909": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-909",
- "number": "909",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-909",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000909",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-910": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-910",
- "number": "910",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-910",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000910",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-911": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-911",
- "number": "911",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-911",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000911",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-912": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-912",
- "number": "912",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-912",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000912",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-913": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-913",
- "number": "913",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-913",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000913",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-914": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-914",
- "number": "914",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-914",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000914",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-915": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-915",
- "number": "915",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-915",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000915",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-916": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-916",
- "number": "916",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-916",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000916",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-917": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-917",
- "number": "917",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-917",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000917",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-918": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-918",
- "number": "918",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-918",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000918",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-919": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-919",
- "number": "919",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-919",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000919",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-920": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-920",
- "number": "920",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-920",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000920",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-921": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-921",
- "number": "921",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-921",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000921",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-922": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-922",
- "number": "922",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-922",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000922",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-923": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-923",
- "number": "923",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-923",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000923",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-924": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-924",
- "number": "924",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-924",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000924",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-925": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-925",
- "number": "925",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-925",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000925",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-926": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-926",
- "number": "926",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-926",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000926",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-927": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-927",
- "number": "927",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-927",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000927",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-928": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-928",
- "number": "928",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-928",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000928",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-929": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-929",
- "number": "929",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-929",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000929",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-930": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-930",
- "number": "930",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-930",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000930",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-931": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-931",
- "number": "931",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-931",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000931",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-932": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-932",
- "number": "932",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-932",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000932",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-933": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-933",
- "number": "933",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-933",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000933",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-934": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-934",
- "number": "934",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-934",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000934",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-935": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-935",
- "number": "935",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-935",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000935",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-936": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-936",
- "number": "936",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-936",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000936",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-937": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-937",
- "number": "937",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-937",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000937",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-938": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-938",
- "number": "938",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-938",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000938",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-939": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-939",
- "number": "939",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-939",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000939",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-940": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-940",
- "number": "940",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-940",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000940",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-941": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-941",
- "number": "941",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-941",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000941",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-942": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-942",
- "number": "942",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-942",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000942",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-943": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-943",
- "number": "943",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-943",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000943",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-944": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-944",
- "number": "944",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-944",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000944",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-945": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-945",
- "number": "945",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-945",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000945",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-946": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-946",
- "number": "946",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-946",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000946",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-947": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-947",
- "number": "947",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-947",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000947",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-948": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-948",
- "number": "948",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-948",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000948",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-949": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-949",
- "number": "949",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-949",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000949",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-950": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-950",
- "number": "950",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-950",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000950",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-951": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-951",
- "number": "951",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-951",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000951",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-952": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-952",
- "number": "952",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-952",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000952",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-953": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-953",
- "number": "953",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-953",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000953",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-954": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-954",
- "number": "954",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-954",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000954",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-955": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-955",
- "number": "955",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-955",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000955",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-956": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-956",
- "number": "956",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-956",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000956",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-957": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-957",
- "number": "957",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-957",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000957",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-958": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-958",
- "number": "958",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-958",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000958",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-959": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-959",
- "number": "959",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-959",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000959",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-960": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-960",
- "number": "960",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-960",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000960",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-961": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-961",
- "number": "961",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-961",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000961",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-962": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-962",
- "number": "962",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-962",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000962",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-963": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-963",
- "number": "963",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-963",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000963",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-964": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-964",
- "number": "964",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-964",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000964",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-965": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-965",
- "number": "965",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-965",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000965",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-966": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-966",
- "number": "966",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-966",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000966",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-967": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-967",
- "number": "967",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-967",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000967",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-968": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-968",
- "number": "968",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-968",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000968",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-969": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-969",
- "number": "969",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-969",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000969",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-970": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-970",
- "number": "970",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-970",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000970",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-971": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-971",
- "number": "971",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-971",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000971",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-972": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-972",
- "number": "972",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-972",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000972",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-973": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-973",
- "number": "973",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-973",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000973",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-974": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-974",
- "number": "974",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-974",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000974",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-975": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-975",
- "number": "975",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-975",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000975",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-976": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-976",
- "number": "976",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-976",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000976",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-977": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-977",
- "number": "977",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-977",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000977",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-978": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-978",
- "number": "978",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-978",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000978",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-979": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-979",
- "number": "979",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-979",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000979",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-980": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-980",
- "number": "980",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-980",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000980",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-981": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-981",
- "number": "981",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-981",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000981",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-982": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-982",
- "number": "982",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-982",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000982",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-983": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-983",
- "number": "983",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-983",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000983",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-984": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-984",
- "number": "984",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-984",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000984",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-985": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-985",
- "number": "985",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-985",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000985",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-986": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-986",
- "number": "986",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-986",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000986",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-987": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-987",
- "number": "987",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-987",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000987",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-988": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-988",
- "number": "988",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-988",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000988",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-989": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-989",
- "number": "989",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-989",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000989",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-990": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-990",
- "number": "990",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-990",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000990",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-991": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-991",
- "number": "991",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-991",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000991",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-992": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-992",
- "number": "992",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-992",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000992",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-993": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-993",
- "number": "993",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-993",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000993",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-994": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-994",
- "number": "994",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-994",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000994",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-995": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-995",
- "number": "995",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-995",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000995",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-996": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-996",
- "number": "996",
- "tag": "silly",
- "type": "even",
- "factor3": "yes"
- },
- "name": "mock-996",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000996",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-997": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-997",
- "number": "997",
- "tag": "silly",
- "type": "odd",
- "factor3": "no"
- },
- "name": "mock-997",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000997",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-998": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-998",
- "number": "998",
- "tag": "silly",
- "type": "even",
- "factor3": "no"
- },
- "name": "mock-998",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000998",
- "namespace": "default"
- }
- },
- "namespaces/default/pods/mock-999": {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-999",
- "number": "999",
- "tag": "silly",
- "type": "odd",
- "factor3": "yes"
- },
- "name": "mock-999",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100000999",
- "namespace": "default"
- }
- },
- "namespaces/default/replicationcontrollers/oddcontroller": {
- "kind": "ReplicationController",
- "metadata": {
- "labels": {
- "example": "mock",
- "name": "oddcontroller"
- },
- "name": "oddcontroller",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100001000",
- "namespace": "default"
- },
- "spec": {
- "replicas": 1,
- "selector": {
- "tag": "silly",
- "type": "odd"
- }
- }
- },
- "namespaces/default/replicationcontrollers/3controller": {
- "kind": "ReplicationController",
- "metadata": {
- "labels": {
- "example": "mock",
- "name": "3controller"
- },
- "name": "3controller",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100001001",
- "namespace": "default"
- },
- "spec": {
- "replicas": 1,
- "selector": {
- "factor3": "yes"
- }
- }
- }
-};
diff --git a/pkg/kubernetes/scripts/frob-fixture.js b/pkg/kubernetes/scripts/frob-fixture.js
deleted file mode 100755
index f5cf12dc5..000000000
--- a/pkg/kubernetes/scripts/frob-fixture.js
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/env node
-
-/*
- * This is used to generate data sets like the one in mock-large.js
- * Use it like so:
- *
- * $ ./frob-mock.js > ./mock-large.js
- */
-
-var last = 99999999;
-function uid() {
- last += 1;
- return "11768037-ab8a-11e4-9a7c-" + last;
-}
-
-var pod_template = {
- "kind": "Pod",
- "metadata": {
- "labels": {
- "name": "mock-",
- "number": "",
- "tag": "silly"
- }
- }
-};
-
-var objects = {};
-
-var pod, i;
-for (i = 0; i < 1000; i++) {
- pod = JSON.parse(JSON.stringify(pod_template));
- pod.metadata.name += i;
- pod.metadata.resourceVersion += i;
- pod.metadata.labels.name += i;
- pod.metadata.labels.number += i;
- pod.metadata.labels.type = ["even", "odd"][i % 2];
- pod.metadata.labels.factor3 = ["yes", "no", "no"][i % 3];
-
- objects["namespaces/default/pods/mock-" + i] = pod;
-}
-
-var repl_template = {
- "kind": "ReplicationController",
- "metadata": {
- "labels": {
- "example": "mock"
- }
- },
- "spec": {
- "replicas": 1,
- "selector": { },
- }
-};
-
-var repl = JSON.parse(JSON.stringify(repl_template));
-repl.metadata.name = "oddcontroller";
-repl.spec.selector = { "tag": "silly", "type": "odd" };
-objects["namespaces/default/replicationcontrollers/oddcontroller"] = repl;
-
-repl = JSON.parse(JSON.stringify(repl_template));
-repl.metadata.name = "3controller";
-repl.spec.selector = { "factor3": "yes" };
-objects["namespaces/default/replicationcontrollers/3controller"] = repl;
-
-var path, parts;
-for (path in objects) {
- parts = path.split("/");
- objects[path].metadata.resourceVersion = 10000;
- objects[path].metadata.uid = uid();
- objects[path].metadata.namespace = parts[1];
- objects[path].metadata.name = parts.reverse()[0];
- objects[path].metadata.labels.name = objects[path].metadata.name;
-}
-
-var data = JSON.stringify(objects, null, 4);
-process.stdout.write("define(" + data + ");\n");
diff --git a/pkg/kubernetes/scripts/frob-layers-v1compatibility.jsonp b/pkg/kubernetes/scripts/frob-layers-v1compatibility.jsonp
deleted file mode 100644
index bc0c40221..000000000
--- a/pkg/kubernetes/scripts/frob-layers-v1compatibility.jsonp
+++ /dev/null
@@ -1,1181 +0,0 @@
-sink([
- {
- "v1Compatibility": {
- "id": "89e18bec96a4ca40a5152842d99c4781a190516182579deeadf13f20f44ecea6",
- "parent": "6a2b1b2520571bdb32fb52dd9ce9e3a24838f9fb8025aa974bdd2d6b340d0669",
- "created": "2016-03-02T13:49:23.199169725Z",
- "container": "1f489ce72478945e5f71171d7153612b3472f994ab6f7f1f1bc8d6569799be63",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) LABEL version=1.0"
- ],
- "Image": "6a2b1b2520571bdb32fb52dd9ce9e3a24838f9fb8025aa974bdd2d6b340d0669",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [
- "ADD . /app/src"
- ],
- "Labels": {
- "Test": "Value",
- "version": "1.0"
- },
- "StopSignal": "SIGKILL"
- },
- "docker_version": "1.9.1",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "-c"
- ],
- "Image": "6a2b1b2520571bdb32fb52dd9ce9e3a24838f9fb8025aa974bdd2d6b340d0669",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [
- "ADD . /app/src"
- ],
- "Labels": {
- "Test": "Value",
- "version": "1.0"
- },
- "StopSignal": "SIGKILL"
- },
- "architecture": "amd64",
- "os": "linux"
- }
- },
- {
- "v1Compatibility": {
- "id": "6a2b1b2520571bdb32fb52dd9ce9e3a24838f9fb8025aa974bdd2d6b340d0669",
- "parent": "bbca6d51c41a46b40e63abc9f64ee4cddcaf989a5e9a0fbeaa1ee80f24f11149",
- "created": "2016-03-02T13:49:17.622735453Z",
- "container": "fc89ccedb7e2bd02ac22c6b2f814330ca29fe7467290cc55a8fc95ec610b9d09",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) LABEL Test=Value"
- ],
- "Image": "bbca6d51c41a46b40e63abc9f64ee4cddcaf989a5e9a0fbeaa1ee80f24f11149",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [
- "ADD . /app/src"
- ],
- "Labels": {
- "Test": "Value"
- },
- "StopSignal": "SIGKILL"
- },
- "docker_version": "1.9.1",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "-c"
- ],
- "Image": "bbca6d51c41a46b40e63abc9f64ee4cddcaf989a5e9a0fbeaa1ee80f24f11149",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [
- "ADD . /app/src"
- ],
- "Labels": {
- "Test": "Value"
- },
- "StopSignal": "SIGKILL"
- },
- "architecture": "amd64",
- "os": "linux"
- }
- },
- {
- "v1Compatibility": {
- "id": "bbca6d51c41a46b40e63abc9f64ee4cddcaf989a5e9a0fbeaa1ee80f24f11149",
- "parent": "d2a5b8c97b05b03c3e02cae4cd0732229840f9fd55b15edfa2a2a3831f92e455",
- "created": "2016-03-02T13:49:12.537373555Z",
- "container": "a0e4a63ee751bf5883b2b40d96543a48fe6af18ac5061d3cb2be6884505d451b",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) ARG simple"
- ],
- "Image": "d2a5b8c97b05b03c3e02cae4cd0732229840f9fd55b15edfa2a2a3831f92e455",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [
- "ADD . /app/src"
- ],
- "Labels": {},
- "StopSignal": "SIGKILL"
- },
- "docker_version": "1.9.1",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "-c"
- ],
- "Image": "d2a5b8c97b05b03c3e02cae4cd0732229840f9fd55b15edfa2a2a3831f92e455",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [
- "ADD . /app/src"
- ],
- "Labels": {},
- "StopSignal": "SIGKILL"
- },
- "architecture": "amd64",
- "os": "linux"
- }
- },
- {
- "v1Compatibility": {
- "id": "d2a5b8c97b05b03c3e02cae4cd0732229840f9fd55b15edfa2a2a3831f92e455",
- "parent": "8533fc673cc91593f95373049cbe53d5f517a90c34377a3c4e746a3be6d028af",
- "created": "2016-03-02T13:49:07.17643214Z",
- "container": "80cb2cba4ad6dd3b66b0aafaf3d49a2f57720bc4ea67956fee9bf3bb44e2227a",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) ARG hello=test"
- ],
- "Image": "8533fc673cc91593f95373049cbe53d5f517a90c34377a3c4e746a3be6d028af",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [
- "ADD . /app/src"
- ],
- "Labels": {},
- "StopSignal": "SIGKILL"
- },
- "docker_version": "1.9.1",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "-c"
- ],
- "Image": "8533fc673cc91593f95373049cbe53d5f517a90c34377a3c4e746a3be6d028af",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [
- "ADD . /app/src"
- ],
- "Labels": {},
- "StopSignal": "SIGKILL"
- },
- "architecture": "amd64",
- "os": "linux"
- }
- },
- {
- "v1Compatibility": {
- "id": "8533fc673cc91593f95373049cbe53d5f517a90c34377a3c4e746a3be6d028af",
- "parent": "ee546cdf7ed55e9055722350db6fe2d1364e2aba690f84c9fe5300ece1b539d7",
- "created": "2016-03-02T13:49:01.993873286Z",
- "container": "07837b3e4624fc3f3fd6c093880f313dd6eff7f97c48e66c879bebf70b087d26",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) ONBUILD ADD . /app/src"
- ],
- "Image": "ee546cdf7ed55e9055722350db6fe2d1364e2aba690f84c9fe5300ece1b539d7",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [
- "ADD . /app/src"
- ],
- "Labels": {},
- "StopSignal": "SIGKILL"
- },
- "docker_version": "1.9.1",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "-c"
- ],
- "Image": "ee546cdf7ed55e9055722350db6fe2d1364e2aba690f84c9fe5300ece1b539d7",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [
- "ADD . /app/src"
- ],
- "Labels": {},
- "StopSignal": "SIGKILL"
- },
- "architecture": "amd64",
- "os": "linux"
- }
- },
- {
- "v1Compatibility": {
- "id": "ee546cdf7ed55e9055722350db6fe2d1364e2aba690f84c9fe5300ece1b539d7",
- "parent": "e2368fd48286bb997dac8c9681de714e76a825dc87fc2a6854baaed8e748b9de",
- "created": "2016-03-02T13:48:55.221100229Z",
- "container": "94a628e0153d7c579bec9c54fab7ed6296b90ee3f58d541209043628dda81a41",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) STOPSIGNAL [SIGKILL]"
- ],
- "Image": "e2368fd48286bb997dac8c9681de714e76a825dc87fc2a6854baaed8e748b9de",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [],
- "Labels": {},
- "StopSignal": "SIGKILL"
- },
- "docker_version": "1.9.1",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "-c"
- ],
- "Image": "e2368fd48286bb997dac8c9681de714e76a825dc87fc2a6854baaed8e748b9de",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [],
- "Labels": {},
- "StopSignal": "SIGKILL"
- },
- "architecture": "amd64",
- "os": "linux"
- }
- },
- {
- "v1Compatibility": {
- "id": "e2368fd48286bb997dac8c9681de714e76a825dc87fc2a6854baaed8e748b9de",
- "parent": "9541b952349ea6116d1ea82736f4407572257bc2080fe0a85656a13b5e8fed82",
- "created": "2016-03-02T13:48:48.18265793Z",
- "container": "298e297b12b4953029fc24de7fc21a493f30a6c34dfaa00a6b697672d358691a",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) CMD [\"-c\"]"
- ],
- "Image": "9541b952349ea6116d1ea82736f4407572257bc2080fe0a85656a13b5e8fed82",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [],
- "Labels": {}
- },
- "docker_version": "1.9.1",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "-c"
- ],
- "Image": "9541b952349ea6116d1ea82736f4407572257bc2080fe0a85656a13b5e8fed82",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [],
- "Labels": {}
- },
- "architecture": "amd64",
- "os": "linux"
- }
- },
- {
- "v1Compatibility": {
- "id": "9541b952349ea6116d1ea82736f4407572257bc2080fe0a85656a13b5e8fed82",
- "parent": "7733d572fc28bc5dfdaef85b85990201a5a835d8b65b31c6f659f313bea70d33",
- "created": "2016-03-02T13:48:42.168991966Z",
- "container": "7d9ccd9a84e6631b66190b5f73ef6e5b3fb2442d2615e857302c2e478aba302b",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) ENTRYPOINT &{[\"top\" \"-b\"]}"
- ],
- "Image": "7733d572fc28bc5dfdaef85b85990201a5a835d8b65b31c6f659f313bea70d33",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [],
- "Labels": {}
- },
- "docker_version": "1.9.1",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": null,
- "Image": "7733d572fc28bc5dfdaef85b85990201a5a835d8b65b31c6f659f313bea70d33",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": [
- "top",
- "-b"
- ],
- "OnBuild": [],
- "Labels": {}
- },
- "architecture": "amd64",
- "os": "linux"
- }
- },
- {
- "v1Compatibility": {
- "id": "7733d572fc28bc5dfdaef85b85990201a5a835d8b65b31c6f659f313bea70d33",
- "parent": "daa3842818eba54c8f9896c4a73004cb758f17cf17340c02bae7a02713fb1141",
- "created": "2016-03-02T13:48:36.127887903Z",
- "container": "84d126716b35735750893946e3f2b3538a4fe90b1c2fcb6dac25ec3e8ba10d3e",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) USER [nobody:wheel]"
- ],
- "Image": "daa3842818eba54c8f9896c4a73004cb758f17cf17340c02bae7a02713fb1141",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": [],
- "Labels": {}
- },
- "docker_version": "1.9.1",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "nobody:wheel",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "\"/echo-script\""
- ],
- "Image": "daa3842818eba54c8f9896c4a73004cb758f17cf17340c02bae7a02713fb1141",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": [],
- "Labels": {}
- },
- "architecture": "amd64",
- "os": "linux"
- }
- },
- {
- "v1Compatibility": {
- "id": "daa3842818eba54c8f9896c4a73004cb758f17cf17340c02bae7a02713fb1141",
- "parent": "9d4f2e1ac750a13b0b40c058ff1f43c408d2b3981a69709cb1d122916ffd0c52",
- "created": "2016-03-02T13:48:27.418271646Z",
- "container": "4f41201cb36cf14e8b786613487dd32db63023cacaf32d48be699b56c1b30403",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) ADD file:7a0204a785c5c99c2e0a34e186257e7e1a06b46a6467172d42f2a8b6faaec266 in /usr/bin"
- ],
- "Image": "9d4f2e1ac750a13b0b40c058ff1f43c408d2b3981a69709cb1d122916ffd0c52",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": [],
- "Labels": {}
- },
- "docker_version": "1.9.1",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "\"/echo-script\""
- ],
- "Image": "9d4f2e1ac750a13b0b40c058ff1f43c408d2b3981a69709cb1d122916ffd0c52",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": [],
- "Labels": {}
- },
- "architecture": "amd64",
- "os": "linux",
- "Size": 124985485
- }
- },
- {
- "v1Compatibility": {
- "id": "9d4f2e1ac750a13b0b40c058ff1f43c408d2b3981a69709cb1d122916ffd0c52",
- "parent": "f2fac80fdf50b0738e434a0a5b04677bcf39f3afb4c892b683035b1cc6810945",
- "created": "2016-03-02T13:48:00.528642138Z",
- "container": "7093d7c71526d6441bacd87becc23b258f9747c1121e4743ada00b5a3b16a974",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) CMD [\"/bin/sh\" \"-c\" \"\\\"/echo-script\\\"\"]"
- ],
- "Image": "f2fac80fdf50b0738e434a0a5b04677bcf39f3afb4c892b683035b1cc6810945",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": [],
- "Labels": {}
- },
- "docker_version": "1.9.1",
- "author": "cockpit@example.com",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "\"/echo-script\""
- ],
- "Image": "f2fac80fdf50b0738e434a0a5b04677bcf39f3afb4c892b683035b1cc6810945",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": [],
- "Labels": {}
- },
- "architecture": "amd64",
- "os": "linux"
- }
- },
- {
- "v1Compatibility": {
- "id": "f2fac80fdf50b0738e434a0a5b04677bcf39f3afb4c892b683035b1cc6810945",
- "parent": "0b7194f278c0677c43cdc273985ac5534c30f1534e15457e328da8ded4cedd95",
- "created": "2016-03-02T13:47:53.685835007Z",
- "container": "9459e4feec9d3516c9ca21a6040bac1e9d62ae54dfeda031620ead552146c377",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "chmod +x /echo-script"
- ],
- "Image": "0b7194f278c0677c43cdc273985ac5534c30f1534e15457e328da8ded4cedd95",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": [],
- "Labels": {}
- },
- "docker_version": "1.9.1",
- "author": "cockpit@example.com",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "sh"
- ],
- "Image": "0b7194f278c0677c43cdc273985ac5534c30f1534e15457e328da8ded4cedd95",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": [],
- "Labels": {}
- },
- "architecture": "amd64",
- "os": "linux",
- "Size": 49
- }
- },
- {
- "v1Compatibility": {
- "id": "0b7194f278c0677c43cdc273985ac5534c30f1534e15457e328da8ded4cedd95",
- "parent": "0a85b5651d9d66663bde6e24c8322dd06394dcd2f14a590a71f5264b5bae68c9",
- "created": "2016-03-02T13:47:46.440413292Z",
- "container": "ff2c25f93e7b586ac29757d37bd8324dfc449de16270df6efe69276a8173a064",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) ADD file:b35fc316562d0e29fa7ae1e767f3597811f4349e30aa74122b67965a103f817a in /"
- ],
- "Image": "0a85b5651d9d66663bde6e24c8322dd06394dcd2f14a590a71f5264b5bae68c9",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": [],
- "Labels": {}
- },
- "docker_version": "1.9.1",
- "author": "cockpit@example.com",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "sh"
- ],
- "Image": "0a85b5651d9d66663bde6e24c8322dd06394dcd2f14a590a71f5264b5bae68c9",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": [],
- "Labels": {}
- },
- "architecture": "amd64",
- "os": "linux",
- "Size": 49
- }
- },
- {
- "v1Compatibility": {
- "id": "0a85b5651d9d66663bde6e24c8322dd06394dcd2f14a590a71f5264b5bae68c9",
- "parent": "5a82ed0a2cc4a5a9f8ce2656d8d7c5254592baac28d1701b0153416759fbabf9",
- "created": "2016-03-02T13:47:40.786531005Z",
- "container": "9b31ac4ceb47e917187332bbdf26407d99de10e095941a3a2caba95a7d433850",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) EXPOSE 8888/tcp"
- ],
- "Image": "5a82ed0a2cc4a5a9f8ce2656d8d7c5254592baac28d1701b0153416759fbabf9",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": [],
- "Labels": {}
- },
- "docker_version": "1.9.1",
- "author": "cockpit@example.com",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "ExposedPorts": {
- "8888/tcp": {}
- },
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "sh"
- ],
- "Image": "5a82ed0a2cc4a5a9f8ce2656d8d7c5254592baac28d1701b0153416759fbabf9",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": [],
- "Labels": {}
- },
- "architecture": "amd64",
- "os": "linux"
- }
- },
- {
- "v1Compatibility": {
- "id": "5a82ed0a2cc4a5a9f8ce2656d8d7c5254592baac28d1701b0153416759fbabf9",
- "parent": "fef924a0204a00b3ec67318e2ed337b189c99ea19e2bf10ed30a13b87c5e17ab",
- "created": "2016-03-02T13:47:34.535472081Z",
- "container": "01e40050638e9621b63c9f2da83f6b2778c4bdc9ef0c592649d819beeff43633",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) MAINTAINER cockpit@example.com"
- ],
- "Image": "65e4158d96256e032299e07ac28308d644c0e81d52b18dcb08847a5027b4f107",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": [],
- "Labels": {}
- },
- "docker_version": "1.9.1",
- "author": "cockpit@example.com",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": [
- "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- ],
- "Cmd": [
- "sh"
- ],
- "Image": "65e4158d96256e032299e07ac28308d644c0e81d52b18dcb08847a5027b4f107",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": [],
- "Labels": {}
- },
- "architecture": "amd64",
- "os": "linux"
- }
- },
- {
- "v1Compatibility": {
- "id": "fef924a0204a00b3ec67318e2ed337b189c99ea19e2bf10ed30a13b87c5e17ab",
- "parent": "9a163e0b8d138ec700b5a5f7e62509012f7eb34b9f86cd3bbeb3d183958114a9",
- "created": "2016-02-16T22:59:37.407805421Z",
- "container": "d23509cd0189de02bef382544ebfab515f29094f3c0e2f161fa7ce09afa8974e",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": null,
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) CMD [\"sh\"]"
- ],
- "Image": "9a163e0b8d138ec700b5a5f7e62509012f7eb34b9f86cd3bbeb3d183958114a9",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": null,
- "Labels": {}
- },
- "docker_version": "1.9.1",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": null,
- "Cmd": [
- "sh"
- ],
- "Image": "9a163e0b8d138ec700b5a5f7e62509012f7eb34b9f86cd3bbeb3d183958114a9",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": null,
- "Labels": {}
- },
- "architecture": "amd64",
- "os": "linux"
- }
- },
- {
- "v1Compatibility": {
- "id": "9a163e0b8d138ec700b5a5f7e62509012f7eb34b9f86cd3bbeb3d183958114a9",
- "created": "2016-02-16T22:59:36.792440427Z",
- "container": "13709f13afe11b7d4a007d2866afd20c5b783f0a89f4e6792a28102a4c12c473",
- "container_config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": null,
- "Cmd": [
- "/bin/sh",
- "-c",
- "#(nop) ADD file:7cdf7a89f6a004b2e9501317bd72bd863d93a51255d8f83b2ed3058d385a4938 in /"
- ],
- "Image": "",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": null,
- "Labels": null
- },
- "docker_version": "1.9.1",
- "config": {
- "Hostname": "13709f13afe1",
- "Domainname": "",
- "User": "",
- "AttachStdin": false,
- "AttachStdout": false,
- "AttachStderr": false,
- "Tty": false,
- "OpenStdin": false,
- "StdinOnce": false,
- "Env": null,
- "Cmd": null,
- "Image": "",
- "Volumes": null,
- "WorkingDir": "",
- "Entrypoint": null,
- "OnBuild": null,
- "Labels": null
- },
- "architecture": "amd64",
- "os": "linux",
- "Size": 1113554
- }
- }
-]);
diff --git a/pkg/kubernetes/scripts/graphs.js b/pkg/kubernetes/scripts/graphs.js
deleted file mode 100644
index 30276f12b..000000000
--- a/pkg/kubernetes/scripts/graphs.js
+++ /dev/null
@@ -1,863 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
- var d3 = require('d3');
-
- require('./kube-client');
- require('./kube-client-cockpit');
- require('./utils');
-
- angular.module('kubernetes.graph', [
- 'kubeClient',
- 'kubeClient.cockpit',
- 'kubeUtils',
- ])
-
- .factory('CAdvisorSeries', [
- "KubeRequest",
- "CockpitMetrics",
- "$exceptionHandler",
- "$timeout",
- function (KubeRequest, CockpitMetrics, $exceptionHandler, $timeout) {
- function CAdvisor(node) {
- var self = this;
-
- /* called when containers changed */
- var callbacks = [];
-
- /* cAdvisor has 10 second intervals */
- var interval = 10000;
-
- var last = { };
-
- var requests = { };
-
- /* Holds the container specs */
- self.specs = { };
-
- function feed(containers) {
- var x, y, ylen, i, len;
- var item, offset, timestamp, container, stat;
-
- /*
- * The cAdvisor data doesn't seem to have inherent guarantees of
- * continuity or regularity. In theory each stats object can have
- * it's own arbitrary timestamp ... although in practice they do
- * generally follow the interval to within a few milliseconds.
- *
- * So we first look for the lowest timestamp, treat that as our
- * base index, and then batch the data based on that.
- */
-
- var first = null;
-
- for (x in containers) {
- container = containers[x];
- if (container.stats) {
- len = container.stats.length;
- for (i = 0; i < len; i++) {
- timestamp = container.stats[i].timestamp;
- if (timestamp) {
- if (first === null || timestamp < first)
- first = timestamp;
- }
- }
- }
- }
-
- if (first === null)
- return;
-
- var base = Math.floor(new Date(first).getTime() / interval);
-
- var items = [];
- var name;
- var mapping = { };
- var new_ids = [];
- var id;
- var names = { };
-
- for (x in containers) {
- container = containers[x];
-
- /*
- * This builds the correct type of object graph for the
- * paths seen in grid.add() to operate on
- */
- name = container.name;
- if (!name)
- continue;
-
- names[name] = name;
- mapping[name] = { "": name };
- id = name;
-
- if (container.aliases) {
- ylen = container.aliases.length;
- for (y = 0; y < ylen; y++) {
- mapping[container.aliases[y]] = { "": name };
-
- /* Try to use the real docker container id as our id */
- if (container.aliases[y].length === 64)
- id = container.aliases[y];
- }
- }
-
- if (id && container.spec) {
- if (!self.specs[id]) {
- self.specs[id] = container.spec;
- new_ids.push(id);
- }
- }
-
- if (container.stats) {
- len = container.stats.length;
- for (i = 0; i < len; i++) {
- stat = container.stats[i];
- if (!stat.timestamp)
- continue;
-
- /* Convert the timestamp into an index */
- offset = Math.floor(new Date(stat.timestamp).getTime() / interval);
-
- item = items[offset - base];
- if (!item)
- item = items[offset - base] = { };
- item[name] = stat;
- }
- }
- }
-
- if (new_ids.length > 0)
- invokeCallbacks(new_ids);
-
- /* Make sure each offset has something */
- len = items.length;
- for (i = 0; i < len; i++) {
- if (items[i] === undefined)
- items[i] = { };
- }
-
- /* Now for each offset, if it's a duplicate, put in a copy */
- for (name in names) {
- len = items.length;
- for (i = 0; i < len; i++) {
- if (items[i][name] === undefined)
- items[i][name] = last[name];
- else
- last[name] = items[i][name];
- }
- }
-
- self.series.input(base, items, mapping);
- }
-
- function request(query) {
- var body = JSON.stringify(query);
-
- /* Only one request active at a time for any given body */
- if (body in requests)
- return;
-
- var path = "/api/v1/proxy/nodes/" + encodeURIComponent(node) + ":4194/api/v1.2/docker";
- var req = KubeRequest("POST", path, query);
-
- requests[body] = req;
- req.then(function(data) {
- delete requests[body];
- feed(data.data);
- })
- .catch(function(ex) {
- delete requests[body];
- if (ex.status != 503)
- console.warn(ex);
- });
- }
-
- function invokeCallbacks(/* ... */) {
- var i, len, func;
- for (i = 0, len = callbacks.length; i < len; i++) {
- func = callbacks[i];
- try {
- if (func)
- func.apply(self, arguments);
- } catch (e) {
- $exceptionHandler(e);
- }
- }
- }
-
- self.fetch = function fetch(beg, end) {
- var query;
- if (!beg || !end) {
- query = { num_stats: 60 };
- } else {
- query = {
- start: new Date((beg - 1) * interval).toISOString(),
- end: new Date(end * interval).toISOString()
- };
- }
- request(query);
- };
-
- self.close = function close() {
- var req, body;
- for (body in requests) {
- req = requests[body];
- if (req && req.cancel)
- req.cancel();
- }
- };
-
- self.watch = function watch(callback) {
- var ids;
- var timeout;
- callbacks.push(callback);
- if (self.specs) {
- ids = Object.keys(self.specs);
- if (ids.length > 0) {
- timeout = $timeout(function() {
- timeout = null;
- callback.call(self, ids);
- }, 0);
- }
- }
-
- return {
- cancel: function() {
- var i, len;
- $timeout.cancel(timeout);
- timeout = null;
- for (i = 0, len = callbacks.length; i < len; i++) {
- if (callbacks[i] === callback)
- callbacks[i] = null;
- }
- }
- };
- };
-
- var cache = "cadv1-" + (node || null);
- self.series = CockpitMetrics.series(interval, cache, self.fetch);
- }
-
- return {
- new_cadvisor: function(node) {
- return new CAdvisor(node);
- },
- };
- }
- ])
-
- .factory('ServiceGrid', [
- "CAdvisorSeries",
- "CockpitMetrics",
- "kubeSelect",
- "kubeLoader",
- function ServiceGrid(CAdvisorSeries, CockpitMetrics, select, loader) {
- function CockpitServiceGrid(until) {
- var self = CockpitMetrics.grid(10000, 0, 0);
-
- /* All the cadvisors that have been opened, one per host */
- var cadvisors = { };
-
- /* Service uids */
- var services = { };
-
- /* The various rows being shown, override */
- self.rows = [ ];
- self.events = [ ];
-
- var change_queued = false;
- var current_metric = null;
-
- var rows = {
- cpu: { },
- memory: { },
- network: { }
- };
-
- var container_cpu = { };
- var container_mem = { };
- var container_rx = { };
- var container_tx = { };
-
- /* Track Pods and Services */
- loader.listen(function() {
- var changed = false;
- var seen_services = {};
- var seen_hosts = {};
-
- /* Lookup all the services */
- angular.forEach(select().kind("Service"), function(service) {
- var spec = service.spec;
- var meta = service.metadata;
- var name = meta.name;
-
- if (!spec || !spec.selector || name === "kubernetes" || name === "kubernetes-ro")
- return;
-
- var uid = meta.uid;
- var pods = select().kind("Pod")
- .namespace(meta.namespace || "")
- .label(spec.selector || {});
-
- seen_services[uid] = true;
- if (!services[uid])
- add_service(uid);
-
- /* Lookup all the pods for each service */
- angular.forEach(pods, function(pod) {
- var status = pod.status || { };
- var spec = pod.spec || { };
- var host = spec.nodeName;
- var container_ids = {};
- var containers = status.containerStatuses || [];
- var i;
- var mapped = services[uid];
-
- seen_hosts[host] = true;
- if (host && !cadvisors[host]) {
- add_cadvisor(host);
- }
-
- /* Note all the containers for that pod */
- for (i = 0; i < containers.length; i++) {
- var container = containers[i];
- var id = container.containerID;
- if (id && id.indexOf("docker://") === 0) {
- container_ids[id] = id;
- id = id.substring(9);
- container_ids[id] = id;
- if (!mapped || !mapped[id])
- changed = true;
- }
- }
- services[uid] = container_ids;
- });
- });
-
- var k;
- for (k in services) {
- if (!seen_services[k]) {
- remove_service(k);
- changed = true;
- }
- }
-
- for (k in cadvisors) {
- if (!seen_hosts[k]) {
- remove_host(k);
- changed = true;
- }
- }
-
- /* Notify for all rows */
- if (changed)
- self.sync();
- }, until);
-
- loader.watch("Pod", until);
- loader.watch("Service", until);
-
- function add_container(cadvisor, id) {
- var cpu = self.add(cadvisor, [ id, "cpu", "usage", "total" ]);
- container_cpu[id] = self.add(function(row, x, n) {
- row_delta(cpu, row, x, n);
- }, true);
-
- container_mem[id] = self.add(cadvisor, [ id, "memory", "usage" ]);
-
- var rx = self.add(cadvisor, [ id, "network", "rx_bytes" ]);
- container_rx[id] = self.add(function(row, x, n) {
- row_delta(rx, row, x, n);
- }, true);
-
- var tx = self.add(cadvisor, [ id, "network", "tx_bytes" ]);
- container_tx[id] = self.add(function(row, x, n) {
- row_delta(tx, row, x, n);
- }, true);
-
- self.sync();
- }
-
- function add_cadvisor(host) {
- var cadvisor = CAdvisorSeries.new_cadvisor(host);
- cadvisor.watch(function (ids) {
- var i;
- for (i = 0; i < ids.length; i++)
- add_container(cadvisor, ids[i]);
- });
-
- /* A dummy row to force fetching data from the cadvisor */
- self.add(cadvisor, [ "unused-dummy" ]);
-
- /* TODO: Handle cadvisor failure somehow */
- cadvisors[host] = cadvisor;
- }
-
- function remove_host(host) {
- var cadvisor = cadvisors[host];
- if (cadvisor) {
- delete cadvisors[host];
- cadvisor.close();
- cadvisor = null;
- change_queued = true;
- }
- }
-
- function add_service(uid) {
- /* CPU needs summing of containers, and then delta between them */
- rows.cpu[uid] = self.add(function(row, x, n) {
- containers_sum(uid, container_cpu, row, x, n);
- });
-
- /* Memory row is pretty simple, just sum containers */
- rows.memory[uid] = self.add(function(row, x, n) {
- containers_sum(uid, container_mem, row, x, n);
- });
-
- /* Network sums containers, then sum tx and rx, and then delta */
- var tx = self.add(function(row, x, n) {
- containers_sum(uid, container_tx, row, x, n);
- });
- var rx = self.add(function(row, x, n) {
- containers_sum(uid, container_rx, row, x, n);
- });
- rows.network[uid] = self.add(function(row, x, n) {
- rows_sum([tx, rx], row, x, n);
- });
-
- change_queued = true;
- }
-
- function remove_service(uid) {
- delete services[uid];
- delete rows.network[uid];
- delete rows.cpu[uid];
- delete rows.memory[uid];
- change_queued = true;
- }
-
- function rows_sum(input, row, x, n) {
- var max = row.maximum || 0;
- var value, i, v, j;
- var len = input.length;
-
- /* Calculate the sum of the rows */
- for (i = 0; i < n; i++) {
- value = undefined;
- for (j = 0; j < len; j++) {
- v = input[j][x + i];
- if (v !== undefined) {
- if (value === undefined)
- value = v;
- else
- value += v;
- }
- }
-
- if (value !== undefined && value > max) {
- row.maximum = max = value;
- change_queued = true;
- }
-
- row[x + i] = value;
- }
- }
-
- function row_delta(input, row, x, n) {
- var i, last, res, value;
- if (x > 0)
- last = input[x - 1];
-
- var max = row.maximum || 1;
- for (i = 0; i < n; i++) {
- value = input[x + i];
- if (last === undefined || value === undefined) {
- res = undefined;
- } else {
- res = (value - last);
- if (res < 0) {
- res = undefined;
- } else if (res > max) {
- row.maximum = max = res;
- change_queued = true;
- }
- }
- row[x + i] = res;
- last = value;
- }
- }
-
- function containers_sum(service, input, row, x, n) {
- var id, rowc;
- var subset = [];
- var mapped = services[service];
- if (mapped) {
- for (id in mapped) {
- rowc = input[id];
- if (rowc)
- subset.push(rowc);
- }
- }
- rows_sum(subset, row, x, n);
- }
-
- self.metric = function metric(type) {
- if (type === undefined)
- return current_metric;
- if (rows[type] === undefined)
- throw Error("unsupported metric type");
-
- self.rows = [];
- current_metric = type;
-
- var service_uids = Object.keys(services);
- var row, i;
- var len = service_uids.length;
- for (i = 0; i < len; i++) {
- row = rows[type][service_uids[i]];
- if (row !== undefined) {
- self.rows.push(row);
- row.uid = service_uids[i];
- }
- }
-
- var event = new CustomEvent("changed", {
- bubbles: false,
- cancelable: false,
- detail: null
- });
- self.dispatchEvent(event, null);
- };
-
- var base_close = self.close;
- self.close = function close() {
- var hosts = Object.keys(cadvisors);
- var i;
- for (i = 0; i < hosts.length; i++) {
- var k = hosts[i];
- var cadvisor = cadvisors[k];
- if (cadvisor) {
- delete cadvisors[k];
- cadvisor.close();
- cadvisor = null;
- }
- }
- base_close.apply(self);
- };
-
- self.addEventListener("notify", function () {
- if (change_queued) {
- change_queued = false;
- self.metric(current_metric);
- }
- });
-
- return self;
- }
-
- return {
- new_grid: function (until) {
- return new CockpitServiceGrid(until);
- }
- };
- }
- ])
-
- .directive('kubernetesServiceGraph', [
- "ServiceGrid",
- "KubeTranslate",
- "KubeFormat",
- function kubernetesServiceGraph(ServiceGrid, KubeTranslate, KubeFormat) {
- const _ = KubeTranslate.gettext;
-
- function service_graph($scope, selector, highlighter) {
- var grid = ServiceGrid.new_grid($scope);
- var outer = d3.select(selector);
-
- var highlighted = null;
-
- /* Various tabs */
-
- var tabs = {
- cpu: {
- label: _("CPU"),
- step: 1000 * 1000 * 1000 * 10,
- formatter: function(v) { return (v / (100 * 1000 * 1000)) + "%" }
- },
- memory: {
- label: _("Memory"),
- step: 1024 * 1024 * 64,
- formatter: function(v) { return KubeFormat.formatBytes(v) }
- },
- network: {
- label: _("Network"),
- step: 1000 * 1000 * 10,
- formatter: function(v) { return KubeFormat.formatBitsPerSec((v / 10), "Mbps") }
- }
- };
-
- outer.append("ul")
- .attr("class", "nav nav-tabs")
- .selectAll("li")
- .data(Object.keys(tabs))
- .enter()
- .append("li")
- .attr("data-metric", function(d) { return d })
- .append("a")
- .text(function(d) { return tabs[d].label });
-
- function metric_tab(tab) {
- outer.selectAll("ul li")
- .attr("class", function(d) { return tab === d ? "active" : null });
- grid.metric(tab);
- }
-
- outer.selectAll("ul li")
- .on("click", function() {
- metric_tab(d3.select(this).attr("data-metric"));
- });
-
- metric_tab("cpu");
-
- /* The main svg graph stars here */
-
- var margins = {
- top: 12,
- right: 15,
- bottom: 40,
- left: 60
- };
-
- var colors = d3.scale.category20();
-
- var element = d3.select(selector).append("svg");
- var stage = element.append("g")
- .attr("transform", "translate(" + margins.left + "," + margins.top + ")");
-
- var y = d3.scale.linear();
- var y_axis = d3.svg.axis()
- .scale(y)
- .ticks(5)
- .orient("left");
- var y_group = stage.append("g")
- .attr("class", "y axis");
-
- var x = d3.scale.linear();
- var x_axis = d3.svg.axis()
- .scale(x)
- .orient("bottom");
- var x_group = stage.append("g")
- .attr("class", "x axis");
-
- var offset = 0;
-
- var line = d3.svg.line()
- .defined(function(d) { return d !== undefined })
- .x(function(d, i) { return x((grid.beg + i) - offset) })
- .y(function(d, i) { return y(d) });
-
- /* Initial display: 1024 px, 5 minutes of data */
- var factor = 300000 / 1024;
- var width = 300;
- var height = 300;
-
- var rendered = false;
- window.setTimeout(function() {
- rendered = true;
- adjust();
- }, 1);
-
- function ceil(value, step) {
- var d = value % step;
- if (value === 0 || d !== 0)
- value += (step - d);
- return value;
- }
-
- function jump() {
- var interval = grid.interval;
- var w = (width - margins.right) - margins.left;
- /* This doesn't yet work for an arbitary ponit in time */
- var now = new Date().getTime();
- var end = Math.floor(now / interval);
- var beg = end - Math.floor((factor * w) / interval);
- offset = beg;
- grid.move(beg, end);
- }
-
- function adjust() {
- if (!rendered)
- return;
-
- element
- .attr("width", width)
- .attr("height", height);
-
- var w = (width - margins.right) - margins.left;
- var h = (height - margins.top) - margins.bottom;
-
- var metric = grid.metric();
- var interval = grid.interval;
-
- /* Calculate our maximum value, hopefully rows are tracking this for us */
- var rows = grid.rows;
- var maximum = 0;
- var i, max;
- var len = rows.length;
- for (i = 0; i < len; i++) {
- if (rows[i].maximum !== undefined)
- max = rows[i].maximum;
- else
- max = d3.max(rows[i]);
- if (max > maximum)
- maximum = Math.ceil(max);
- }
-
- /* This doesn't yet work for an arbitary ponit in time */
- var end = Math.floor((factor * w) / interval);
- x.domain([0, end]).range([0, w]);
- y.domain([0, ceil(maximum, tabs[metric].step)]).range([h, 0]);
-
- /* The ticks are inverted backwards */
- var tsc = d3.scale.linear().domain([0, end])
- .range([end, 0]);
-
- /* Calculate ticks every 60 seconds in past */
- var ticks = [];
- for (i = 6; i < end; i += 6)
- ticks.push(Math.round(tsc(i)));
-
- /* Make x-axis ticks into grid of right width */
- x_axis
- .tickValues(ticks)
- .tickSize(-h, -h)
- .tickFormat(function(d) {
- d = Math.round(tsc.invert(d));
- return (d / 6) + " min";
- });
-
- /* Re-render the X axis. Note that we also
- * bump down the labels a bit. */
- x_group
- .attr("transform", "translate(0," + h + ")")
- .call(x_axis)
- .selectAll("text")
- .attr("y", "10px");
-
- /* Turn the Y axis ticks into a grid */
- y_axis
- .tickSize(-w, -w)
- .tickFormat(tabs[metric].formatter);
-
- y_group
- .call(y_axis)
- .selectAll("text")
- .attr("x", "-10px");
-
- jump();
- }
-
- function notified() {
- var rows = grid.rows;
-
- var series = stage.selectAll("path.line")
- .data(rows, function(d, i) { return i });
-
- series
- .style("stroke", function(d, i) { return colors(i) })
- .attr("d", function(d) { return line(d) })
- .classed("highlight", function(d) { return d.uid === highlighted });
-
- series.enter().append("path")
- .attr("class", "line")
- .on("mouseover", function() {
- highlighter(d3.select(this).datum().uid);
- })
- .on("mouseout", function() {
- highlighter(null);
- });
- series.exit().remove();
- }
-
- grid.addEventListener('notify', notified);
-
- function changed() {
- adjust();
- notified();
- }
-
- grid.addEventListener('changed', changed);
-
- function resized() {
- width = selector.offsetWidth - 10;
- if (width < 0)
- width = 0;
- adjust();
- }
-
- window.addEventListener('resize', resized);
- resized();
-
- var timer = window.setInterval(function () {
- if (!width)
- resized();
- else
- jump();
- }, grid.interval);
-
- return {
- highlight: function highlight(uid) {
- highlighted = uid;
- notified();
- },
- close: function close() {
- if (timer)
- window.clearInterval(timer);
- timer = null;
- window.removeEventListener('resize', resized);
- grid.removeEventListener('notify', notified);
- grid.removeEventListener('changed', changed);
- grid.close();
- }
- };
- }
-
- return {
- restrict: 'E',
- link: function($scope, element, attributes) {
- var graph = service_graph($scope, element[0], function(uid) {
- $scope.$broadcast('highlight', uid);
- $scope.$digest();
- });
- $scope.$on("highlight", function(ev, uid) {
- graph.highlight(uid);
- });
- element.on('$destroy', function() {
- graph.close();
- graph = null;
- });
- }
- };
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/images.js b/pkg/kubernetes/scripts/images.js
deleted file mode 100644
index d2403ab92..000000000
--- a/pkg/kubernetes/scripts/images.js
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
- require("angular-route");
- require('angular-dialog.js');
-
- require('./kube-client');
- require('./date');
- require('./tags');
- require('./policy');
-
- require('registry-image-widgets/dist/image-widgets.js');
-
- require('../views/images-page.html');
- require('../views/imagestream-page.html');
- require('../views/image-page.html');
- require('../views/imagestream-delete.html');
- require('../views/imagestream-modify.html');
- require('../views/imagestream-modify.html');
- require('../views/image-delete.html');
-
- /*
- * Executes callback for each stream.status.tag[x].item[y]
- * in a stream. Similar behavior to angular.forEach()
- */
- function imagestreamEachTagItem(stream, callback, context) {
- var i, il, items;
- var t, tl;
- var tags = (stream.status || {}).tags || [];
- for (t = 0, tl = tags.length; t < tl; t++) {
- items = (tags[t].items) || [];
- for (i = 0, il = items.length; i < il; i++)
- callback.call(context || null, tags[t], items[i]);
- }
- }
-
- function identifier(imagestream, tag) {
- var id = imagestream.metadata.namespace + "/" + imagestream.metadata.name;
- if (tag)
- id += ":" + tag.name;
- return id;
- }
-
- angular.module('registry.images', [
- 'ngRoute',
- 'ui.cockpit',
- 'kubeClient',
- 'kubernetes.date',
- 'registry.tags',
- 'registryUI.images',
- ])
-
- .config([
- '$routeProvider',
- function($routeProvider) {
- $routeProvider
- .when('/images/:namespace?', {
- templateUrl: 'views/images-page.html',
- controller: 'ImagesCtrl'
- })
- .when('/images/:namespace/:target', {
- controller: 'ImageCtrl',
- templateUrl: function(params) {
- var target = params['target'] || '';
- if (target.indexOf(':') === -1)
- return 'views/imagestream-page.html';
- else
- return 'views/image-page.html';
- }
- });
- }
- ])
-
- .factory('registryListingScopeSetup', [
- 'imageData',
- 'imageActions',
- 'projectData',
- 'kubeSelect',
- '$location',
- function (data, actions, projectData, select, $location) {
- return function($scope, inPage) {
- function imageByTag (tag) {
- if (tag && tag.items && tag.items.length)
- return select().kind("Image")
- .name(tag.items[0].image)
- .one();
- }
-
- function deleteImageStream(stream) {
- var promise = actions.deleteImageStream(stream);
-
- /* If the promise is successful, redirect to another page */
- promise.then(function() {
- $location.path($scope.viewUrl('images'));
- });
-
- return promise;
- }
-
- function deleteTag(stream, tag) {
- var promise = actions.deleteTag(stream, tag);
-
- /* If the promise is successful, redirect to another page */
- promise.then(function() {
- var parts = [ "images", stream.metadata.namespace, stream.metadata.name ];
- $location.path("/" + parts.map(encodeURIComponent).join("/"));
- });
-
- return promise;
- }
-
- /* All the actions available on the $scope */
- angular.extend($scope, actions);
- angular.extend($scope, data);
-
- $scope.sharedImages = projectData.sharedImages;
- $scope.imageTagNames = data.imageTagNames;
- $scope.imageByTag = imageByTag;
-
- if (inPage) {
- $scope.deleteTag = deleteTag;
- $scope.deleteImageStream = deleteImageStream;
- }
-
- $scope.actions = {
- modifyImageStream: $scope.modifyImageStream,
- deleteImageStream: $scope.deleteImageStream,
- deleteTag: $scope.deleteTag,
- modifyProject: $scope.modifyProject,
- };
- };
- }
- ])
-
- .controller('ImagesCtrl', [
- '$scope',
- '$location',
- 'imageData',
- 'imageActions',
- 'projectData',
- 'kubeLoader',
- 'registryListingScopeSetup',
- 'filterService',
- function($scope, $location, data, actions, projectData, loader, registryListingScopeSetup) {
- $scope.sharedImages = projectData.sharedImages;
-
- /* Watch all the images in current namespace */
- data.watchImages($scope);
-
- $scope.imagestreams = data.allStreams();
- loader.listen(function() {
- $scope.imagestreams = data.allStreams();
- }, $scope);
-
- $scope.$on("activate", function(ev, imagestream, tag) {
- ev.preventDefault();
- $location.path('/images/' + identifier(imagestream, tag));
- });
-
- registryListingScopeSetup($scope, false);
- }
- ])
-
- /*
- * Note that we use the same controller for both the ImageStream
- * and the Image view. This is because ngRoute can't special case
- * routes based on the colon we use to differentiate the two in
- * the path.
- *
- * ie: cockpit/ws vs. cockpit/ws:latest
- *
- * The |kind| on the scope tells us which is which.
- */
- .controller('ImageCtrl', [
- '$scope',
- '$location',
- '$routeParams',
- 'kubeSelect',
- 'kubeLoader',
- 'KubeDiscoverSettings',
- 'imageData',
- 'imageActions',
- 'projectData',
- 'projectPolicy',
- 'registryListingScopeSetup',
- function($scope, $location, $routeParams, select, loader, discoverSettings, data, actions, projectData, projectPolicy, registryListingScopeSetup) {
- var target = $routeParams["target"] || "";
- var pos = target.indexOf(":");
-
- /* colon contains a tag name, only set if we're looking at an image */
- var namespace = $routeParams["namespace"] || "";
- var name, tagname;
- if (pos === -1) {
- $scope.kind = "ImageStream";
- name = target;
- tagname = null;
- } else {
- $scope.kind = "Image";
- name = target.substr(0, pos);
- tagname = target.substr(pos + 1);
- }
-
- registryListingScopeSetup($scope, true);
-
- /* There's no way to watch a single item ... so watch them all :( */
- data.watchImages($scope);
-
- loader.listen(function() {
- $scope.stream = select().kind("ImageStream")
- .namespace(namespace)
- .name(name)
- .one();
- $scope.image = $scope.config = $scope.layers = $scope.labels = $scope.tag = null;
-
- imagestreamEachTagItem($scope.stream || {}, function(tag, item) {
- if (tag.tag === tagname)
- $scope.tag = tag;
- });
-
- if ($scope.tag)
- $scope.image = $scope.imageByTag($scope.tag);
- if ($scope.image) {
- $scope.names = data.imageTagNames($scope.image);
- $scope.config = data.imageConfig($scope.image);
- $scope.layers = data.imageLayers($scope.image);
- $scope.labels = data.imageLabels($scope.image);
- }
- }, $scope);
-
- $scope.$on("activate", function(ev, imagestream, tag) {
- ev.preventDefault();
- $location.path('/images/' + identifier(imagestream, tag));
- });
-
- function updateShowDockerPushCommands() {
- discoverSettings().then(function(settings) {
- projectPolicy.subjectAccessReview(namespace, settings.currentUser, 'update', 'imagestreamimages')
- .then(function(allowed) {
- if (allowed != $scope.showDockerPushCommands) {
- $scope.showDockerPushCommands = allowed;
- $scope.$applyAsync();
- }
- });
- });
- }
-
- // watch for project changes to update showDockerPushCommands, and initialize it
- $scope.$on("$routeUpdate", updateShowDockerPushCommands);
- updateShowDockerPushCommands();
- }
- ])
-
- .factory("imageData", [
- 'kubeSelect',
- 'kubeLoader',
- function(select, loader) {
- var watching = false;
-
- /* Called when we have to load images via imagestreams */
- loader.listen(function(objects) {
- for (var link in objects) {
- if (objects[link].kind === "ImageStream")
- handle_imagestream(objects[link]);
- if (objects[link].kind === "Image")
- handle_image(objects[link]);
- }
- });
-
- function handle_imagestream(imagestream) {
- var meta = imagestream.metadata || { };
- var status = imagestream.status || { };
- angular.forEach(status.tags || [ ], function(tag) {
- angular.forEach(tag.items || [ ], function(item) {
- var link = loader.resolve("Image", item.image);
- if (link in loader.objects)
- return;
-
- /* An interim object while we're loading */
- var interim = { kind: "Image", apiVersion: "v1", metadata: { name: item.image } };
- loader.handle(interim);
-
- if (!watching)
- return;
-
- var name = meta.name + "@" + item.image;
- loader.load("ImageStreamImage", name, meta.namespace).then(function(resource) {
- var image = resource.image;
- if (image) {
- image.kind = "Image";
- loader.handle(image);
- handle_image(image);
- }
- }, function(response) {
- var message = response.statusText || response.message || String(response);
- console.warn("couldn't load image: " + message);
- interim.metadata.resourceVersion = "invalid";
- });
- });
- });
- }
-
- /*
- * Create a pseudo-item with kind DockerImageManifest for
- * each image with a dockerImageManifest that we see. Identical
- * name to the image itself.
- */
- function handle_image(image) {
- var item;
- var manifest = image.dockerImageManifest;
- if (manifest) {
- manifest = JSON.parse(manifest);
- angular.forEach(manifest.history || [], function(item) {
- if (typeof item.v1Compatibility == "string")
- item.v1Compatibility = JSON.parse(item.v1Compatibility);
- });
- item = {
- kind: "DockerImageManifest",
- metadata: {
- name: image.metadata.name,
- selfLink: "/internal/manifests/" + image.metadata.name
- },
- manifest: manifest,
- };
- loader.handle(item);
- }
- }
-
- /* Load images, but fallback to loading individually */
- function watchImages(until) {
- watching = true;
- var a = loader.watch("images", until);
- var b = loader.watch("imagestreams", until);
-
- return {
- cancel: function() {
- a.cancel();
- b.cancel();
- }
- };
- }
-
- /*
- * Filters selection to those with names that is
- * in the given TagEvent.
- */
- select.register("taggedBy", function(tag) {
- var i, len;
- var results = { };
- // catch condition when tag.items is null due to imagestream import error
- if (!tag.items)
- return select(null);
- for (i = 0, len = tag.items.length; i < len; i++)
- this.name(tag.items[i].image).extend(results);
- return select(results);
- });
-
- /*
- * Filters selection to those with names that is in the first
- * item in the given TagEvent.
- */
- select.register("taggedFirst", function(tag) {
- var results = { };
- if (!tag.items)
- return select(null);
- if (tag.items.length)
- this.name(tag.items[0].image).extend(results);
- return select(results);
- });
-
- /*
- * Filter that gets image streams for the given tag.
- */
- select.register({
- name: "containsTagImage",
- digests: function(arg) {
- var ret = [];
- if (typeof arg == "string") {
- ret.push(arg);
- } else {
- imagestreamEachTagItem(arg, function(tag, item) {
- ret.push(item.image + "");
- });
- }
- return ret;
- }
- });
-
- select.register("listTagNames", function(image_name) {
- var names = [];
- angular.forEach(this.containsTagImage(image_name), function(stream) {
- imagestreamEachTagItem(stream, function(tag, item) {
- if (!image_name || item.image == image_name)
- names.push(stream.metadata.namespace + "/" + stream.metadata.name + ":" + tag.tag);
- });
- });
- return names;
- });
-
- /*
- * Filter that gets the config object for a docker based
- * image.
- */
- select.register("dockerImageConfig", function() {
- var results = { };
- angular.forEach(this, function(image, key) {
- var compat;
- var layers = imageLayers(image) || { };
- if (layers[0]) {
- compat = layers[0].v1Compatibility;
- if (compat && compat.config) {
- results[key] = compat.config;
- return;
- }
- }
-
- var meta = image.dockerImageMetadata || { };
- if (meta.Config)
- results[key] = meta.Config;
- });
-
- return select(results);
- });
-
- /*
- * Filter that gets a dict of labels for a config
- * image.
- */
- select.register("dockerConfigLabels", function() {
- var results = { };
- angular.forEach(this, function(config, key) {
- var labels;
- if (config)
- labels = config.Labels;
- if (labels)
- results[key] = labels;
- });
- return select(results);
- });
-
- function imageLayers(image) {
- if (!image)
- return null;
- var item = select().kind("DockerImageManifest")
- .name(image.metadata.name)
- .one();
- if (item && item.manifest && item.manifest.schemaVersion === 1)
- return item.manifest.history;
- if (image.dockerImageLayers)
- return image.dockerImageLayers;
- return null;
- }
-
- /* HACK: We really want a metadata index here */
- function configCommand(config) {
- var result = [ ];
- if (!config)
- return "";
- if (config.Entrypoint)
- result.push.apply(result, config.Entrypoint);
- if (config.Cmd)
- result.push.apply(result, config.Cmd);
- var string = result.join(" ");
- if (config.User && config.User.split(":")[0] != "root")
- return "$ " + string;
- else
- return "# " + string;
- }
-
- return {
- watchImages: watchImages,
- allStreams: function allStreams() {
- return select().kind("ImageStream");
- },
- imageLayers: imageLayers,
- imageConfig: function imageConfig(image) {
- return select(image).dockerImageConfig()
- .one() || { };
- },
- imageTagNames: function imageTagNames(image) {
- return select().kind("ImageStream")
- .listTagNames(image.metadata.name);
- },
- imageLabels: function imageLabels(image) {
- var labels = select(image).dockerImageConfig()
- .dockerConfigLabels()
- .one();
- if (labels && angular.equals({ }, labels))
- labels = null;
- return labels;
- },
- configCommand: configCommand,
- };
- }
- ])
-
- .factory('imageActions', [
- '$modal',
- '$location',
- function($modal, $location) {
- function deleteImageStream(stream) {
- return $modal.open({
- animation: false,
- controller: 'ImageStreamDeleteCtrl',
- templateUrl: 'views/imagestream-delete.html',
- resolve: {
- dialogData: function() {
- return { stream: stream };
- }
- },
- }).result;
- }
-
- function createImageStream() {
- return $modal.open({
- animation: false,
- controller: 'ImageStreamModifyCtrl',
- templateUrl: 'views/imagestream-modify.html',
- resolve: {
- dialogData: function() {
- return { };
- }
- },
- }).result;
- }
-
- function modifyImageStream(stream) {
- return $modal.open({
- animation: false,
- controller: 'ImageStreamModifyCtrl',
- templateUrl: 'views/imagestream-modify.html',
- resolve: {
- dialogData: function() {
- return { stream: stream };
- }
- },
- }).result;
- }
-
- function deleteTag(stream, tag) {
- var modal = $modal.open({
- animation: false,
- controller: 'ImageDeleteCtrl',
- templateUrl: 'views/image-delete.html',
- resolve: {
- dialogData: function() {
- return { stream: stream, tag: tag };
- }
- },
- });
-
- return modal.result;
- }
-
- function modifyProject(project) {
- $location.path("/projects/" + project);
- return false;
- }
-
- return {
- createImageStream: createImageStream,
- modifyImageStream: modifyImageStream,
- deleteImageStream: deleteImageStream,
- deleteTag: deleteTag,
- modifyProject: modifyProject,
- };
- }
- ])
-
- .controller("ImageStreamDeleteCtrl", [
- "$scope",
- "$modalInstance",
- "dialogData",
- "kubeMethods",
- function($scope, $instance, dialogData, methods) {
- angular.extend($scope, dialogData);
-
- $scope.performDelete = function performDelete() {
- return methods.delete($scope.stream);
- };
- }
- ])
-
- .controller("ImageStreamModifyCtrl", [
- "$scope",
- "$modalInstance",
- "dialogData",
- "imageTagData",
- "kubeMethods",
- "filterService",
- "gettextCatalog",
- function($scope, $instance, dialogData, tagData, methods, filter, gettextCatalog) {
- var stream = dialogData.stream || { };
- var meta = stream.metadata || { };
- var spec = stream.spec || { };
- const _ = gettextCatalog.getString.bind(gettextCatalog);
-
- var populate = "none";
- if (spec.dockerImageRepository)
- populate = "pull";
- if (spec.tags)
- populate = "tags";
-
- var fields = {
- name: meta.name || "",
- project: meta.namespace || filter.namespace() || "",
- populate: populate,
- pull: spec.dockerImageRepository || "",
- tags: tagData.parseSpec(spec),
- insecure: hasInsecureTag(spec),
- };
-
- $scope.fields = fields;
- $scope.labels = {
- populate: {
- none: _("Don't pull images automatically"),
- pull: _("Sync all tags from a remote image repository"),
- tags: _("Pull specific tags from another image repository"),
- }
- };
-
- $scope.placeholder = _("eg: my-image-stream");
-
- /* During creation we have a different label */
- if (!dialogData.stream)
- $scope.labels.populate.none = _("Create empty image stream");
-
- function performModify() {
- var data = {
- apiVersion: "v1",
- kind: "ImageStream",
- metadata: { annotations: { "openshift.io/image.dockerRepositoryCheck" : null } }
- };
-
- if (fields.populate == "pull")
- data.spec = { dockerImageRepository: fields.pull.trim(), };
- else if (fields.populate == "tags")
- data.spec = tagData.buildSpec(fields.tags, data.spec, fields.insecure, fields.pull.trim());
- else
- data.spec = { dockerImageRepository: null, tags: null };
-
- return methods.patch(stream, data);
- }
-
- function performCreate() {
- var data = {
- apiVersion: "v1",
- kind: "ImageStream",
- metadata: {
- name: fields.name.trim(),
- namespace: fields.project.trim(),
- }
- };
-
- if (fields.populate == "pull")
- data.spec = { dockerImageRepository: fields.pull.trim(), };
- else if (fields.populate == "tags")
- data.spec = tagData.buildSpec(fields.tags, data.spec, fields.insecure, fields.pull.trim());
-
- return methods.check(data, {
- "metadata.name": "#imagestream-modify-name",
- "metadata.namespace": "#imagestream-modify-project",
- }).then(function() {
- return methods.create(data, fields.project);
- });
- }
-
- function hasInsecureTag(spec) {
- // loop through tags, check importPolicy.insecure boolean
- // if one tag is insecure the intent is the imagestream is insecure
- var insecure;
- if (spec) {
- for (var tag in spec.tags) {
- if (spec.tags[tag].importPolicy.insecure) {
- insecure = spec.tags[tag].importPolicy.insecure;
- break;
- }
- }
- }
- return insecure;
- }
-
- $scope.performCreate = performCreate;
- $scope.performModify = performModify;
- $scope.hasInsecureTag = hasInsecureTag;
-
- $scope.projects = filter.namespaces;
- angular.extend($scope, dialogData);
- }
- ])
-
- .controller("ImageDeleteCtrl", [
- "$scope",
- "$modalInstance",
- "dialogData",
- "kubeMethods",
- function($scope, $instance, dialogData, methods) {
- angular.extend($scope, dialogData);
-
- $scope.performDelete = function performDelete() {
- var name = $scope.stream.metadata.name + ":" + $scope.tag.tag;
- return methods.delete("ImageStreamTag", name, $scope.stream.metadata.namespace);
- };
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/kube-client-cockpit.js b/pkg/kubernetes/scripts/kube-client-cockpit.js
deleted file mode 100644
index 6d1b6b0f6..000000000
--- a/pkg/kubernetes/scripts/kube-client-cockpit.js
+++ /dev/null
@@ -1,1229 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
- var cockpit = require('cockpit');
-
- require('./kube-client');
-
- function debug() {
- if (window.debugging == "all" || window.debugging == "kube")
- console.debug.apply(console, arguments);
- }
-
- function updateMessage(response) {
- if (!response)
- return;
-
- var obj;
- try {
- obj = JSON.parse(response.data);
- } catch (e) {
- // Some kubernetes versions message up json reponses
- if (response.data && response.headers &&
- response.headers["Content-Type"] === "text/plain") {
- obj = { message: response.data };
- } else {
- return;
- }
- }
-
- if (obj && obj.message)
- response.message = response.statusText = obj.message;
- }
-
- /*
- * Currently we assume that the certificates in the kube config
- * file are:
- *
- * base64(PEM(data))
- *
- * Since our http-stream2 expects PEM certificates (although they're
- * nasty, they're better than all the alternatives) so we strip out
- * the outer base64 layer.
- */
-
- function parseCertOption(object, option) {
- var blob = object[option + "-data"];
- if (blob !== undefined)
- return { data: window.atob(blob) };
-
- var file = object[option];
- if (file !== undefined)
- return { file: file };
-
- return undefined;
- }
-
- function basicToken(user, pass) {
- return window.btoa(window.unescape(encodeURIComponent(user + ":" + pass)));
- }
-
- angular.module("kubeClient.cockpit", [
- "kubeClient",
- ])
-
- .factory("CockpitKubeWatch", [
- "$q",
- "KUBE_SCHEMA",
- "cockpitKubeDiscover",
- function($q, KUBE_SCHEMA, cockpitKubeDiscover) {
- return function CockpitKubeWatch(path, callback) {
- debug("creating watch:", path);
-
- /* Used to track the last resource for restarting query */
- var lastResource;
-
- /* Whether close has been called */
- var stopping = false;
-
- /* The current HTTP request */
- var channel = null;
-
- /* The http options */
- var http = null;
-
- /* Waiting to do the next http request */
- var wait = null;
-
- /*
- * Loading logic.
- *
- * For performance, we only use watches here. So we have
- * to guess when loading is finished and when updates begin.
- * There are several heuristics:
- *
- * 1) Receiving a MODIFY or DELETE means loading has finished.
- * 2) A timeout after last ADDED
- * 3) Error or connection closed.
- *
- * Remember that a watch object can restart its request for a number
- * of reasons, and so the loading/loaded state may go back and forth.
- *
- * When transitioning from a loading to a loaded state, we have to:
- * a) Notify the caller if not already done
- * b) See if any objects present before load need to be removed.
- */
-
- var defer = $q.defer();
- var promise = defer.promise;
- var loaded = false;
- var objects = { };
- var previous;
- var loading;
-
- function loadBegin(full) {
- if (full) {
- previous = objects;
- objects = { };
- } else {
- previous = null;
- }
- loadPoke(true);
- }
-
- function loadPoke(force) {
- if (force || loading !== undefined) {
- window.clearTimeout(loading);
- loading = window.setTimeout(loadFinish, 100);
- }
- }
-
- function loadFinish(ex) {
- if (loaded)
- return;
- loaded = true;
-
- var key, prev;
- var frames = [];
- prev = previous;
- previous = null;
- for (key in prev) {
- if (!(key in objects))
- frames.push({ type: "DELETED", object: prev[key] });
- }
-
- /* Simulated delete frames */
- if (frames.length)
- callback(frames);
-
- /* Tell callback to flush */
- callback([]);
-
- if (ex)
- defer.reject(ex);
- else
- defer.resolve();
- }
-
- /*
- * Each change is sent as an individual line from Kubernetes
- * but they may not arrive exactly that way, so we buffer
- * and split lines again.
- */
-
- var buffer;
- function handleWatch(data) {
- if (buffer)
- data = buffer + data;
-
- var lines = data.split("\n");
- var i;
- var length = lines.length - 1;
-
- /* Last line is incomplete save for later */
- buffer = lines[length];
-
- var frames = [];
-
- /* Process all the others */
- var frame, object;
- for (i = 0; i < length; i++) {
- try {
- frame = JSON.parse(lines[i]);
- } catch (ex) {
- console.warn(lines[i], ex);
- channel.close();
- continue;
- }
-
- object = frame.object;
- if (!object) {
- console.warn("invalid watch without object", frame);
- continue;
- }
-
- /* The watch failed, likely due to invalid resourceVersion */
- if (frame.type == "ERROR") {
- if (lastResource) {
- lastResource = null;
- startWatch();
- }
- continue;
- }
-
- var meta = object.metadata;
- if (!meta || (!meta.uid && object.kind !== "Project") || !object.kind) {
- console.warn("invalid kube object: ", object);
- continue;
- }
-
- lastResource = meta.resourceVersion;
-
- /* We track objects here so we can restart watches */
- var uid = meta.uid;
- if (frame.type == "DELETED")
- delete objects[uid];
- else
- objects[uid] = object;
-
- debug(frame.type, object.kind, meta.uid);
- frames.push(frame);
- }
-
- callback(frames);
- loadPoke();
- }
-
- function startWatch() {
- if (channel)
- return;
-
- var full = true;
- var uri = path + "?watch=true";
-
- /*
- * If we have a last resource we can guarantee that we don't miss
- * any objects or changes to objects. If we don't have one, then we
- * have to list everything again. Still watch at the same time though.
- */
- if (lastResource) {
- uri += "&resourceVersion=" + encodeURIComponent(lastResource);
- full = false;
- }
-
- /*
- * As a precaution, watch must take at least 1 second
- * to complete. Otherwise we could be in a tight loop here.
- * eg: if the API of Kubernetes changes unpredictably.
- */
- var blocked = false;
- window.setTimeout(function() {
- blocked = true;
- }, 1000);
-
- var opts = angular.extend({ }, http, {
- path: uri,
- method: "GET"
- });
-
- channel = cockpit.channel(opts);
-
- var response = { };
- var failed = false;
- channel.addEventListener("control", function(ev, options) {
- if (options.command == "response") {
- response = options;
- if (response.status > 299)
- failed = true;
- loadBegin(full);
- }
- });
-
- channel.addEventListener("message", function(ev, payload) {
- if (failed)
- response.data = (response.data || "") + payload;
- else
- handleWatch(payload);
- });
-
- channel.addEventListener("close", function(ev, options) {
- channel = null;
- loading = false;
- if (stopping)
- return;
-
- var msg = "watching " + path + " failed: ";
- var problem = options.problem;
- var status = response.status;
-
- if (problem) {
- msg += problem;
- if (problem == "disconnected")
- debug(msg);
- else
- console.warn(msg);
- response.problem = problem;
- response.status = 999;
- loadFinish(response);
- } else if (failed) {
- updateMessage(response);
- msg += (response.message || response.reason || status);
- if (status === 404 || status === 410 || status === 403) {
- debug(msg);
- loadFinish(response);
- return; /* don't try watch again if we get a 404/410/403 */
- } else {
- console.warn(msg);
- }
- loadFinish(response);
- } else if (!blocked) {
- console.warn("watching kube " + path + " didn't block");
- } else {
- startWatch();
- return;
- }
-
- startWatchLater();
- });
-
- /* No http request body */
- channel.control({ command: "done" });
- }
-
- function startWatchLater() {
- if (!wait) {
- wait = window.setTimeout(function() {
- wait = null;
- startWatch();
- }, 5000);
- }
- }
-
- $q.when(cockpitKubeDiscover(), function(options) {
- http = options;
- startWatch();
- }, function(resp) {
- loadFinish(resp);
- });
-
- promise.cancel = function cancel(ex) {
- stopping = true;
- var problem;
- if (channel) {
- if (ex)
- problem = ex.problem;
- channel.close(problem || "disconnected");
- channel = null;
- }
- window.clearTimeout(wait);
- wait = null;
- http = null;
- loadFinish(ex);
- };
-
- return promise;
- };
- }
- ])
-
- /*
- * A WebSocket factory for the kubernetes-container-terminal
- * that uses the kubectl command with a fake websocket
- */
- .factory("CockpitKubectlWebSocket", [
- function() {
- function decode(href, options) {
- var pos = href.indexOf('?');
- var first = href;
- var path;
- if (pos === -1)
- first = href;
- else
- first = href.substr(0, pos);
-
- path = first.split('/').map(decodeURIComponent);
-
- if (pos !== -1) {
- angular.forEach(href.substring(pos + 1).split("&"), function(opt) {
- var last;
- var parts = opt.split('=');
- var name = decodeURIComponent(parts[0]);
- var value = decodeURIComponent(parts[1]);
- if (options.hasOwnProperty(name)) {
- last = options[name];
- if (!angular.isArray(last))
- last = options[name] = [ last ];
- last.push(value);
- } else {
- options[name] = value;
- }
- });
- }
-
- return path;
- }
-
- function parser(url) {
- var options = { };
- var path = decode(url, options);
-
- var command = [ ];
- var args = [ ];
- var namespace = "default";
- var container = null;
- var cmd = "log";
- var pod = "";
-
- var i, len;
- for (i = 0, len = path.length; i < len; i++) {
- if (path[i] === "namespaces") {
- namespace = path[++i];
- } else if (path[i] === "pods") {
- pod = path[++i];
- if (path[i + 1] == "exec")
- cmd = "exec";
- else if (path[i + 1] == "log")
- cmd = "logs";
- }
- }
-
- for (i in options) {
- if (i == "container") {
- container = options[i];
- } else if (i == "command") {
- if (angular.isArray(options[i]))
- command = options[i];
- else
- command.push(options[i]);
- } else if (i == "stdin" || i == "tty" || i == "follow") {
- args.push("--" + i);
- }
- }
-
- var ret = [ "kubectl", cmd, "--namespace=" + namespace ];
- if (container)
- ret.push("--container=" + container);
- ret.push.apply(ret, args);
- ret.push(pod, "--");
- ret.push.apply(ret, command);
- return ret;
- }
-
- return function KubeFakeWebSocket(url, protocols) {
- var cmd = parser(url);
- var base64 = false;
-
- /* A fake WebSocket */
- var channel;
- var state = 0; /* CONNECTING */
- var ws = { };
- cockpit.event_target(ws);
-
- function open() {
- channel = cockpit.channel({
- payload: "stream",
- spawn: cmd,
- pty: true
- });
-
- channel.addEventListener("close", function(ev, options) {
- channel = null;
-
- state = 3;
- var cev = new Event("close", { bubbles: false, cancelable: false });
- ws.dispatchEvent(cev);
- });
-
- channel.addEventListener("message", function(ev, data) {
- if (base64)
- data = "1" + window.btoa(data);
- var mev = new window.MessageEvent('message', { data: data });
- ws.dispatchEvent(mev);
- });
-
- state = 1;
- var oev = new Event("open", { bubbles: false, cancelable: false });
- ws.dispatchEvent(oev);
- }
-
- function fail() {
- var ev = new Event("close", { bubbles: false, cancelable: false });
- ws.dispatchEvent(ev);
- }
-
- function close(code, reason) {
- if (channel)
- channel.close(reason);
- }
-
- function send(data) {
- if (base64) {
- /*
- * HACK: container-terminal sends Width/Height commands but
- * many of the kubernetes implementations don't yet support
- * that. So filter them out here for now.
- */
- if (data[0] === "4")
- return;
- data = window.atob(data.slice(1));
- }
-
- if (channel)
- channel.send(data);
- }
-
- var valid = true;
- if (protocols) {
- if (angular.isArray(protocols))
- valid = base64 = protocols.indexOf("base64.channel.k8s.io") !== -1;
- else
- valid = base64 = protocols === "base64.channel.k8s.io";
- }
-
- /* A fake WebSocket */
- Object.defineProperties(ws, {
- binaryType: { value: "arraybuffer" },
- bufferedAmount: { value: 0 },
- extensions: { value: "" },
- protocol: { value: base64 ? "base64.channel.k8s.io" : "" },
- readyState: { get: function() { return state } },
- url: { value: url },
- close: { value: close },
- send: { value: send },
- });
-
- if (valid) {
- window.setTimeout(open);
- } else {
- console.warn("Unsupported kubernetes container WebSocket subprotocol: " + protocols);
- window.setTimeout(fail);
- }
-
- return ws;
- };
- }
- ])
-
- .factory("CockpitKubeSocket", [
- "$q",
- "$injector",
- function($q, $injector) {
- return function CockpitKubeSocket(url, config) {
- var base64 = false;
- var connect;
- var state = 0; /* CONNECTING */
- var ws = { };
- var channel;
-
- var protocols = [];
- if (config && config.protocols) {
- protocols = config.protocols;
- if (!angular.isArray(protocols))
- protocols = [ String(config.protocols) ];
- }
-
- /*
- * If we're called with fully formed options, then don't do
- * connect discovery stuff. Otherwise ask our connect service
- * for connection info, and do discovery.
- */
- if (config && config.port)
- connect = config;
- else
- connect = $injector.get('cockpitKubeDiscover')();
-
- function close(code, reason) {
- if (channel)
- channel.close(reason);
- }
-
- function send(data) {
- /*
- * HACK: container-terminal sends Width/Height commands but
- * many of the kubernetes implementations don't yet support
- * that. So filter them out here for now.
- */
- if (base64 && data[0] === "4")
- return;
-
- if (channel)
- channel.send(data);
- }
-
- /* A fake WebSocket */
- Object.defineProperties(ws, {
- binaryType: { value: "arraybuffer" },
- bufferedAmount: { value: 0 },
- extensions: { value: "" },
- protocol: { value: protocols[0] },
- readyState: { get: function() { return state } },
- url: { value: url },
- close: { value: close },
- send: { value: send },
- });
-
- base64 = protocols.indexOf("base64.channel.k8s.io") !== -1;
-
- $q.when(connect, function connected(options) {
- cockpit.event_target(ws);
-
- channel = cockpit.channel(angular.extend({ }, options, {
- payload: "websocket-stream1",
- path: url,
- protocols: protocols.length > 0 ? protocols : undefined,
- }));
-
- channel.addEventListener("close", function(ev, options) {
- channel = null;
-
- state = 3;
- var cev = new Event("close", { bubbles: false, cancelable: false });
- ws.dispatchEvent(cev);
- });
-
- channel.addEventListener("message", function(ev, data) {
- var mev = new window.MessageEvent('message', { data: data });
- ws.dispatchEvent(mev);
- });
-
- state = 1;
- var oev = new Event("open", { bubbles: false, cancelable: false });
- ws.dispatchEvent(oev);
- });
-
- return ws;
- };
- }
- ])
-
- .factory("CockpitKubeRequest", [
- "$q",
- "$injector",
- function($q, $injector) {
- var CONTENT_TYPE = "Content-Type";
- var JSON_TYPE = "application/json";
- return function CockpitKubeRequest(method, path, body, config) {
- var defer = $q.defer();
- var promise = defer.promise;
- var connect, channel;
-
- var heads = { };
- if (body && typeof body == "object") {
- body = JSON.stringify(body);
- heads[CONTENT_TYPE] = JSON_TYPE;
- }
-
- if (!config)
- config = { };
-
- /*
- * If we're called with fully formed options, then don't do
- * connect discovery stuff. Otherwise ask our connect service
- * for connection info, and do discovery.
- */
- if (config && config.port)
- connect = config;
- else
- connect = $injector.get('cockpitKubeDiscover')();
-
- $q.when(connect, function connected(options) {
- var opts = angular.extend({ }, config, options, {
- path: path,
- method: method,
- payload: "http-stream2"
- });
-
- opts.headers = angular.extend(heads, config.headers || { }, options.headers || { });
-
- debug("request:", method, path, opts);
- channel = cockpit.channel(opts);
-
- var response = { };
- channel.addEventListener("control", function(ev, options) {
- if (options.command == "response") {
- response = options;
- response.statusText = response.reason;
- }
- });
-
- channel.addEventListener("message", function(ev, payload) {
- response.data = (response.data || "") + payload;
- });
-
- channel.addEventListener("close", function(ev, options) {
- channel = null;
-
- response.options = options;
- if (options.problem) {
- response.problem = response.statusText = options.problem;
- response.status = 999;
- }
-
- var headers = response.headers || { };
- var content_type = headers[CONTENT_TYPE] || headers[CONTENT_TYPE.toLowerCase()] || "";
- if (content_type.lastIndexOf(JSON_TYPE, 0) === 0) {
- try {
- response.data = JSON.parse(response.data);
- } catch (ex) {
- /* it's not JSON, just leave as text */
- }
- }
-
- if (response.status > 299) {
- updateMessage(response);
- defer.reject(response);
- } else {
- defer.resolve(response);
- }
- });
-
- if (body)
- channel.send(body);
- channel.control({ command: "done" });
-
- /* Failed to connect */
- }, function failed(response) {
- defer.reject(response);
- });
-
- /* Helpful function on the promise */
- promise.cancel = function cancel() {
- if (connect.cancel)
- connect.cancel();
- if (channel)
- channel.close("cancelled");
- };
-
- return promise;
- };
- }
- ])
-
- .factory("cockpitRunCommand", [
- '$q',
- function($q) {
- return function runCommand(args) {
- var defer = $q.defer();
- var promise = defer.promise;
- var channel = cockpit.channel({
- "payload": "stream",
- "spawn": args,
- "err": "message"
- });
-
- var result = "";
- channel.addEventListener("message", function(ev, payload) {
- result += payload;
- });
- channel.addEventListener("close", function(ev, options) {
- channel = null;
- if (options.problem)
- defer.reject(options);
- else
- defer.resolve(result);
- });
-
- promise.cancel = function cancel(options) {
- if (channel)
- channel.close(options || "cancelled");
- };
-
- promise.send = function send(data) {
- if (channel)
- channel.send(data);
- };
-
- return promise;
- };
- }
- ])
-
- .factory("cockpitKubectlConfig", [
- '$q',
- 'cockpitRunCommand',
- function($q, runCommand) {
- function generateKubeOptions(cluster, user) {
- var parser, token, provider;
- var options = { port: 8080, headers: { } };
-
- if (cluster && cluster.server) {
- parser = document.createElement('a');
- parser.href = cluster.server;
- if (parser.hostname)
- options.address = parser.hostname;
- if (parser.port)
- options.port = parseInt(parser.port, 10);
- if (parser.protocol == 'https:') {
- if (!parser.port || parser.port === "0")
- options.port = parser.href == cluster.server ? 6443 : 443;
-
- options.tls = { };
- options.tls.authority = parseCertOption(cluster, "certificate-authority");
- options.tls.validate = !cluster["insecure-skip-tls-verify"];
- }
- }
-
- if (user) {
- token = user.token;
- provider = user["auth-provider"] || {};
- if (provider.config) {
- if (provider.config['access-token'])
- token = provider.config['access-token'];
- else if (provider.config['token'])
- token = provider.config['token'];
- }
-
- if (token)
- options.headers["Authorization"] = "Bearer " + token;
- if (user.username)
- options.headers["Authorization"] = "Basic " + basicToken(user.username, user.password || "");
- if (options.tls) {
- options.tls.certificate = parseCertOption(user, "client-certificate");
- options.tls.key = parseCertOption(user, "client-key");
- }
- }
-
- return options;
- }
-
- function parseKubeConfig(data, contextName) {
- var config, options;
-
- try {
- config = JSON.parse(data);
- } catch (ex) {
- console.warn("received invalid kubectl config", ex);
- return null;
- }
-
- if (!contextName)
- contextName = config["current-context"];
- var contexts = config["contexts"] || [];
-
- /* Find the cluster info */
- var userName, clusterName;
- contexts.forEach(function(info) {
- if (info.name === contextName) {
- var context = info.context || { };
- userName = context.user;
- clusterName = context.cluster;
- }
- });
-
- /* Find the user info */
- var user;
- var users = config["users"] || [];
- users.forEach(function(info) {
- if (info.name === userName)
- user = info.user;
- });
-
- /* Find the cluster info */
- var cluster;
- var clusters = config["clusters"] || [];
- clusters.forEach(function(info) {
- if (info.name == clusterName)
- cluster = info.cluster;
- });
-
- options = generateKubeOptions(cluster, user);
- debug("parsed kube config", options);
- return options;
- }
-
- function read() {
- var cmd = ["kubectl", "config", "view", "--output=json", "--raw"];
-
- /* Call kubectl minified config view. That only outputs
- * the objects that would be used by a connection */
- return runCommand(["kubectl", "config", "view", "--minify", "--output=json"])
- .then(function (data) {
- var p;
- var auth_provider;
- var user;
-
- /* If the default data has a 'auth-provider'
- * section then call kubectl version to try to
- * get it to fill in any token data.
- */
- try {
- user = JSON.parse(data)["users"][0];
- if (user && user['user'])
- auth_provider = user['user']['auth-provider'];
- } catch (ex) {
- console.warn("received invalid kubectl config", ex);
- }
-
- if (auth_provider) {
- p = runCommand(["kubectl", "version"])
- .then(function () {
- return runCommand(cmd);
- }, function () {
- return runCommand(cmd);
- });
- } else {
- p = runCommand(cmd);
- }
-
- return p;
- });
- }
-
- return {
- read: read,
- parseKubeConfig: parseKubeConfig,
- generateKubeOptions: generateKubeOptions,
- };
- }
- ])
-
- .factory("cockpitKubeDiscover", [
- "$q",
- "CockpitKubeRequest",
- "cockpitKubectlConfig",
- "cockpitConnectionInfo",
- "cockpitBrowserStorage",
- function($q, CockpitKubeRequest, cockpitKubectlConfig, info, browser) {
- var defer = null;
-
- return function cockpitKubeDiscover(force) {
- if (!force && defer)
- return defer.promise;
-
- var last, req, kubectl, loginOptions;
- var loginData = browser.localStorage.getItem('login-data', true);
- defer = $q.defer();
-
- var schemes = [
- { port: 8080 },
- { port: 8443, tls: { } },
- { port: 6443, tls: { } },
- ];
-
- function step(options, kubeConfig) {
- if (!options)
- options = schemes.shift();
-
- /* No further ports to try? */
- if (!options) {
- last.statusText = cockpit.gettext("Couldn't find running API server");
- last.problem = "not-found";
- defer.reject(last);
- return;
- }
-
- /* If options is a function call it, the function is
- * responsible to call step again when ready */
- if (typeof options === "function") {
- options();
- return;
- }
-
- options.payload = "http-stream2";
- debug("trying kube at:", options);
- req = new CockpitKubeRequest("GET", "/api", "", options);
- req.then(function(response) {
- req = null;
- var resp = response.data;
- if (resp && resp.versions) {
- debug("discovered kube api", resp);
- if (kubeConfig) {
- info.kubeConfig = kubeConfig;
- if (kubectl)
- info.type = "kubectl";
- else
- info.type = "sessionData";
- } else {
- info.type = "open";
- }
-
- defer.resolve(options);
- } else {
- debug("not an api endpoint:", options);
- last = response;
- kubectl = null;
- step();
- }
- })
- .catch(function(response) {
- req = null;
- kubectl = null;
- last = response;
-
- if (response.problem === "not-found") {
- debug("api endpoint not found on:", options);
- step();
- } else {
- debug("connecting to kube failed:", response);
- defer.reject(response);
- }
- });
- }
-
- function kubectlStep() {
- kubectl = cockpitKubectlConfig.read()
- .then(function(data) {
- var options = cockpitKubectlConfig.parseKubeConfig(data);
- step(options, options ? JSON.parse(data) : null);
- })
- .catch(function(options) {
- console.warn("kubectl failed: " + (options.message || options.problem));
- step();
- });
- }
-
- if (force && typeof force === 'object') {
- schemes = [ force ];
- step();
- } else if (force === "kubectl") {
- schemes = [ kubectlStep ];
- step();
- } else {
- schemes.unshift(kubectlStep);
- if (loginData)
- loginOptions = cockpitKubectlConfig.parseKubeConfig(loginData);
- step(loginOptions, loginOptions ? JSON.parse(loginData) : null);
- }
-
- defer.promise.cancel = function cancel() {
- if (kubectl && kubectl.cancel)
- kubectl.cancel("cancelled");
-
- if (req)
- req.close("cancelled");
- };
- return defer.promise;
- };
- }
- ])
-
- .factory("CockpitEnvironment", [
- "$q",
- function($q) {
- var defer = $q.defer();
- var settings = null;
- return function cockpitKubeSettings() {
- if (settings !== null)
- return defer.promise;
- var channel = cockpit.channel({ payload: "dbus-json3", bus: "internal" });
- channel.addEventListener("close", function(ev, options) {
- if (options.problem) {
- console.warn("couldn't retrieve environment:", options.problem);
- defer.reject(options);
- } else {
- defer.resolve(settings);
- }
- });
- channel.addEventListener("message", function(ev, data) {
- var result = JSON.parse(data);
- if (result.reply) {
- settings = result.reply[0][0].Variables.v;
- channel.close(null);
- } else if (result.error) {
- console.warn("error retrieving environment:", result.error);
- channel.close("internal-error");
- }
- });
- channel.send(JSON.stringify({
- id: "cookie",
- call: [ "/environment", "org.freedesktop.DBus.Properties", "GetAll",
- [ "cockpit.Environment" ] ]
- }));
- return defer.promise;
- };
- }
- ])
-
- .factory("cockpitKubeDiscoverSettings", [
- "$q",
- "CockpitKubeRequest",
- "cockpitKubeDiscover",
- "CockpitEnvironment",
- 'kubeLoader',
- 'cockpitConnectionInfo',
- function($q, CockpitKubeRequest, cockpitKubeDiscover,
- CockpitEnvironment, loader, info) {
- var promise = null;
- return function kubeDiscoverSettings(force) {
- if (!force && promise)
- return promise;
-
- var settings = {
- registry: {
- host: "registry",
- host_explicit: false
- },
- flavor: "kubernetes",
- isAdmin: false,
- currentUser: null,
- canChangeConnection: false
- };
-
- var env_p = CockpitEnvironment()
- .then(function(result) {
- var regHost = result["REGISTRY_HOST"];
- if (regHost) {
- settings.registry.host = regHost;
- settings.registry.host_explicit = true;
- }
- var openshifthost = result["OPENSHIFT_OAUTH_PROVIDER_URL"];
- if (openshifthost) {
- settings.registry.openshifthost = openshifthost.replace(/^http(s?):\/\//i, "");
- settings.registry.openshifthost_explicit = true;
- }
- }, function(ex) {});
-
- var discover_p = cockpitKubeDiscover(force)
- .then(function(options) {
- var req = new CockpitKubeRequest("GET", "/oapi/v1/users/~", "", options)
- .then(function(response) {
- settings.flavor = "openshift";
- if (response)
- settings.currentUser = response.data;
- }, function () {
- settings.flavor = "kubernetes";
- });
-
- var watch = loader.watch("namespaces")
- .then(function () {
- settings.isAdmin = true;
- }, function () {
- settings.isAdmin = false;
- });
-
- var authorization;
- /* See if we have a bearer token to use */
- if (options.headers) {
- authorization = (options.headers['Authorization'] || "").trim();
- if (authorization.toLowerCase().indexOf("bearer ") === 0)
- settings.registry.password = authorization.substr(7).trim();
- }
- return $q.all([watch, req]);
- });
-
- promise = $q.all([discover_p, env_p])
- .then(function() {
- settings.canChangeConnection = info.type == "kubectl";
- return settings;
- });
-
- return promise;
- };
- }
- ])
-
- .factory("cockpitBrowserStorage", [
- "$window",
- function($window) {
- var base = $window;
- if (cockpit && cockpit.sessionStorage && cockpit.localStorage)
- base = cockpit;
-
- /* Some browsers fail localStorage access due to corruption, preventing Cockpit login */
- var localStorage;
- try {
- localStorage = base.localStorage;
- } catch (ex) {
- localStorage = base.sessionStorage;
- console.warn(String(ex));
- }
-
- return {
- sessionStorage: base.sessionStorage,
- localStorage: localStorage
- };
- }
- ])
-
- .factory('cockpitConnectionInfo', function () {
- return {
- type: null,
- kubeConfig: null,
- };
- })
-
- .factory('cockpitContainerWebSocket', [
- 'CockpitKubeSocket',
- 'CockpitKubectlWebSocket',
- 'cockpitConnectionInfo',
- function (socket, kubectlSocket, info) {
- return function(url, protocols) {
- /* config retrieved from kubectl? */
- if (info.type == "kubectl")
- return kubectlSocket(url, protocols);
- else
- return socket(url, { protocols: protocols });
- };
- }
- ])
-
- .factory('CockpitFormat', function() {
- return {
- formatBytes: cockpit.format_bytes,
- formatBitsPerSec: cockpit.format_bits_per_sec,
- format: cockpit.format
- };
- })
-
- .factory('CockpitMetrics', function() {
- return {
- grid: cockpit.grid,
- series: cockpit.series,
- };
- })
-
- .factory('CockpitTranslate', function() {
- return {
- gettext: cockpit.gettext,
- ngettext: cockpit.ngettext,
- };
- });
-}());
diff --git a/pkg/kubernetes/scripts/kube-client-mock.js b/pkg/kubernetes/scripts/kube-client-mock.js
deleted file mode 100644
index 4c614b2ec..000000000
--- a/pkg/kubernetes/scripts/kube-client-mock.js
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-var angular = require("angular");
-
-(function() {
- var kubeLast = 100;
-
- var kubeData = { };
- var handlers = [ ];
-
- function addNotify(handler) {
- handlers.push(handler);
- }
-
- function removeNotify(handler) {
- var i;
- var len = handlers.length;
- for (i = 0; i < len; i++) {
- if (handlers[i] === handler)
- handlers[i] = null;
- }
- }
-
- function dispatchNotify() {
- var i;
- var len = handlers.length;
- for (i = 0; i < len; i++) {
- if (handlers[i])
- handlers[i].apply(kubeData, arguments);
- }
- }
-
- function guid() {
- function s4() {
- return Math.floor((1 + Math.random()) * 0x10000)
- .toString(16)
- .substring(1);
- }
- return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
- s4() + '-' + s4() + s4() + s4();
- }
-
- function deparam(query) {
- var parsed = { };
- var vars = query.split("&");
- for (var i = 0; i < vars.length; i++) {
- var pair = vars[i].split("=");
- var k = decodeURIComponent(pair[0]);
- var v = decodeURIComponent(pair[1]);
- if (typeof parsed[k] === "undefined" ||
- typeof parsed[k] === "function") {
- if (k.substr(k.length - 2) != '[]')
- parsed[k] = v;
- else
- parsed[k] = [v];
- } else if (typeof parsed[k] === "string") {
- parsed[k] = v;
- } else {
- parsed[k].push(v);
- }
- }
-
- return parsed;
- }
-
- function kubeApiserver(req, defer) {
- var path;
- var query;
-
- var pos = req.path.indexOf('?');
- if (pos === -1) {
- path = req.path;
- query = { };
- } else {
- path = req.path.substring(0, pos);
- query = deparam(req.path.substring(pos + 1));
- }
-
- var parts = path.substring(1).split("/");
-
- /* The API check */
- if (parts.length == 1 && (parts[0] == "api" || parts[0] != "oapi")) {
- req.mockRespond(200, "OK", { }, JSON.stringify({
- versions: [ "v1" ]
- }));
- }
-
- if (parts[0] != "api" && parts[0] != "oapi" && parts[1] != "v1") {
- req.mockRespond(404, "Not API");
- return;
- }
-
- var baseUri = "/" + parts.slice(0, 2).join("/");
- parts = parts.slice(2);
-
- var ret = false;
- if (req.method === "POST") {
- ret = kubeApiPost(req, parts, query, baseUri);
- } else if (req.method === "PUT") {
- ret = kubeApiPut(req, parts, query, baseUri);
- } else if (req.method === "GET") {
- ret = kubeApiGet(req, parts, query, baseUri);
- } else if (req.method === "DELETE") {
- ret = kubeApiDelete(req, parts, query, baseUri);
- } else if (req.method === "PATCH") {
- ret = kubeApiPatch(req, parts, query, baseUri);
- } else {
- req.mockRespond(405, "Unsupported method");
- ret = true;
- }
-
- if (!ret)
- req.mockRespond(404, "Not found", { "Content-Type": "application/json" }, { code: 404, message: "Not found here" });
- }
-
- function kubeUpdate(key, object) {
- var type;
- if (!object) {
- if (kubeData[key]) {
- type = "DELETED";
- object = kubeData[key];
- delete kubeData[key];
- } else {
- return null;
- }
- } else {
- if (kubeData[key])
- type = "MODIFIED";
- else
- type = "ADDED";
- kubeData[key] = object;
- }
-
- if (!object.metadata)
- object.metadata = { };
- if (!object.metadata.uid)
- object.metadata.uid = guid();
- object.metadata.resourceVersion = kubeLast;
- kubeLast += 1;
-
- dispatchNotify(type, key, object);
- return object;
- }
-
- function kubeApiGet(req, parts, query, baseUri) {
- var resourceVersion = null;
- var namespaceRe = ".+";
-
- /* Figure out if this is a watch */
- var watch = false;
- if (query.hasOwnProperty("watch")) {
- watch = true;
- if (query.resourceVersion) {
- resourceVersion = parseInt(query.resourceVersion, 10);
- if (isNaN(resourceVersion))
- throw Error("invalid resourceVersion");
- }
- }
-
- /* Figure out if namespace api was used */
- var what = parts.shift();
- if (what == "namespaces" && parts.length > 1) {
- namespaceRe = parts.shift();
- what = parts.shift();
- }
-
- var specific = parts.join("/");
- var kind = null;
- var regexp = null;
-
- function prepare(key, object) {
- if (resourceVersion) {
- if (!object.metadata || !object.metadata.resourceVersion ||
- object.metadata.resourceVersion < resourceVersion)
- return null;
- }
- if (specific) {
- if (key != specific)
- return null;
- }
- if (regexp) {
- if (!key.match(regexp))
- return null;
- }
-
- var copy = JSON.parse(JSON.stringify(object));
- copy.metadata.selfLink = baseUri + "/" + key;
- copy.apiVersion = "v1";
- return copy;
- }
-
- /* Various lists */
- if (what == "namespaces") {
- regexp = /namespaces\/[a-z0-9-_]+$/;
- kind = "NamespaceList";
- } else if (what == "nodes") {
- regexp = /nodes\//;
- kind = "NodeList";
- } else if (what == "pods") {
- regexp = RegExp("namespaces/" + namespaceRe + "/pods/");
- kind = "PodList";
- } else if (what == "services") {
- regexp = RegExp("namespaces/" + namespaceRe + "/services/");
- kind = "ServiceList";
- } else if (what == "replicationcontrollers") {
- regexp = RegExp("namespaces/" + namespaceRe + "/replicationcontrollers/");
- kind = "ReplicationControllerList";
- } else if (what == "events") {
- regexp = RegExp("namespaces/" + namespaceRe + "/events/");
- kind = "EventList";
- } else if (what == "images") {
- req.mockRespond(404, "OK", { "Content-Type": "text/plain; charset=utf-8" });
- return;
- } else if (what == "imagestreams") {
- regexp = RegExp("namespaces/" + namespaceRe + "/imagestreams/");
- kind = "ImageStreamList";
- /* Nothing found */
- } else {
- return false;
- }
-
- function respondGet() {
- var items = [ ];
- var result = {
- kind: kind,
- creationTimestamp: null,
- items: items
- };
-
- angular.forEach(kubeData, function(value, key) {
- var object = prepare(key, value);
- if (object)
- items.push(object);
- });
-
- req.mockRespond(200, "OK", { "Content-Type": "application/json" }, JSON.stringify(result));
- return true;
- }
-
- function respondWatch() {
- req.mockRespond(200, "OK", { "Content-Type": "text/plain; charset=utf-8" }, null);
-
- var body = "";
- angular.forEach(kubeData, function(value, key) {
- var object = prepare(key, value);
- if (object)
- body += JSON.stringify({ type: "ADDED", object: object }) + "\n";
- });
-
- function streamWatch(type, key, value) {
- var object = prepare(key, value);
- if (object)
- req.mockData(JSON.stringify({ type: type, object: object }) + "\n", true);
- }
-
- addNotify(streamWatch);
- req.mockData(body, true);
-
- window.setTimeout(function() {
- removeNotify(streamWatch);
- req.mockData("", false);
- }, 5000);
-
- return true;
- }
-
- if (watch)
- return respondWatch();
- else
- return respondGet();
- }
-
- function kubeApiPost(req, parts, query, baseUri) {
- var section;
-
- if (parts.length === 3) {
- if (parts[0] != "namespaces")
- return false;
- section = parts[2];
- } else if (parts.length === 1) {
- section = parts[0];
- } else {
- return false;
- }
-
- var object;
- try {
- object = JSON.parse(req.body);
- } catch (ex) {
- req.mockRespond(400, "Bad JSON");
- return true;
- }
-
- var kind = object.kind;
- var meta = object.metadata || { };
- var name = meta.name;
-
- if (!kind || !meta || !name) {
- req.mockRespond(400, "Bad fields in JSON");
- return true;
- }
-
- if (kind.toLowerCase() + "s" != section) {
- req.mockRespond(400, "Bad section of URI");
- return true;
- }
-
- parts.push(name);
- var key = parts.join("/");
-
- if (kubeData[key]) {
- req.mockRespond(409, "Already exists", { "Content-Type": "application/json" },
- JSON.stringify({ code: 409, message: "Already exists" }));
- return true;
- }
-
- kubeUpdate(key, object);
- req.mockRespond(200, "OK", { "Content-Type": "application/json" }, JSON.stringify(object));
- return true;
- }
-
- function kubeApiPut(req, parts, query, baseUri) {
- var object;
- try {
- object = JSON.parse(req.body);
- } catch (ex) {
- req.mockRespond(400, "Bad JSON");
- return true;
- }
-
- var key = parts.join("/");
- kubeUpdate(key, object);
- req.mockRespond(200, "OK", { "Content-Type": "application/json" }, JSON.stringify(object));
- return true;
- }
-
- function kubeApiDelete(req, parts, query, baseUri) {
- if (parts.length === 4) {
- if (parts[0] != "namespaces")
- return false;
- } else if (parts.length !== 2) {
- return false;
- }
-
- var key = parts.join("/");
-
- var resp = kubeUpdate(key, null);
- req.mockRespond(200, "OK", { "Content-Type": "application/json" }, JSON.stringify(resp));
- return true;
- }
-
- function kubeApiPatch(req, parts, query, baseUri) {
- if (parts.length === 4) {
- if (parts[0] != "namespaces")
- return false;
- } else if (parts.length !== 2) {
- return false;
- }
-
- if (req.headers["Content-Type"] != "application/strategic-merge-patch+json") {
- req.mockRespond(400, "Bad Content Type");
- return true;
- }
-
- var key = parts.join("/");
- var patch;
- try {
- patch = JSON.parse(req.body);
- } catch (ex) {
- req.mockRespond(400, "Bad JSON");
- return true;
- }
-
- var data = angular.extend({ }, kubeData[key] || { }, patch);
- var resp = kubeUpdate(key, data);
- req.mockRespond(200, "OK", { "Content-Type": "application/json" }, JSON.stringify(resp));
- return true;
- }
-
- var unique = 0;
-
- angular.module("kubeClient.mock", [
- "kubeClient",
- ])
-
- .value("MockKubeData", {
- load: function load(data) {
- kubeData = JSON.parse(JSON.stringify(data));
- },
- update: kubeUpdate
- })
-
- .factory("MockKubeWatch", [
- "$q",
- "KUBE_SCHEMA",
- "MockKubeRequest",
- function($q, KUBE_SCHEMA, MockKubeRequest) {
- return function CockpitKubeWatch(path, callback) {
- var defer = $q.defer();
- var promise = defer.promise;
-
- unique += 1;
-
- var request = new MockKubeRequest("GET", path + "?watch=true", "", {
- streamer: handleStream,
- unique: unique,
- });
-
- var buffer;
- function handleStream(data, response) {
- if (buffer)
- data = buffer + data;
-
- var lines = data.split("\n");
- var i;
- var length = lines.length - 1;
-
- /* Last line is incomplete save for later */
- buffer = lines[length];
-
- /* Process all the others */
- var frame;
- var frames = [];
- for (i = 0; i < length; i++) {
- frame = JSON.parse(lines[i]);
- if (!frame.object)
- throw Error("invalid watch without object");
-
- /* The watch failed, likely due to invalid resourceVersion */
- if (frame.type == "ERROR")
- throw frame;
-
- frames.push(frame);
- }
-
- callback(frames);
-
- var df = defer;
- if (df) {
- callback([]);
- defer = null;
- df.resolve(response);
- }
- }
-
- request.then(function(response) {
- var df = defer;
- defer = null;
- if (df)
- df.resolve(response);
- }, function(response) {
- var df = defer;
- defer = null;
- if (df)
- df.reject(response);
- });
-
- promise.cancel = function cancel() {
- var df = defer;
- if (request)
- request.cancel();
- if (df) {
- defer = null;
- df.reject({
- status: 999,
- statusText: "Cancelled",
- problem: "cancelled",
- });
- }
- };
- return promise;
- };
- }
- ])
-
- .factory("MockKubeRequest", [
- "$q",
- function($q) {
- return function MockKubeRequest(method, path, data, config) {
- var req = angular.extend({ }, config, { method: method, path: path, body: data });
- var defer = $q.defer();
- var promise = defer.promise;
- var response;
- function finish() {
- var df = defer;
- defer = null;
- if (response.headers["Content-Type"] == "application/json")
- response.data = JSON.parse(response.data);
- if (response.status < 300)
- df.resolve(response);
- else
- df.reject(response);
- }
-
- req.mockRespond = function(status, reason, headers, body) {
- if (!defer)
- return;
- response = {
- status: status,
- statusText: reason,
- headers: headers || { },
- data: "",
- unique: req.unique,
- };
- if (body !== null)
- req.mockData(body || "", false);
- };
-
- req.mockData = function(body, stream) {
- if (!defer)
- return;
- if (typeof (body) !== "string")
- body = JSON.stringify(body);
- if (req.streamer)
- req.streamer(body, response);
- else
- response.data += body;
- if (!stream)
- finish();
- };
-
- promise.cancel = function cancel() {
- if (!defer)
- return;
- defer.reject({
- status: 999,
- statusText: "Cancelled",
- problem: "cancelled",
- });
- defer = null;
- };
-
- window.setTimeout(function() {
- kubeApiserver(req);
- });
-
- return promise;
- };
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/kube-client.js b/pkg/kubernetes/scripts/kube-client.js
deleted file mode 100644
index 833994b79..000000000
--- a/pkg/kubernetes/scripts/kube-client.js
+++ /dev/null
@@ -1,1582 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
-
- /*
- * Some notes on the create fields.
- *
- * Namespaces should be created first, as they must exist before objects in
- * them are created.
- *
- * Services should be created before pods (or replication controllers that
- * make pods. This is because of the environment variables that pods get
- * when they want to access a service.
- *
- * Create pods before replication controllers ... corner case, but keeps
- * things sane.
- */
-
- var KUBE = "/api/v1";
- var OPENSHIFT = "/oapi/v1";
- var DEFAULT = { api: KUBE, create: 0 };
- var SCHEMA = flatSchema([
- { kind: "DeploymentConfig", type: "deploymentconfigs", api: OPENSHIFT },
- { kind: "Endpoints", type: "endpoints", api: KUBE },
- { kind: "Group", type: "groups", api: OPENSHIFT, global: true },
- { kind: "Image", type: "images", api: OPENSHIFT, global: true },
- { kind: "ImageStream", type: "imagestreams", api: OPENSHIFT },
- { kind: "ImageStreamImage", type: "imagestreamimages", api: OPENSHIFT },
- { kind: "ImageStreamTag", type: "imagestreamtags", api: OPENSHIFT },
- { kind: "LocalResourceAccessReview", type: "localresourceaccessreviews", api: OPENSHIFT },
- { kind: "Namespace", type: "namespaces", api: KUBE, global: true, create: -100 },
- { kind: "Node", type: "nodes", api: KUBE, global: true },
- { kind: "Pod", type: "pods", api: KUBE, create: -20 },
- { kind: "PolicyBinding", type: "policybindings", api: OPENSHIFT },
- { kind: "RoleBinding", type: "rolebindings", api: OPENSHIFT },
- { kind: "Route", type: "routes", api: OPENSHIFT },
- { kind: "PersistentVolume", type: "persistentvolumes", api: KUBE, global: true, create: -100 },
- { kind: "PersistentVolumeClaim", type: "persistentvolumeclaims", api: KUBE, create: -50 },
- { kind: "Project", type: "projects", api: OPENSHIFT, global: true, create: -90 },
- { kind: "ProjectRequest", type: "projectrequests", api: OPENSHIFT, global: true, create: -90 },
- { kind: "ReplicationController", type: "replicationcontrollers", api: KUBE, create: -60 },
- { kind: "Service", type: "services", api: KUBE, create: -80 },
- { kind: "SubjectAccessReview", type: "subjectaccessreviews", api: OPENSHIFT },
- { kind: "User", type: "users", api: OPENSHIFT, global: true },
- ]);
-
- var NAME_RE = /^[a-z0-9]([-a-z0-9_.]*[a-z0-9])?$/;
- var USER_NAME_RE = /^[a-zA-Z0-9_.]([-a-zA-Z0-9 ,=@._:]*[a-zA-Z0-9._:])?$/;
-
- /* Timeout for non-GET requests */
- var REQ_TIMEOUT = "120s";
-
- function debug() {
- if (window.debugging == "all" || window.debugging == "kube")
- console.debug.apply(console, arguments);
- }
-
- function hash(str) {
- var h, i, chr, len;
- if (str.length === 0)
- return 0;
- for (h = 0, i = 0, len = str.length; i < len; i++) {
- chr = str.charCodeAt(i);
- h = ((h << 5) - h) + chr;
- h |= 0; // Convert to 32bit integer
- }
- return Math.abs(h);
- }
-
- function search(arr, val) {
- var low = 0;
- var high = arr.length - 1;
- var mid, v;
-
- while (low <= high) {
- mid = (low + high) / 2 | 0;
- v = arr[mid];
- if (v < val)
- low = mid + 1;
- else if (v > val)
- high = mid - 1;
- else
- return mid; /* key found */
- }
- return low;
- }
-
- /**
- * HashIndex
- *
- * A probablisting hash index, where items are added with
- * various keys, and probable matches are returned. Similar
- * to bloom filters, false positives are possible, but never
- * false negatives.
- */
- function HashIndex(size) {
- var self = this;
- var array = [];
-
- self.add = function add(keys, value) {
- var i, j, p, x;
- var length = keys.length;
- for (j = 0; j < length; j++) {
- i = hash("" + keys[j]) % size;
- p = array[i];
- if (p === undefined)
- p = array[i] = [];
- x = search(p, value);
- if (p[x] != value)
- p.splice(x, 0, value);
- }
- };
-
- self.get = function get(key) {
- var p = array[hash("" + key) % size];
- if (!p)
- return [];
- return p.slice();
- };
-
- self.all = function all(keys) {
- var i, j, p, result, n;
- var rl, rv, pv, ri, px;
-
- for (j = 0, n = keys.length; j < n; j++) {
- i = hash("" + keys[j]) % size;
- p = array[i];
-
- /* No match for this key, short cut out */
- if (!p) {
- result = [];
- break;
- }
-
- /* First key */
- if (!result) {
- result = p.slice();
-
- /* Calculate intersection */
- } else {
- for (ri = 0, px = 0, rl = result.length; ri < rl;) {
- rv = result[ri];
- pv = p[ri + px];
- if (pv < rv) {
- px += 1;
- } else if (rv !== pv) {
- result.splice(ri, 1);
- rl -= 1;
- } else {
- ri += 1;
- }
- }
- }
- }
-
- return result || [];
- };
- }
-
- /*
- * A WeakMap implementation
- *
- * This works on ES5 browsers, with the caveat that the mapped
- * items are discoverable with enough work.
- *
- * To be clear, the principal use of a WeakMap is to associate
- * an value with an object, the object is the key. And then have
- * that value go away when the object does. This is very, very
- * similar to properties.
- *
- * The main difference is that any assigned values are not
- * garbage collected if the *weakmap* itself is collected,
- * and of course one can actually access the non-enumerable
- * property that makes this work.
- */
-
- var weak_property = Math.random().toString(36)
- .slice(2);
- var local_seed = 1;
-
- function SimpleWeakMap() {
- var local_property = "weakmap" + local_seed;
- local_seed += 1;
-
- var self = this;
-
- self.delete = function delete_(obj) {
- var map = obj[weak_property];
- if (map)
- delete map[local_property];
- };
-
- self.has = function has(obj) {
- var map = obj[weak_property];
- return (map && local_property in map);
- };
-
- self.get = function has(obj) {
- var map = obj[weak_property];
- if (!map)
- return undefined;
- return map[local_property];
- };
-
- self.set = function set(obj, value) {
- var map = obj[weak_property];
- if (!map) {
- map = function WeakMapData() { };
- Object.defineProperty(obj, weak_property, {
- enumerable: false, configurable: false,
- writable: false, value: map,
- });
- }
-
- map[local_property] = value;
- };
- }
-
- function flatSchema(items) {
- var i, len;
- var ret = { "": DEFAULT };
- for (i = 0, len = items.length; i < len; i++) {
- ret[items[i].type] = items[i];
- ret[items[i].kind] = items[i];
- }
- return ret;
- }
-
- /*
- * Accepts:
- * 1. an object
- * 2. an involved object
- * 2. a path string
- * 3. type/kind, name, namespace
- */
- function resourcePath(args) {
- var one = args[0];
- if (one && typeof one === "object") {
- if (one.metadata) {
- /* An object with a link */
- if (one.metadata.selfLink)
- return one.metadata.selfLink;
-
- /* Pull out the arguments */
- args = [ one.kind, one.metadata.name, one.metadata.namespace ];
- } else if (one.name && one.kind) {
- /* An involved object */
- args = [ one.kind, one.name, one.namespace ];
- }
-
- /* Already a path */
- } else if (one && one[0] == '/') {
- return one;
- }
-
- /*
- * Combine into a path.
- */
- var schema = SCHEMA[args[0]] || SCHEMA[""];
- var path = schema.api;
- if (!schema.global && args[2])
- path += "/namespaces/" + args[2];
- path += "/" + schema.type;
- if (args[1])
- path += "/" + encodeURIComponent(args[1]);
-
- return path;
- }
-
- /*
- * Angular definitions start here
- */
-
- angular.module("kubeClient", [])
-
- /**
- * KUBE_SCHEMA
- *
- * A dict of schema information. The keys are both object types
- * and resource kinds. The values are objects with the following
- * properties:
- *
- * schema.kind The object kind
- * schema.type The resource type (ie: used in urls)
- * schema.api The api endpoint to use
- * schema.global Set to true if resource is not namespaced.
- */
-
- .value("KUBE_SCHEMA", SCHEMA)
-
- /**
- * KUBE_NAME_RE
- *
- * Regular Expression that names in kubernetes must match.
- */
- .value("KUBE_NAME_RE", NAME_RE)
-
- /**
- * kubeLoader
- *
- * Loads kubernetes objects either by watching them or loading
- * objects explicitly. The loaded objects are available at
- * the .objects property, although you probably want to
- * use kubeSelect() to interact with these objects.
- *
- * loader.handle(objects, [removed])
- *
- * Tell the loader about a objects that has been loaded
- * or removed elsewhere.
- *
- * loader.listen(callback, until)
- *
- * Register a callback to be invoked some time after new
- * objects have been loaded. Returns an object with a
- * .cancel() method, that can be used to stop listening.
- *
- * promise = loader.load(path)
- * promise = loader.load(involvedObject)
- * promise = loader.load(resource)
- * promise = loader.load(kind, [name], [namespace])
- *
- * Load the resource at the path. Returns a promise that will
- * resolve with the resource or an array of objects at the
- * given path.
- *
- * loader.limits
- *
- * Contains various limits that govern what the loader loads
- * from watches. Of note is loader.limits.namespace which is set
- * to null for the loader to load all objects, or a namespace
- * string or array of namespace strings for the loader to watch
- * objects from specific namespaces.
- *
- * loader.limit(options)
- *
- * Adjust the loader limits that govern what the loader loads
- * from watches. Options can contain a "namespace" field to
- * set the namespace or namespaces to limit watching to.
- *
- * loader.reset()
- *
- * Clear out all loaded objects, and clear all watches. Also
- * clears the limits and other state.
- *
- * loader.objects
- *
- * A dict of all loaded objects.
- *
- * promise = loader.watch(type, until)
- *
- * Start watching the given resource type. The returned promise
- * will be resolved when an initial set of objects have been
- * loaded for the watch, or rejected if the watch has failed.
- */
-
- .factory("kubeLoader", [
- "$q",
- "$timeout",
- "KubeWatch",
- "KubeRequest",
- "KUBE_SCHEMA",
- function($q, $timeout, KubeWatch, KubeRequest, KUBE_SCHEMA) {
- var self;
-
- var callbacks = [];
- var limits = { namespace: null };
-
- /* All the current watches */
- var watching = { };
-
- /* All the loaded objects */
- var objects = { };
-
- /* Timeout batching */
- var batch = null;
- var batchTimeout = null;
-
- function ensureWatch(what, namespace, increment) {
- var schema = SCHEMA[what] || SCHEMA[""];
- var watch;
- var path = schema.api;
- if (!schema.global && namespace)
- path += "/namespaces/" + namespace;
- path += "/" + schema.type;
-
- if (!(path in watching)) {
- watch = new KubeWatch(path, handleFrames);
- watch.what = what;
- watch.global = schema.global;
- watch.namespace = namespace;
- watch.cancelWatch = watch.cancel;
-
- /* Replace the cancel function with one that does ref counting */
- watch.cancel = function() {
- var w = watching[path];
- if (w) {
- w.references -= 1;
- if (w.references <= 0) {
- w.cancelWatch();
- delete watching[path];
- }
- }
- };
- watching[path] = watch;
- }
-
- /* Increase the references here */
- watching[path].references += increment;
- return watching[path];
- }
-
- function ensureWatches(what, increment) {
- var namespace = limits.namespace;
- if (!angular.isArray(namespace))
- return ensureWatch(what, namespace, increment);
-
- var parts = [];
- angular.forEach(namespace, function(val) {
- parts.push(ensureWatch(what, val, increment));
- });
- var ret = $q.all(parts);
- ret.cancel = function() {
- angular.forEach(parts, function(val) {
- val.cancel();
- });
- };
- return ret;
- }
-
- function handleFrames(frames) {
- if (batch === null)
- batch = frames;
- else
- batch.push.apply(batch, frames);
-
- /* When called with empty data, flush, don't wait */
- if (frames.length > 0) {
- if (batchTimeout === null)
- batchTimeout = window.setTimeout(handleTimeout, 150);
- else
- return; /* called again later */
- }
-
- handleFlush(invokeCallbacks);
- }
-
- function resourceVersion(resource) {
- var version;
- if (resource && resource.metadata)
- version = parseInt(resource.metadata.resourceVersion, 10);
-
- if (!isNaN(version))
- return version;
- }
-
- function handleFlush(invoke) {
- var drain = batch;
- batch = null;
-
- if (!drain)
- return;
-
- var present = { };
- var removed = { };
- var i, len, link, resource;
- var cVersion, lVersion;
- for (i = 0, len = drain.length; i < len; i++) {
- resource = drain[i].object;
- if (resource) {
- link = decodeURIComponent(resourcePath([resource]));
- if (drain[i].type == "DELETED") {
- delete objects[link];
- delete present[link];
- removed[link] = resource;
- } else if (drain[i].checkResourceVersion) {
- /* There is a race between items loaded from
- * watchers and items loaded other ways such as
- * from KubeMethods callbacks, where we might
- * end up saving the older item if loader.load is
- * called after the watcher has already loaded fresher
- * data. Look at the resourceVersion and only add
- * if it is the same or newer than what we already have.
- */
- cVersion = resourceVersion(resource);
- lVersion = resourceVersion(objects[link]);
- if (!cVersion || !lVersion || cVersion >= lVersion) {
- present[link] = resource;
- objects[link] = resource;
- }
- } else {
- present[link] = resource;
- objects[link] = resource;
- }
- }
- }
-
- /* Run all the listeners and then digest */
- invoke(present, removed);
- }
-
- function invokeCallbacks(/* ... */) {
- var i, len, func;
- for (i = 0, len = callbacks.length; i < len; i++) {
- func = callbacks[i];
- if (func)
- func.apply(self, arguments);
- }
- }
-
- function handleTimeout() {
- batchTimeout = null;
- handleFlush(invokeCallbacks);
- }
-
- function resetLoader() {
- var link;
-
- /* We drop any batched objects in flight */
- window.clearTimeout(batchTimeout);
- batchTimeout = null;
- batch = null;
-
- /* Cancel all the watches */
- var old = watching;
- watching = { };
- angular.forEach(old, function(w) {
- w.cancelWatch();
- });
-
- /* Clear out everything */
- for (link in objects)
- delete objects[link];
-
- for (link in limits)
- delete limits[link];
- limits.namespace = null;
-
- /* Tell the callbacks we're resetting */
- invokeCallbacks();
- }
-
- function handleObjects(objects, removed, kind) {
- handleFrames(objects.map(function(resource) {
- if (kind)
- resource.kind = kind;
-
- return {
- type: removed ? "DELETED" : "ADDED",
- object: resource,
- checkResourceVersion: true
- };
- }));
- handleFlush(invokeCallbacks);
- }
-
- function loadObjects(/* ... */) {
- var path = resourcePath(arguments);
- var req = new KubeRequest("GET", path);
- var promise = req.then(function(response) {
- req = null;
- var resource = response.data;
- if (!resource || !resource.kind) {
- return null;
- } else if (resource.kind.indexOf("List") === resource.kind.length - 4) {
- handleObjects(resource.items, false, resource.kind.slice(0, -4));
- return resource.items;
- } else {
- handleObjects([resource]);
- return resource;
- }
- }, function(response) {
- req = null;
- var resp = response.data;
- return $q.reject(resp || response);
- });
- promise.cancel = function cancel(ex) {
- req.cancel(ex);
- };
- return promise;
- }
-
- function adjustNamespace(value) {
- window.clearTimeout(batchTimeout);
- batchTimeout = null;
-
- /* Convert this to our native format */
- var only = { };
- if (value === null) {
- only = null;
- } else if (angular.isArray(value)) {
- angular.forEach(value, function(namespace) {
- only[namespace] = true;
- });
- } else {
- only[value] = true;
- }
- limits.namespace = value;
-
- /* Flush everything that's outstanding */
- var present = { };
- var removed = { };
- handleFlush(function(a, b) {
- present = a;
- removed = b;
- });
-
- /* Remove objects that are not in these namespaces */
- var meta, link;
- for (link in objects) {
- meta = objects[link].metadata;
- if (only && meta.namespace && !(meta.namespace in only)) {
- removed[link] = objects[link];
- delete objects[link];
- delete present[link];
- }
- }
-
- /* Cancel any watches not applicable to these namespaces */
- var path, w;
- var reconnect = [ ];
- for (path in watching) {
- w = watching[path];
- if ((!only && w.namespace) || (only && !w.global && !(w.namespace in only))) {
- w.cancelWatch();
- delete watching[path];
- reconnect.push(w);
- }
- }
-
- /* Tell the world what we did */
- invokeCallbacks(present, removed);
-
- /* Reconnect all the watches we cancelled with proper namespace */
- angular.forEach(reconnect, function(w) {
- ensureWatches(w.what, w.references);
- });
- }
-
- function connectUntil(ret, until) {
- if (until) {
- if (until.$on) {
- until.$on("$destroy", function() {
- ret.cancel();
- });
- } else {
- console.warn("invalid until passed to watch", until);
- }
- }
- }
-
- self = {
- watch: function watch(what, until) {
- var ret = ensureWatches(what, 1);
- connectUntil(ret, until);
- return ret;
- },
- load: function load(/* ... */) {
- return loadObjects.apply(this, arguments);
- },
- limit: function limit(options) {
- if ("namespace" in options)
- adjustNamespace(options.namespace);
- },
- reset: resetLoader,
- listen: function listen(callback, until) {
- if (callback.early)
- callbacks.unshift(callback);
- else
- callbacks.push(callback);
- var timeout = $timeout(function() {
- timeout = null;
- callback.call(self, objects);
- }, 0);
- var ret = {
- cancel: function() {
- var i, len;
- $timeout.cancel(timeout);
- timeout = null;
- for (i = 0, len = callbacks.length; i < len; i++) {
- if (callbacks[i] === callback)
- callbacks[i] = null;
- }
- }
- };
- connectUntil(ret, until);
- return ret;
- },
- handle: function handle(objects, removed, kind) {
- if (!angular.isArray(objects))
- objects = [ objects ];
- handleObjects(objects, removed, kind);
- },
- resolve: function resolve(/* ... */) {
- return resourcePath(arguments);
- },
- objects: objects,
- limits: limits,
- };
-
- return self;
- }
- ])
-
- /**
- * kubeSelect
- *
- * Allows selecting loaded objects based on various criteria. The
- * goal here is to allow selection to be fast enough that it can be
- * done repeatedly and regularly, without keeping caches of objects
- * all over the place.
- *
- * Resources may be filtered in a chain by calling various filter
- * functions. Lets start with an example that finds a pod:
- *
- * pod = kubeSelect()
- * .kind("Pod")
- * .namespace("default")
- * .name("docker-registry")
- * .one();
- *
- * Calling kubeSelect() will return a dict with all loaded objects,
- * containing unique keys, and then various filters can be called to
- * further narrow results.
- *
- * You can also pass a dict of objects into kubeSelect() and then
- * perform actions on it.
- *
- * The following filters are available by default:
- *
- * .kind(kind) Limit to specified kind
- * .namespace(ns) Limit to specified namespace
- * .name(name) Limit to this name
- * .host(name) Limit to this host
- * .label(selector) Limit to objects whose label match selector
- * .one() Choose one of results, or null
- * .extend(obj) Extend obj with the results
- *
- * Additional filters can be registered by calling the function:
- *
- * kubeSelect.register(name, function)
- * kubeSelect.register(filterobj)
- *
- * Ask on FreeNode #cockpit for documentation on filters.
- */
-
- .factory("kubeSelect", [
- "kubeLoader",
- function(loader) {
- /* A list of all registered filters */
- var filters = { };
-
- /* A hash index */
- var index = null;
-
- /* The filter prototype for functions available on selector */
- var proto = null;
-
- /* Cache data */
- var weakmap = new SimpleWeakMap();
- var version = 1;
-
- function listener(present, removed) {
- version += 1;
-
- /* Get called like this when reset */
- if (!present) {
- index = null;
-
- /* Called like this when more objects arrive */
- } else if (index) {
- indexObjects(present);
- }
- }
-
- listener.early = true;
- loader.listen(listener);
-
- /* Create a new index and populate */
- function indexCreate() {
- /* TODO: Derive this value from cluster size */
- index = new HashIndex(262139);
-
- /* And index all the objects */
- indexObjects(loader.objects);
- }
-
- /* Populate index for the given objects and current filters */
- function indexObjects(objects) {
- var link, object, name, key, keys, filter;
- for (link in objects) {
- object = objects[link];
- for (name in filters) {
- filter = filters[name];
- if (filter.digest) {
- key = filter.digest.call(null, object);
- if (key)
- index.add([ key ], link);
- } else if (filter.digests) {
- keys = filter.digests.call(null, object);
- if (keys.length)
- index.add(keys, link);
- }
- }
- }
- }
-
- /* Return a place to cache data related to obj */
- function cached(obj) {
- var data = weakmap.get(obj);
- if (!data || data.version !== version) {
- data = { version: version, length: data ? data.length : undefined };
- weakmap.set(obj, data);
- }
- return data;
- }
-
- function makePrototypeCall(filter) {
- return function() {
- var cache = cached(this);
-
- /*
- * Do this early, since some browsers cannot pass
- * arguments to JSON.stringify()
- */
- var args = Array.prototype.slice.call(arguments);
-
- /* Fast path, already calculated results */
- var desc = filter.name + ": " + JSON.stringify(args);
- if (desc in cache)
- return cache[desc];
-
- var results;
- if (filter.filter) {
- results = filter.filter.apply(this, args);
- } else {
- if (!index)
- indexCreate();
- if (!cache.indexed) {
- indexObjects(this);
- cache.indexed = true;
- }
- if (filter.digests) {
- results = digestsFilter(filter, this, args);
- } else if (filter.digest) {
- results = digestFilter(filter, this, args);
- } else {
- console.warn("invalid filter: " + filter.name);
- results = { };
- }
- }
-
- cache[desc] = results;
- return results;
- };
- }
-
- function makePrototype() {
- var name;
- var ret = {
- length: {
- enumerable: false,
- configurable: true,
- get: function() { return cached(this).length }
- }
- };
- for (name in filters) {
- ret[name] = {
- enumerable: false,
- configurable: true,
- value: makePrototypeCall(filters[name])
- };
- }
- return ret;
- }
-
- function mixinSelection(results, length, indexed) {
- var data;
- if (length === undefined)
- length = Object.keys(results).length;
- proto = proto || makePrototype();
- Object.defineProperties(results, proto);
- data = cached(results);
- data.length = length;
- data.selection = results;
- data.indexed = indexed;
- return results;
- }
-
- function digestFilter(filter, what, criteria) {
- var p, pl, key, possible, link, object;
- var results = { };
- var count = 0;
-
- key = filter.digest.apply(null, criteria);
- if (key !== null && key !== undefined) {
- possible = index.get(key);
- } else {
- possible = [];
- }
-
- for (p = 0, pl = possible.length; p < pl; p++) {
- link = possible[p];
- object = what[link];
- if (object) {
- if (key === filter.digest.call(null, object)) {
- results[link] = object;
- count += 1;
- }
- }
- }
-
- return mixinSelection(results, count, true);
- }
-
- function digestsFilter(filter, what, criteria) {
- var keys, keyn, keyo, k, link, match, object, possible;
- var p, pl, j, jl;
- var results = { };
- var count = 0;
-
- keys = filter.digests.apply(null, criteria);
- keyn = keys.length;
- if (keyn > 0) {
- possible = index.all(keys);
- keys.sort();
- } else {
- possible = [];
- }
-
- for (p = 0, pl = possible.length; p < pl; p++) {
- link = possible[p];
- object = what[link];
- if (object) {
- keyo = filter.digests.call(null, object);
- keyo.sort();
- match = false;
-
- /* Search for first key */
- for (j = 0, jl = keyo.length; !match && j < jl; j++) {
- if (keys[0] === keyo[j]) {
- match = true;
- for (k = 0; match && k < keyn; k++) {
- if (keys[k] !== keyo[j + k])
- match = false;
- }
- }
- }
-
- if (match) {
- results[link] = object;
- count += 1;
- }
- }
- }
-
- return mixinSelection(results, count, true);
- }
-
- function registerFilter(filter, optional) {
- if (typeof (optional) == "function") {
- filter = {
- name: filter,
- filter: optional,
- };
- }
-
- filters[filter.name] = filter;
- index = null;
- proto = null;
- version += 1;
- }
-
- /* The one filter */
- registerFilter("one", function() {
- var link;
- for (link in this)
- return this[link];
- return null;
- });
-
- /* The extend filter */
- registerFilter("extend", function(target) {
- var link;
- for (link in this)
- target[link] = this[link];
- return target;
- });
-
- /* The label filter */
- registerFilter({
- name: "label",
- digests: function(arg) {
- var ret = [];
- if (!arg)
- return ret;
- var i;
- var meta = arg.metadata;
- var labels = meta ? meta.labels : arg;
- for (i in labels || [])
- ret.push(i + "=" + labels[i]);
- return ret;
- }
- });
-
- /* The namespace filter */
- registerFilter({
- name: "namespace",
- digest: function(arg) {
- if (!arg)
- return null;
- if (typeof arg === "string")
- return arg;
- var meta = arg.metadata;
- return meta ? meta.namespace : null;
- }
- });
-
- /* The name filter */
- registerFilter({
- name: "name",
- digest: function(arg) {
- if (!arg)
- return null;
- if (typeof arg === "string")
- return arg;
- var meta = arg.metadata;
- return meta ? meta.name : null;
- }
- });
-
- /* The kind filter */
- registerFilter({
- name: "kind",
- digest: function(arg) {
- if (!arg)
- return null;
- if (typeof arg === "string")
- return arg;
- return arg.kind;
- }
- });
-
- /* The host filter */
- registerFilter({
- name: "host",
- digest: function(arg) {
- if (!arg)
- return null;
- if (typeof arg === "string")
- return arg;
- var spec = arg.spec;
- return spec ? spec.nodeName : null;
- }
- });
-
- /* The namespace filter */
- registerFilter({
- name: "uid",
- digest: function(arg) {
- if (!arg)
- return null;
- if (typeof arg === "string")
- return arg;
- var meta = arg.metadata;
- return meta ? meta.uid : null;
- }
- });
-
- /* The statusPhase filter */
- registerFilter({
- name: "statusPhase",
- digest: function(arg) {
- var status;
- if (typeof arg == "string") {
- return arg;
- } else {
- status = arg.status || { };
- return status.phase ? status.phase : null;
- }
- }
- });
-
- var empty = { };
-
- function select(arg) {
- var cache;
- var indexed = false;
- if (arg === undefined) {
- arg = loader.objects;
- indexed = true;
- } else if (!arg) {
- arg = empty;
- }
-
- /* Next the specific object */
- if (typeof arg !== "object") {
- console.warn("Pass resources or resource dicts or null to kubeSelect()");
- arg = empty;
- }
-
- cache = cached(arg);
- if (cache.selection)
- return cache.selection;
-
- /* A single resource object */
- var meta, single;
- if (typeof arg.kind === "string") {
- if (!cache.single) {
- meta = arg.meta || { };
- single = { };
- single[meta.selfLink || 1] = arg;
- cache.single = mixinSelection(single, undefined, false);
- }
- return cache.single;
- }
-
- return mixinSelection(arg, undefined, indexed);
- }
-
- /* A seldom used 'static' method */
- select.register = registerFilter;
-
- return select;
- }
- ])
-
- /**
- * kubeMethods
- *
- * Methods that operate on kubernetes objects.
- *
- * promise = methods.create(objects, namespace)
- *
- * Create the given resource or objects in the specified namespace.
- *
- * promise = methods.remove(resource)
- * promise = methods.remove(path)
- * promise = methods.remove(type, name, namespace)
- *
- * Delete the given resource from kubernetes.
- */
- .factory("kubeMethods", [
- "$q",
- "KUBE_SCHEMA",
- "KubeRequest",
- "kubeLoader",
- function($q, KUBE_SCHEMA, KubeRequest, loader) {
- function createCompare(a, b) {
- var sa = KUBE_SCHEMA[a.kind].create || 0;
- var sb = KUBE_SCHEMA[b.kind].create || 0;
- return sa - sb;
- }
-
- function createObjects(objects, namespace) {
- var defer = $q.defer();
- var promise = defer.promise;
- var request = null;
-
- if (!angular.isArray(objects)) {
- if (objects.kind == "List")
- objects = objects.items;
- else
- objects = [ objects ];
- }
-
- var haveNs = false;
- var wantNs = false;
-
- objects.forEach(function(resource) {
- var meta = resource.metadata || { };
- if ((resource.kind == "Namespace" || resource.kind == "Project") && meta.name === namespace)
- haveNs = true;
- var schema = SCHEMA[resource.kind] || SCHEMA[""];
- if (!schema.global)
- wantNs = true;
- });
-
- /* Shallow copy of the array, we modify it below */
- objects = objects.slice();
-
- /* Create the namespace */
- if (namespace && wantNs && !haveNs) {
- objects.unshift({
- apiVersion : "v1",
- kind : "Namespace",
- metadata : { name: namespace }
- });
- }
-
- /* Now sort the array with create preference */
- objects.sort(createCompare);
-
- function step() {
- var resource = objects.shift();
- if (!resource) {
- defer.resolve();
- return;
- }
-
- var path = resourcePath([resource.kind, null, namespace || "default"]);
- path += "?timeout=" + REQ_TIMEOUT;
-
- request = new KubeRequest("POST", path, JSON.stringify(resource))
- .then(function(response) {
- var meta;
-
- debug("created resource:", path, response.data);
- if (response.data.kind) {
- /* HACK: https://github.com/openshift/origin/issues/8167 */
- if (response.data.kind == "Project") {
- meta = response.data.metadata || { };
- delete meta.selfLink;
- }
- loader.handle(response.data);
- }
- step();
- }, function(response) {
- var resp = response.data;
- var code = response.status;
- if (resp && resp.code)
- code = resp.code;
-
- /* Ignore failures creating the namespace if it already exists */
- if (resource.kind == "Namespace" && (code === 409 || code === 403)) {
- debug("skipping namespace creation");
- step();
- } else {
- debug("create failed:", path, resp || response);
- defer.reject(resp || response);
- }
- });
- }
-
- step();
-
- promise.cancel = function cancel() {
- if (request)
- request.cancel();
- };
- return promise;
- }
-
- function deleteResource(/* ... */) {
- var path = resourcePath(arguments);
- var resource = loader.objects[path];
- path += "?timeout=" + REQ_TIMEOUT;
- var promise = new KubeRequest("DELETE", path);
- return promise.then(function() {
- debug("deleted resource:", path, resource);
- if (resource)
- loader.handle(resource, true);
- }, function(response) {
- var resp = response.data;
- return $q.reject(resp || response);
- });
- }
-
- function patchResource(resource, patch) {
- var path = resourcePath([resource]);
- path += "?timeout=" + REQ_TIMEOUT;
- var body = JSON.stringify(patch);
- var config = { headers: { "Content-Type": "application/strategic-merge-patch+json" } };
- var promise = new KubeRequest("PATCH", path, body, config);
- return promise.then(function(response) {
- debug("patched resource:", path, response.data);
- if (response.data.kind)
- loader.handle(response.data);
- }, function(response) {
- var resp = response.data;
- return $q.reject(resp || response);
- });
- }
-
- function generalMethodRequest(method, resource, body, config) {
- var path = resourcePath([resource]);
- if (method != "GET")
- path += "?timeout=" + REQ_TIMEOUT;
- var promise = new KubeRequest(method, path, JSON.stringify(body), config);
- return promise.then(function(response) {
- var resp = response.data;
- return resp || response;
- }, function(response) {
- var resp = response.data;
- return $q.reject(resp || response);
- });
- }
-
- function putResource(resource, body, config) {
- return generalMethodRequest("PUT", resource, body, config);
- }
-
- function postResource(resource, body, config) {
- return generalMethodRequest("POST", resource, body, config);
- }
-
- function checkResource(resource, targets) {
- var defer = $q.defer();
- var ex;
- var exs = [];
-
- if (!targets)
- targets = { };
-
- /* Some simple metadata checks */
- var meta = resource.metadata;
- if (meta) {
- ex = null;
- if (meta.name !== undefined) {
- var check_re = (resource.kind == "User" || resource.kind == "Group") ? USER_NAME_RE : NAME_RE;
- if (!meta.name)
- ex = new Error("The name cannot be empty");
- else if (!check_re.test(meta.name))
- if (check_re == NAME_RE) {
- ex = new Error("The name contains invalid characters. Only letters, numbers and dashes are allowed");
- } else {
- ex = new Error("The name contains invalid characters. Only letters, numbers, spaces and the following symbols are allowed: , = @ . _ - :");
- }
- }
- if (ex) {
- ex.target = targets["metadata.name"];
- exs.push(ex);
- }
-
- ex = null;
- if (meta.namespace !== undefined) {
- if (!meta.namespace)
- ex = new Error("The namespace cannot be empty");
- else if (!NAME_RE.test(meta.namespace))
- ex = new Error("The name contains invalid characters. Only letters, numbers and dashes are allowed");
- }
- if (ex) {
- ex.target = targets["metadata.namespace"];
- exs.push(ex);
- }
- }
-
- if (exs.length)
- defer.reject(exs);
- else
- defer.resolve();
- return defer.promise;
- }
-
- return {
- "create": createObjects,
- "delete": deleteResource,
- "check": checkResource,
- "patch": patchResource,
- post: postResource,
- put: putResource,
- };
- }
- ])
-
- /**
- * KubeRequest
- *
- * Create a new low level kubernetes request. These are instantiated
- * by kubeLoader or kubeMethods, and typically not used directly.
- *
- * An implementation of KubeRequest must be provided. It has the
- * following characteristics.
- *
- * promise = KubeRequest(method, path, [body, [config]])
- *
- * Creates a new request, for the given HTTP method and path. If body
- * is present it will be sent as the request body. If it an object or
- * array it will be encoded as JSON before being sent.
- *
- * If present the config object may include the following properties:
- *
- * headers An dict of headers to include
- *
- * In addition the config object can include implementation specific
- * settings or data.
- *
- * If successful the promise will resolve with a response object that
- * includes the following:
- *
- * status Status code
- * statusText Status reason or message
- * data Response body, JSON decoded if response is json
- * headers Response headers
- *
- * Implementation specific fields may also be present
- */
-
- .provider("KubeRequest", [
- function() {
- var self = this;
-
- /* Until we come up with a good default implementation, must be provided */
- self.KubeRequestFactory = "MissingKubeRequest";
-
- function load(injector, name) {
- if (angular.isString(name))
- return injector.get(name, "KubeRequest");
- else
- return injector.invoke(name);
- }
-
- self.$get = [
- "$injector",
- function($injector) {
- return load($injector, self.KubeRequestFactory);
- }
- ];
- }
- ])
-
- .factory("MissingKubeRequest", [
- function() {
- return function MissingKubeRequest(path, callback) {
- throw new Error("no KubeRequestFactory set");
- };
- }
- ])
-
- /**
- * KubeSocket
- *
- * Create a new low level kubernetes websocket request
- *
- * An implementation of KubeSocket must be provided. It has the
- * following characteristics.
- *
- * ws = KubeSocket(path, [config])
- *
- * Creates a new websocket request, for the given path.
- *
- * headers An dict of headers to include
- * protocals An list or string of websocket protocols
- *
- * In addition the config object can include implementation specific
- * settings or data.
- *
- * A object is returned that implements the Web API
- * Websocket interface. Specifically it should
- * expose a 'readyState' attribute, provide
- * open and close functions, and emit open, close and
- * message events.
- *
- * Implementation specific fields may also be present
- */
-
- .provider("KubeSocket", [
- function() {
- var self = this;
-
- /* Until we come up with a good default implementation, must be provided */
- self.KubeSocketFactory = "MissingKubeSocket";
-
- function load(injector, name) {
- if (angular.isString(name))
- return injector.get(name, "KubeSocket");
- else
- return injector.invoke(name);
- }
-
- self.$get = [
- "$injector",
- function($injector) {
- return load($injector, self.KubeSocketFactory);
- }
- ];
- }
- ])
-
- .factory("MissingKubeSocket", [
- function() {
- return function MissingKubeSocket(path, callback) {
- throw Error("no KubeSocketFactory set");
- };
- }
- ])
-
- /**
- * KubeWatch
- *
- * Create a new low level kubernetes watch. These are instantiated
- * by kubeLoader, and typically not used directly.
- *
- * An implementation of the KubeWatch must be provided. It has the
- * following characteristics:
- *
- * promise = KubeWatch(path, callback)
- *
- * The watch is given two arguments. The first is the kube resource
- * url to watch (without query string) a callback to invoke with
- * watch frames.
- *
- * The watch returns a deferred promise which will resolve when the initial
- * set of items has loaded, it will fail if the watch fails. The promise
- * should also have a promise.cancel() method which is invoked when the
- * watch should be stopped.
- *
- * callback(frames)
- *
- * The callback is invoked with an array of kubernetes watch frames that
- * look like: { type: "ADDED", object: { ... } }
- */
-
- .provider("KubeWatch", [
- function() {
- var self = this;
-
- /* Until we come up with a good default implementation, must be provided */
- self.KubeWatchFactory = "MissingKubeWatch";
-
- function load(injector, name) {
- if (angular.isString(name))
- return injector.get(name, "KubeWatch");
- else
- return injector.invoke(name);
- }
-
- self.$get = [
- "$injector",
- function($injector) {
- return load($injector, self.KubeWatchFactory);
- }
- ];
- }
- ])
-
- .factory("MissingKubeWatch", [
- function() {
- return function MissingKubeWatch(path, callback) {
- throw Error("no KubeWatchFactory set");
- };
- }
- ])
-
- .provider("KubeDiscoverSettings", [
- function() {
- var self = this;
-
- /* Until we come up with a good default implementation, must be provided */
- self.KubeDiscoverSettingsFactory = "MissingKubeDiscoverSettings";
-
- function load(injector, name) {
- if (angular.isString(name))
- return injector.get(name, "KubeDiscoverSettings");
- else
- return injector.invoke(name);
- }
-
- self.$get = [
- "$injector",
- function($injector) {
- return load($injector, self.KubeDiscoverSettingsFactory);
- }
- ];
- }
- ])
-
- .factory("MissingKubeDiscoverSettings", [
- function() {
- return function MissingKubeDiscoverSettings(path, callback) {
- throw Error("no KubeDiscoverSettingsFactory set");
- };
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/listing.js b/pkg/kubernetes/scripts/listing.js
deleted file mode 100644
index 0a2a5ccfb..000000000
--- a/pkg/kubernetes/scripts/listing.js
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
-
- require('../views/user-panel.html');
- require('../views/service-panel.html');
- require('../views/pod-panel.html');
- require('../views/route-panel.html');
- require('../views/pv-panel.html');
- require('../views/default-panel.html');
- require('../views/node-panel.html');
- require('../views/project-panel.html');
- require('../views/container-panel.html');
- require('../views/deploymentconfig-panel.html');
- require('../views/group-panel.html');
- require('../views/replicationcontroller-panel.html');
-
- function inClassOrTag(el, cls, tag) {
- return (el && el.classList && el.classList.contains(cls)) ||
- (el && el.tagName === tag) ||
- (el && inClassOrTag(el.parentNode, cls, tag));
- }
-
- angular.module('kubernetes.listing', [])
-
- .directive('listingTable', [
- function() {
- return {
- restrict: 'A',
- link: function(scope, element, attrs) {
- }
- };
- }
- ])
-
- .factory('ListingState', [
- function() {
- return function ListingState(scope) {
- var self = this;
- var data = { };
-
- self.selected = { };
- self.enableActions = false;
-
- /* Check that either .btn or li were not clicked */
- function checkBrowserEvent(ev) {
- return !(ev && inClassOrTag(ev.target, "btn", "li"));
- }
-
- self.hasSelected = function hasSelected(id) {
- return !angular.equals({}, self.selected);
- };
-
- self.expanded = function expanded(id) {
- if (angular.isUndefined(id)) {
- for (id in data)
- return true;
- return false;
- } else {
- return id in data;
- }
- };
-
- self.toggle = function toggle(id, ev) {
- var value;
- if (self.enableActions) {
- ev.stopPropagation();
- return;
- }
-
- if (id) {
- value = !(id in data);
- if (value)
- self.expand(id, ev);
- else
- self.collapse(id, ev);
- }
- };
-
- self.expand = function expand(id, ev) {
- data[id] = true;
- if (ev)
- ev.stopPropagation();
- };
-
- self.activate = function activate(id, ev) {
- if (checkBrowserEvent(ev)) {
- if (self.expanded(id))
- self.collapse(id);
- else
- scope.$emit("activate", id);
- }
- };
-
- self.collapse = function collapse(id, ev) {
- if (id) {
- delete data[id];
- } else {
- Object.keys(data).forEach(function(old) {
- delete data[old];
- });
- }
- if (ev)
- ev.stopPropagation();
- };
- };
- }
- ])
-
- .directive('listingPanel', [
- function() {
- return {
- restrict: 'A',
- scope: true,
- link: function(scope, element, attrs) {
- var tab = 'main';
- scope.tab = function(name, ev) {
- if (ev) {
- tab = name;
- ev.stopPropagation();
- }
- return tab === name;
- };
- },
- templateUrl: function(element, attrs) {
- var kind = attrs.kind;
- return "views/" + kind.toLowerCase() + "-panel.html";
- }
- };
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/main.js b/pkg/kubernetes/scripts/main.js
deleted file mode 100644
index 0c141ffa7..000000000
--- a/pkg/kubernetes/scripts/main.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- /* Tell webpack what to bundle here */
- var angular = require('angular');
- require('angular-route');
- require('angular-gettext/dist/angular-gettext.js');
- require('angular-bootstrap-npm/dist/angular-bootstrap.js');
- require('kubernetes-container-terminal/dist/container-terminal.js');
- require('object-describer/dist/object-describer.js');
- require('kubernetes-object-describer/dist/object-describer.js');
-
- /* The kubernetes client */
- require('./kube-client');
- require('./kube-client-cockpit');
-
- /* The other angular modules */
- require('./containers');
- require('./dashboard');
- require('./details');
- require('./graphs');
- require('./policy');
- require('./projects');
- require('./images');
- require('./nodes');
- require('./topology');
- require('./volumes');
-
- /* And the actual application */
- require('./app');
-
- angular.module('kubernetes', [
- 'ngRoute',
- 'ui.bootstrap',
- 'gettext',
- 'kubeClient',
- 'kubeClient.cockpit',
- 'kubernetes.app',
- 'kubernetes.graph',
- 'kubernetes.dashboard',
- 'kubernetes.containers',
- 'kubernetes.details',
- 'kubernetes.topology',
- 'kubernetes.volumes',
- 'kubernetes.nodes',
- 'kubernetes.date',
- 'registry.images',
- 'registry.policy',
- 'registry.projects',
- 'registryUI.date',
- 'kubernetesUI'
- ])
-
- .config([
- '$routeProvider',
- 'KubeWatchProvider',
- 'KubeRequestProvider',
- 'KubeSocketProvider',
- 'KubeTranslateProvider',
- 'KubeFormatProvider',
- 'kubernetesContainerSocketProvider',
- 'KubeDiscoverSettingsProvider',
- 'KubeBrowserStorageProvider',
- 'MomentLibProvider',
- '$provide',
- function($routeProvider, KubeWatchProvider, KubeRequestProvider,
- KubeSocketProvider, KubeTranslateProvider, KubeFormatProvider,
- kubernetesContainerSocketProvider, KubeDiscoverSettingsProvider,
- KubeBrowserStorageProvider, MomentLibProvider, $provide) {
- $routeProvider.otherwise({ redirectTo: '/' });
-
- /* Tell the kube-client code to use cockpit watches and requests */
- KubeWatchProvider.KubeWatchFactory = "CockpitKubeWatch";
- KubeRequestProvider.KubeRequestFactory = "CockpitKubeRequest";
- KubeSocketProvider.KubeSocketFactory = "CockpitKubeSocket";
- KubeTranslateProvider.KubeTranslateFactory = "CockpitTranslate";
- KubeFormatProvider.KubeFormatFactory = "CockpitFormat";
- KubeDiscoverSettingsProvider.KubeDiscoverSettingsFactory = "cockpitKubeDiscoverSettings";
- KubeBrowserStorageProvider.KubeBrowserStorageFactory = "cockpitBrowserStorage";
- MomentLibProvider.MomentLibFactory = "momentLib";
-
- /* Tell the container-terminal that we want to be involved in WebSocket creation */
- kubernetesContainerSocketProvider.WebSocketFactory = 'cockpitContainerWebSocket';
-
- $provide.decorator("$exceptionHandler",
- ['$delegate',
- '$log',
- function($delegate, $log) {
- return function (exception, cause) {
- /* Displays an oops if we're running in cockpit */
- if (window.parent !== window && window.name.indexOf("cockpit1:") === 0)
- window.parent.postMessage("\n{ \"command\": \"oops\" }", "*");
-
- $delegate(exception, cause);
- };
- }]);
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/nodes.js b/pkg/kubernetes/scripts/nodes.js
deleted file mode 100644
index bd15e30f9..000000000
--- a/pkg/kubernetes/scripts/nodes.js
+++ /dev/null
@@ -1,898 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-/* This is here to support cockpit.jump
- * If this ever needs to be used outsite of cockpit
- * then we'll need abstract this away in kube-client-cockpit
- */
-/* globals cockpit */
-
-(function() {
- var angular = require('angular');
- var d3 = require('d3');
- require('angular-route');
- require('angular-dialog.js');
-
- require('./charts');
- require('./date');
- require('./kube-client');
- require('./listing');
- require('./utils');
-
- require('../views/nodes-page.html');
- require('../views/node-page.html');
- require('../views/node-body.html');
- require('../views/node-capacity.html');
- require('../views/node-stats.html');
- require('../views/node-add.html');
- require('../views/node-delete.html');
- require('../views/node-alerts.html');
-
- angular.module('kubernetes.nodes', [
- 'ngRoute',
- 'kubeClient',
- 'kubernetes.date',
- 'kubernetes.listing',
- 'kubeUtils',
- 'ui.cockpit',
- 'ui.charts',
- ])
-
- .config([
- '$routeProvider',
- function($routeProvider) {
- $routeProvider
- .when('/nodes', {
- templateUrl: 'views/nodes-page.html',
- controller: 'NodeCtrl'
- })
-
- .when('/nodes/:target', {
- controller: 'NodeCtrl',
- templateUrl: 'views/node-page.html'
- });
- }
- ])
-
- /*
- * The controller for the node view.
- */
- .controller('NodeCtrl', [
- '$scope',
- 'kubeLoader',
- 'kubeSelect',
- 'ListingState',
- 'filterService',
- '$routeParams',
- '$location',
- 'nodeActions',
- 'nodeData',
- 'nodeStatsSummary',
- '$timeout',
- 'KubeBrowserStorage',
- function($scope, loader, select, ListingState, filterService,
- $routeParams, $location, actions, nodeData, statsSummary,
- $timeout, browser) {
- var target = $routeParams["target"] || "";
- $scope.target = target;
-
- $scope.stats = statsSummary.newNodeStatsSummary();
-
- loader.listen(function() {
- var selection;
- $scope.nodes = select().kind("Node");
- if (target) {
- selection = select().kind("Node")
- .name(target);
- $scope.item = selection.one();
- } else {
- selection = $scope.nodes;
- }
- if ($scope.stats)
- $scope.stats.trackNodes(selection);
- }, $scope);
-
- loader.watch("Node", $scope);
-
- $scope.$on("$destroy", function() {
- if ($scope.stats)
- $scope.stats.close();
- $scope.stats = null;
- });
-
- $scope.listing = new ListingState($scope);
-
- /* All the actions available on the $scope */
- angular.extend($scope, actions);
- angular.extend($scope, nodeData);
-
- $scope.$on("activate", function(ev, id) {
- $location.path('/nodes/' + encodeURIComponent(id));
- $scope.$applyAsync();
- });
-
- $scope.nodePods = function node_pods(item) {
- var meta = item.metadata || {};
- return select().kind("Pod")
- .host(meta.name);
- };
-
- $scope.deleteSelectedNodes = function() {
- var k;
- var selected = [];
- for (k in $scope.listing.selected) {
- if ($scope.nodes[k] && $scope.listing.selected[k])
- selected.push($scope.nodes[k]);
- }
-
- if (!selected.length)
- return;
-
- return actions.deleteNodes(selected).then(function() {
- $scope.listing.selected = {};
- });
- };
-
- /* Redirect after a delete */
- $scope.deleteNode = function(val) {
- var promise = actions.deleteNodes(val);
-
- /* If the promise is successful, redirect to another page */
- promise.then(function() {
- if ($scope.target)
- $location.path("/nodes");
- });
-
- return promise;
- };
-
- $scope.jump = function (node) {
- var host, ip;
- if (!node || !node.metadata)
- return;
-
- host = node.metadata.name;
- ip = nodeData.nodeIPAddress(node);
-
- if (ip == "127.0.0.1" || ip == "::1") {
- ip = "localhost";
- } else {
- browser.sessionStorage.setItem(
- "v1-session-machine/" + ip,
- JSON.stringify({ "address": ip,
- "label": host,
- visible: true })
- );
- }
-
- cockpit.jump("/", ip);
- };
- }
- ])
-
- .directive('nodeBody',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/node-body.html',
- };
- }
- )
-
- .directive('nodeCapacity',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/node-capacity.html',
- };
- }
- )
-
- .directive('nodeStats',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/node-stats.html',
- };
- }
- )
-
- .factory('nodeActions', [
- '$modal',
- function($modal) {
- function addNode() {
- return $modal.open({
- animation: false,
- controller: 'AddNodeCtrl',
- templateUrl: 'views/node-add.html',
- resolve: {},
- }).result;
- }
-
- function deleteNodes(val) {
- var nodes;
- if (angular.isArray(val))
- nodes = val;
- else
- nodes = [ val ];
-
- return $modal.open({
- animation: false,
- controller: 'NodeDeleteCtrl',
- templateUrl: 'views/node-delete.html',
- resolve: {
- dialogData: function() {
- return { nodes: nodes };
- }
- },
- }).result;
- }
-
- return {
- addNode: addNode,
- deleteNodes: deleteNodes
- };
- }
- ])
-
- .controller("NodeDeleteCtrl", [
- "$q",
- "$scope",
- "$modalInstance",
- "dialogData",
- "kubeMethods",
- "kubeSelect",
- function($q, $scope, $instance, dialogData, methods, select) {
- angular.extend($scope, dialogData);
-
- $scope.performDelete = function performDelete() {
- var k;
- var errors = [];
- var nodes = {};
- var promises = [];
-
- function handleError(ex) {
- errors.push(ex.message || ex.statusText);
- nodes[k] = $scope.nodes[k];
- return $q.reject();
- }
-
- for (k in $scope.nodes) {
- var p = methods.delete($scope.nodes[k])
- .catch(handleError);
- promises.push(p);
- }
-
- return $q.all(promises).catch(function () {
- $scope.nodes = select(nodes);
- return $q.reject(errors);
- });
- };
- }
- ])
-
- .factory('nodeData', [
- "KubeMapNamedArray",
- "KubeTranslate",
- function (mapNamedArray, translate) {
- const _ = translate.gettext;
-
- function nodeConditions(node) {
- var status;
- if (!node)
- return;
-
- if (!node.conditions) {
- status = node.status || { };
- node.conditions = mapNamedArray(status.conditions, "type");
- }
- return node.conditions;
- }
-
- function nodeCondition(node, type) {
- var conditions = nodeConditions(node) || {};
- return conditions[type] || {};
- }
-
- function nodeStatus(node) {
- var spec = node ? node.spec : {};
- if (!nodeCondition(node, "Ready").status)
- return _("Unknown");
-
- if (nodeCondition(node, "Ready").status != 'True')
- return _("Not Ready");
-
- if (spec && spec.unschedulable)
- return _("Scheduling Disabled");
-
- return _("Ready");
- }
-
- function nodeStatusIcon(node) {
- var state = "";
- /* If no status.conditions then it hasn't even started */
- if (!nodeCondition(node, "Ready").status) {
- state = "wait";
- } else {
- if (nodeCondition(node, "Ready").status != 'True') {
- state = "fail";
- } else if (nodeCondition(node, "OutOfDisk").status == "True" ||
- nodeCondition(node, "OutOfMemory").status == "True") {
- state = "warn";
- }
- }
- return state;
- }
-
- function nodeIPAddress(node) {
- if (!node || !node.status)
- return;
-
- var addresses = node.status.addresses;
- var address;
- var internal;
- /* If no addresses then it hasn't even started */
- if (addresses) {
- addresses.forEach(function(a) {
- if (a.type == "LegacyHostIP" || a.type == "ExternalIP") {
- address = a.address;
- return false;
- } else if (a.type == "InternalIP") {
- internal = a.address;
- }
- });
- }
-
- return address || internal;
- }
-
- return {
- nodeStatusIcon: nodeStatusIcon,
- nodeCondition: nodeCondition,
- nodeConditions: nodeConditions,
- nodeStatus: nodeStatus,
- nodeIPAddress: nodeIPAddress
- };
- }
- ])
-
- .controller("AddNodeCtrl", [
- "$q",
- "$scope",
- "$modalInstance",
- "kubeMethods",
- "KubeTranslate",
- function($q, $scope, $instance, methods, translate) {
- const _ = translate.gettext;
- var fields = {
- "address" : "",
- "name" : "",
- };
- var dirty = false;
-
- $scope.fields = fields;
-
- function validate() {
- var regex = /^[a-z0-9.-]+$/i;
- var defer = $q.defer();
- var address = fields.address.trim();
- var name = fields.name.trim();
- var ex;
- var failures = [];
- var item;
-
- if (!address)
- ex = new Error(_("Please type an address"));
- else if (!regex.test(address))
- ex = new Error(_("The address contains invalid characters"));
-
- if (ex) {
- ex.target = "#node-address";
- failures.push(ex);
- }
-
- if (name && !regex.test(name)) {
- ex = new Error(_("The name contains invalid characters"));
- ex.target = "#node-name";
- failures.push(ex);
- }
-
- if (failures.length > 0) {
- defer.reject(failures);
- } else {
- item = {
- "kind": "Node",
- "apiVersion": "v1",
- "metadata": {
- "name": name || address,
- }
- };
- defer.resolve(item);
- }
-
- return defer.promise;
- }
-
- $scope.nameKeyUp = function nameKeyUp(event) {
- dirty = true;
- if (event.keyCode == 13)
- $scope.performAdd();
- };
-
- $scope.addressKeyUp = function addressKeyUp(event) {
- if (event.keyCode == 13)
- $scope.performAdd();
- else if (!dirty)
- fields.name = event.target.value;
- };
-
- $scope.performAdd = function performAdd() {
- return validate().then(function(item) {
- return methods.create(item);
- });
- };
- }
- ])
-
- .directive('kubernetesStatusIcon', function() {
- return {
- restrict: 'A',
- link: function($scope, element, attributes) {
- $scope.$watch(attributes["status"], function(status) {
- element
- .toggleClass("spinner spinner-xs", status == "wait")
- .toggleClass("pficon pficon-error-circle-o", status == "fail")
- .toggleClass("pficon pficon-warning-triangle-o", status == "warn");
- });
- }
- };
- })
-
- .directive('nodeAlerts', function() {
- return {
- restrict: 'A',
- templateUrl: 'views/node-alerts.html'
- };
- })
-
- .factory('nodeStatsSummary', [
- "$q",
- "$interval",
- "$exceptionHandler",
- "KubeRequest",
- "nodeData",
- "KubeStringToBytes",
- "KubeFormat",
- function ($q, $interval, $exceptionHandler, KubeRequest, nodeData,
- kubeStringToBytes, format) {
- function NodeStatsSummary() {
- var self = this;
-
- var requests = {};
- var statData = {};
- var callbacks = [];
- var interval;
-
- function request(name) {
- if (requests[name])
- return $q.when([]);
-
- var path = "/api/v1/nodes/" + encodeURIComponent(name) + "/proxy/stats/summary/";
- var req = KubeRequest("GET", path);
- requests[name] = req;
-
- return req.then(function(data) {
- delete requests[name];
- statData[name] = data.data;
- })
- .catch(function(ex) {
- delete requests[name];
- delete statData[name];
- if (ex.status != 503)
- console.warn(ex);
- });
- }
-
- function invokeCallbacks(/* ... */) {
- var i, len, func;
- for (i = 0, len = callbacks.length; i < len; i++) {
- func = callbacks[i];
- try {
- if (func)
- func.apply(self, arguments);
- } catch (e) {
- $exceptionHandler(e);
- }
- }
- }
-
- function fetchForNames(names) {
- var q = [];
- angular.forEach(names, function(name) {
- q.push(request(name));
- });
-
- $q.all(q).then(invokeCallbacks, invokeCallbacks);
- }
-
- interval = $interval(function () {
- fetchForNames(Object.keys(statData));
- }, 5000);
-
- self.watch = function watch(callback) {
- callbacks.push(callback);
-
- return {
- cancel: function() {
- var i, len;
- for (i = 0, len = callbacks.length; i < len; i++) {
- if (callbacks[i] === callback)
- callbacks[i] = null;
- }
- }
- };
- };
-
- self.close = function close() {
- var name;
- if (interval)
- $interval.cancel(interval);
-
- for (name in requests) {
- var req = requests[name];
- if (req && req.cancel)
- req.cancel();
- }
- };
-
- self.trackNodes = function trackNodes(selection) {
- var names = [];
- angular.forEach(selection, function(node) {
- var ready = nodeData.nodeCondition(node, "Ready");
- var meta = node ? node.metadata : {};
- var name = meta ? meta.name : "";
-
- if (ready && ready.status === 'True') {
- if (!statData[name])
- names.push(name);
- } else {
- // Unfortunally i'm seen some requests
- // not error so clean them out.
- delete statData[name];
- if (request[name]) {
- request[name].cancel();
- delete request[name];
- }
- }
- });
- fetchForNames(names);
- };
-
- self.getSimpleUsage = function getSimpleUsage(node, section) {
- var meta = node ? node.metadata : {};
- var status = node ? node.status : {};
- var name = meta ? meta.name : "";
-
- var nodeData = statData[name] ? statData[name].node : {};
- var result = nodeData[section];
-
- if (!result)
- return;
-
- var allocatable = status ? status.allocatable : {};
- if (!allocatable)
- return;
-
- switch (section) {
- case "cpu":
- if (!allocatable.cpu)
- return;
- return {
- used: result.usageNanoCores,
- total: allocatable.cpu * 1000000000
- };
- case "memory":
- if (!allocatable.memory)
- return;
- return {
- used: result.usageBytes,
- total: kubeStringToBytes(allocatable.memory)
- };
- case "fs":
- return {
- used: result.usedBytes,
- total: result.capacityBytes
- };
- default:
- }
- };
- }
-
- return {
- newNodeStatsSummary: function(interval) {
- return new NodeStatsSummary(interval);
- },
- };
- }
- ])
-
- .directive('nodeOsGraph', [
- "KubeTranslate",
- function(translate) {
- const _ = translate.gettext;
-
- return {
- scope: {
- 'nodes' : '='
- },
- template: '
',
- restrict: 'A',
- link: function($scope, element, attributes) {
- $scope.data = [];
- $scope.largeTitle = 0;
-
- function refresh(items) {
- items = items || [];
- var data = {};
- angular.forEach(items, function(node) {
- var os;
- var color;
- if (node.status && node.status.nodeInfo)
- os = node.status.nodeInfo.osImage;
-
- if (!os) {
- os = _("Unknown");
- color = "#bbbbbb";
- }
-
- if (data[os])
- data[os].value++;
- else
- data[os] = { value: 1, label: os, color: color };
- });
-
- var arr = Object.keys(data).map(function(k) {
- return data[k];
- });
-
- arr.sort(function (a, b) {
- if (a.label < b.label)
- return -1;
- if (a.label > b.label)
- return 1;
- return 0;
- });
-
- $scope.data = arr;
- $scope.largeTitle = items.length;
- }
-
- $scope.$watchCollection('nodes', function(nodes) {
- refresh(nodes);
- });
- }
- };
- }
- ])
-
- .directive('nodeHeatMap', [
- "KubeTranslate",
- "KubeFormat",
- function(translate, format) {
- const _ = translate.gettext;
- return {
- restrict: 'A',
- scope: {
- 'nodes' : '=',
- 'stats' : '='
- },
- template: '
',
- link: function($scope, element, attributes) {
- var outer = d3.select(element[0]);
- var currentTab;
- var tabs = {
- cpu: {
- label: _("CPU"),
- tooltip: function(r) { return format.format(_("CPU Utilization: $0%"), Math.round((r.used / r.total) * 100)) }
- },
- memory: {
- label: _("Memory"),
- tooltip: function(r) { return format.format(_("Memory Utilization: $0%"), Math.round((r.used / r.total) * 100)) }
- },
- fs: {
- label: _("Disk"),
- tooltip: function(r) { return format.format(_("Disk Utilization: $0%"), Math.round((r.used / r.total) * 100)) }
- }
- };
-
- outer.select("ul.nav-tabs")
- .selectAll("li")
- .data(Object.keys(tabs))
- .enter()
- .append("li")
- .attr("data-metric", function(d) { return d })
- .append("a")
- .text(function(d) { return tabs[d].label });
-
- function changeTab(tab) {
- currentTab = tab;
- outer.selectAll("ul.nav-tabs li")
- .attr("class", function(d) { return tab === d ? "active" : null });
- refreshData();
- }
-
- outer.selectAll("ul.nav-tabs li")
- .on("click", function() {
- changeTab(d3.select(this).attr("data-metric"));
- });
-
- function refreshData() {
- var nodes = $scope.nodes;
- var data = [];
-
- if (!nodes)
- nodes = [];
-
- angular.forEach(nodes, function(node) {
- var result, value, name;
- var tooltip = _("Unknown");
- if (node && node.metadata)
- name = node.metadata.name;
-
- if (!name)
- return;
-
- result = $scope.stats.getSimpleUsage(node, currentTab);
- if (result)
- value = result.used / result.total;
-
- if (value === undefined)
- value = -1;
- else
- tooltip = tabs[currentTab].tooltip(result);
-
- data.push({ value: value, name: name,
- tooltip: tooltip });
- });
-
- data.sort(function (a, b) {
- return b.value - a.value;
- });
-
- $scope.$applyAsync(function() {
- $scope.data = data;
- });
- return true;
- }
-
- $scope.$on("boxClick", function (ev, name) {
- $scope.$emit("activate", name);
- });
-
- var sw = $scope.stats.watch(refreshData);
- $scope.$on("$destroy", function() {
- sw.cancel();
- });
-
- changeTab("cpu");
- }
- };
- }
- ])
-
- .directive('nodeUsageDonutChart', [
- "KubeTranslate",
- "KubeFormat",
- function(translate, format) {
- const _ = translate.gettext;
- return {
- restrict: 'A',
- scope: {
- 'node' : '=',
- 'stats' : '=',
- },
- template: '
{{ title }}
',
- link: function($scope, element, attributes) {
- var colorFunc = d3.scale.threshold()
- .domain([0.7, 0.8, 0.9])
- .range(['#d4f0fa', '#F9D67A', '#EC7A08', '#CE0000']);
-
- var types = {
- cpu: {
- label: _("CPU"),
- smallTitle: function () {},
- largeTitle: function (result) {
- var r = result.used / result.total;
- var p = Math.round(r * 100);
- return format.format("$0%", p);
- },
- },
- memory: {
- label: _("Memory"),
- smallTitle: function (result) {
- return _("Used");
- },
- largeTitle: function (result) {
- return format.formatBytes(result.used);
- },
- },
- fs: {
- label: _("Disk"),
- smallTitle: function (result) {
- return _("Used");
- },
- largeTitle: function (result) {
- return format.formatBytes(result.used);
- },
- }
- };
-
- var type = attributes['type'];
- $scope.title = types[type].label;
-
- function clear() {
- $scope.$applyAsync(function() {
- $scope.data = null;
- $scope.smallTitle = null;
- $scope.largeTitle = null;
- });
- }
-
- function refreshData() {
- var node = $scope.node;
- var result;
-
- if (!node)
- return clear();
-
- result = $scope.stats.getSimpleUsage(node, type);
- if (result) {
- $scope.$applyAsync(function() {
- $scope.smallTitle = types[type].smallTitle(result);
- $scope.largeTitle = types[type].largeTitle(result);
- var u = Math.round((result.used / result.total) * 100);
- var l = 100 - u;
- var freeText = translate.ngettext("$0% Free",
- "$0% Free", u);
- var usedText = translate.ngettext("$0% Used",
- "$0% Used", u);
- $scope.data = [
- { value: result.total - result.used,
- tooltip : format.format(freeText, l),
- color: "#bbbbbb" },
- { value: result.used,
- tooltip : format.format(usedText, u),
- color: colorFunc(result.used / result.total) }
- ];
- });
- } else {
- clear();
- }
- return true;
- }
-
- var sw = $scope.stats.watch(refreshData);
- $scope.$on("$destroy", function() {
- sw.cancel();
- });
- }
- };
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/policy.js b/pkg/kubernetes/scripts/policy.js
deleted file mode 100644
index d91f6c174..000000000
--- a/pkg/kubernetes/scripts/policy.js
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
- require('./kube-client');
-
- angular.module('registry.policy', [
- 'kubeClient',
- ])
-
- .factory("projectPolicy", [
- '$q',
- '$rootScope',
- 'kubeLoader',
- 'kubeMethods',
- 'kubeSelect',
- 'KubeWatch',
- 'KubeRequest',
- 'KUBE_SCHEMA',
- function($q, $rootScope, loader, methods, select, watch, KubeRequest, KUBE_SCHEMA) {
- var apiGroup;
- var RBAC_GROUP = "rbac.authorization.k8s.io";
- var RBAC_API = "/apis/rbac.authorization.k8s.io/v1beta1";
- var POLICY_BINDING_API = KUBE_SCHEMA["RoleBinding"]["api"];
- var watchPromise;
-
- function setupRoleBinding(group) {
- KUBE_SCHEMA["RoleBinding"]["api"] = group ? RBAC_API : POLICY_BINDING_API;
- KUBE_SCHEMA["rolebindings"]["api"] = group ? RBAC_API : POLICY_BINDING_API;
- apiGroup = group;
- expireSAR(null);
- expireWhoCan(null);
- return group ? "rolebindings" : "policybindings";
- }
-
- function ensureWatchType() {
- if (!watchPromise) {
- watchPromise = new KubeRequest("GET", "/oapi/v1")
- .then(function(response) {
- var data = response.data || {};
- var i;
- var l = data.resources || [];
- for (i = 0; i < l.length; i++) {
- if (l[i].kind == "PolicyBinding")
- return setupRoleBinding();
- }
- return setupRoleBinding(RBAC_GROUP);
- }, function(err) {
- console.warn("Error getting API", err);
- return setupRoleBinding();
- });
- }
- return watchPromise;
- }
-
- /*
- * Data loading hacks:
- *
- * We would like to watch rolebindings, but not all versions support
- * that. So we have to watch policybindings and then infer the
- * rolebindings from there.
- *
- * In addition we would like to be able to load User and Group objects,
- * even if only for a certain project. However, non-cluster admins
- * fail to do this, so we simulate these objects from the role bindings.
- */
- loader.listen(function(present, removed) {
- var link;
- var expire = { };
-
- /* If reseting clear status */
- if (!present && !removed) {
- expireSAR(null);
- expireWhoCan(null);
- watchPromise = null;
- return;
- }
-
- for (link in removed) {
- if (removed[link].kind == "PolicyBinding") {
- update_rolebindings(removed[link].roleBindings, true);
- expire[removed[link].metadata.namespace] = true;
- }
- }
- for (link in present) {
- if (present[link].kind == "PolicyBinding") {
- update_rolebindings(present[link].roleBindings, false);
- expire[present[link].metadata.namespace] = true;
- } else if (present[link].kind == "RoleBinding") {
- ensure_subjects(present[link].subjects || []);
- expire[present[link].metadata.namespace] = true;
- }
- }
-
- var namespace;
- for (namespace in expire) {
- expireWhoCan(namespace);
- expireSAR(namespace);
- }
- });
-
- function update_rolebindings(bindings, removed) {
- angular.forEach(bindings || [], function(wrapper) {
- loader.handle(wrapper.roleBinding, removed, "RoleBinding");
- });
- }
-
- function ensure_subjects(subjects) {
- angular.forEach(subjects, function(subject) {
- var link = loader.resolve(subject.kind, subject.name, subject.namespace);
- if (link in loader.objects)
- return;
-
- /* Don't show system groups */
- if (subject.kind == "Group" && subject.name.indexOf("system:") === 0)
- return;
-
- /* An interim object, until perhaps the real thing can be loaded */
- var interim = { kind: subject.kind, apiVersion: "v1", metadata: { name: subject.name } };
- if (subject.namespace)
- interim.metadata.namespace = subject.namespace;
- loader.handle(interim);
- });
- }
-
- /*
- * Cached localresourceaccessreviews responses, and expired data
- * Each one has a project key, containing an object with verb:resource keys.
- */
- var cached = { };
- var expired = { };
-
- function fillWhoCan(namespace, verb, resource, result) {
- var key = verb + ":" + resource;
-
- if (!(namespace in cached))
- cached[namespace] = { };
- cached[namespace][key] = result;
-
- if (result) {
- if (namespace in expired) {
- delete expired[namespace][key];
- }
- }
-
- $rootScope.$applyAsync();
- }
-
- function expireWhoCan(namespace) {
- if (namespace) {
- expired[namespace] = angular.extend({ }, cached[namespace]);
- delete cached[namespace];
- } else {
- expired = cached;
- cached = { };
- }
-
- $rootScope.$applyAsync();
- }
-
- function lookupWhoCan(namespace, verb, resource) {
- var key = verb + ":" + resource;
-
- var ask = true;
- var result = null;
-
- var data = cached[namespace];
- if (data) {
- if (key in data) {
- result = data[key];
- ask = false;
- }
- }
-
- if (!result) {
- data = expired[namespace];
- if (data) {
- if (key in data)
- result = data[key];
- }
- }
-
- if (!ask)
- return result;
-
- /* Perform a request */
- var request = {
- kind: "LocalResourceAccessReview",
- apiVersion: "v1",
- namespace: "",
- verb: verb,
- resource: resource,
- resourceName: "",
- content: null
- };
-
- /* Fill in null info while looking up */
- fillWhoCan(namespace, verb, resource, null);
-
- var path = loader.resolve("localresourceaccessreviews", null, namespace);
- methods.post(path, request)
- .then(function(response) {
- fillWhoCan(namespace, verb, resource, response);
- }, function(response) {
- console.warn("failed to lookup access:", namespace, verb, resource + ":",
- response.message || JSON.stringify(response));
- });
-
- return result;
- }
-
- var sarCache = { };
-
- function subjectAccessReview(namespace, user, verb, resource) {
- var key = namespace + ':' + (user ? user.metadata.name : "") + ':' + verb + ':' + resource;
- var defer = $q.defer();
-
- if (key in sarCache) {
- defer.resolve(sarCache[key]);
- } else {
- var request = {
- kind: "SubjectAccessReview",
- apiVersion: "v1",
- namespace: namespace,
- verb: verb,
- resource: resource
- };
-
- methods.post(loader.resolve("subjectaccessreviews"), request)
- .then(function(response) {
- sarCache[key] = response.allowed;
- defer.resolve(response.allowed);
- }, function(response) {
- console.warn("failed to review subject access:", response.message || JSON.stringify(response));
- defer.reject(response.message || JSON.stringify(response));
- });
- }
-
- return defer.promise;
- }
-
- function expireSAR(namespace) {
- if (namespace) {
- for (var key in sarCache) {
- if (key.lastIndexOf(namespace + ':', 0) === 0)
- delete sarCache[key];
- }
- } else {
- sarCache = { };
- }
-
- $rootScope.$applyAsync();
- }
-
- /*
- * HACK: There's no way to PATCH subjects in or out
- * of a role, so we have to use this race prone mechanism.
- */
- function modifyRole(namespace, role, callback) {
- var path = loader.resolve("RoleBinding", role, namespace);
- return loader.load(path)
- .then(function(resource) {
- callback(resource);
- return methods.put(path, resource);
- });
- }
-
- function createRole(namespace, role, subjects) {
- var name = toName(role);
- var binding = {
- kind: "RoleBinding",
- metadata: {
- name: name,
- namespace: namespace,
- creationTimestamp: null,
- },
- userNames: [],
- groupNames: [],
- subjects: [],
- roleRef: {
- name: role,
- kind: "ClusterRole",
- }
- };
- addToArray(roleArray(binding, "subjects"), subjects);
- addToArray(roleArrayKind(binding, subjects.kind), subjects.name);
- return methods.create(binding, namespace);
- }
-
- function removeFromRole(project, role, subject) {
- subject.apiGroup = apiGroup;
- var namespace = toName(project);
- return modifyRole(namespace, role, function(data) {
- removeFromArray(roleArray(data, "subjects"), subject);
- removeFromArray(roleArrayKind(data, subject.kind), subject.name);
- }).then(function() {
- expireWhoCan(namespace);
- }, function(resp) {
- /* If the role doesn't exist consider removed to work */
- if (resp.code !== 404)
- return $q.reject(resp);
- });
- }
-
- function removeMemberFromProject(project, subjectRoleBindings, subject) {
- var registryRoles = ["registry-admin", "registry-editor", "registry-viewer"];
- var chain = $q.when();
- subject.apiGroup = apiGroup;
-
- angular.forEach(subjectRoleBindings, function(role) {
- // Since we only added registry roles
- // remove ONLY registry roles
- if (indexOf(registryRoles, role.roleRef.name) !== -1) {
- chain = chain.then(function() {
- return removeFromRole(project, role.roleRef.name, subject);
- });
- }
- });
- return chain;
- }
- function indexOf(array, value) {
- var i, len;
- for (i = 0, len = array.length; i < len; i++) {
- if (angular.equals(array[i], value))
- return i;
- }
- return -1;
- }
-
- function addToArray(array, value) {
- var index = indexOf(array, value);
- if (index < 0)
- array.push(value);
- }
-
- function removeFromArray(array, value) {
- var index = indexOf(array, value);
- if (index >= 0)
- array.splice(index, 1);
- }
-
- function roleArray(data, field) {
- var array = data[field] || [];
- data[field] = array;
- return array;
- }
-
- function roleArrayKind(data, kind) {
- if (kind == "Group" || kind == "SystemGroup")
- return roleArray(data, "groupNames");
- else
- return roleArray(data, "userNames");
- }
-
- function toName(object) {
- if (typeof object == "object")
- return object.metadata.name;
- else
- return object;
- }
-
- return {
- watch: function watch(until) {
- ensureWatchType().then(function (what) {
- loader.watch(what, until)
- .then(function() {
- expireWhoCan(null);
- });
- });
- },
- whoCan: function whoCan(project, verb, resource) {
- return lookupWhoCan(toName(project), verb, resource);
- },
- addToRole: function addToRole(project, role, subject) {
- subject.apiGroup = apiGroup;
- var namespace = toName(project);
- return modifyRole(namespace, role, function(data) {
- addToArray(roleArray(data, "subjects"), subject);
- addToArray(roleArrayKind(data, subject.kind), subject.name);
- }).then(function() {
- expireWhoCan(namespace);
- }, function(resp) {
- /* If the role doesn't exist create it */
- if (resp.code === 404)
- return createRole(namespace, role, subject);
- return $q.reject(resp);
- });
- },
- removeFromRole: removeFromRole,
- removeMemberFromProject: removeMemberFromProject,
- subjectAccessReview: subjectAccessReview
- };
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/projects.js b/pkg/kubernetes/scripts/projects.js
deleted file mode 100644
index f808d70a1..000000000
--- a/pkg/kubernetes/scripts/projects.js
+++ /dev/null
@@ -1,1411 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
- require('angular-route');
- require('angular-dialog.js');
-
- require('./kube-client');
- require('./listing');
- require('./policy');
-
- require('../views/projects-page.html');
- require('../views/project-page.html');
- require('../views/user-page.html');
- require('../views/group-page.html');
- require('../views/project-panel.html');
- require('../views/project-body.html');
- require('../views/user-body.html');
- require('../views/group-panel.html');
- require('../views/user-panel.html');
- require('../views/project-listing.html');
- require('../views/project-modify.html');
- require('../views/project-modify.html');
- require('../views/project-delete.html');
- require('../views/add-group-dialog.html');
- require('../views/user-group-add.html');
- require('../views/user-group-remove.html');
- require('../views/group-delete.html');
- require('../views/add-user-dialog.html');
- require('../views/user-modify.html');
- require('../views/user-add-membership.html');
- require('../views/user-remove-membership.html');
- require('../views/user-delete.html');
- require('../views/add-member-role-dialog.html');
- require('../views/remove-role-dialog.html');
- require('../views/add-role-dialog.html');
-
- function toName(object) {
- if (object && typeof object == "object")
- return object.metadata.name;
- else
- return object;
- }
-
- angular.module('registry.projects', [
- 'ngRoute',
- 'ui.cockpit',
- 'kubeClient',
- 'kubernetes.listing',
- 'registry.policy',
- ])
-
- .config(['$routeProvider',
- function($routeProvider) {
- $routeProvider
- .when('/projects/:namespace?', {
- controller: 'ProjectsCtrl',
- templateUrl: function(params) {
- if (!params['namespace'])
- return 'views/projects-page.html';
- else
- return 'views/project-page.html';
- }
- })
- .when('/users/:user', {
- controller: 'UserCtrl',
- templateUrl: function(params) {
- return 'views/user-page.html';
- }
- })
- .when('/groups/:group', {
- controller: 'GroupCtrl',
- templateUrl: function(params) {
- return 'views/group-page.html';
- }
- });
- }
- ])
-
- .controller('ProjectsCtrl', [
- '$scope',
- '$routeParams',
- '$location',
- 'kubeSelect',
- 'kubeLoader',
- 'projectData',
- 'projectActions',
- 'ListingState',
- 'roleActions',
- 'projectPolicy',
- function($scope, $routeParams, $location, select, loader, projectData, projectAction, ListingState, roleAction, projectPolicy) {
- loader.watch("users", $scope);
- loader.watch("groups", $scope);
- projectPolicy.watch($scope);
- var namespace = $routeParams["namespace"] || "";
- $scope.projName = namespace;
- if (namespace) {
- $scope.listing = new ListingState($scope);
- $scope.project = function() {
- return select().kind("Project")
- .name(namespace)
- .one();
- };
- } else {
- $scope.listing = new ListingState($scope);
- $scope.projects = function() {
- return select().kind("Project");
- };
- }
- $scope.$on("activate", function(ev, id) {
- ev.preventDefault();
- $location.path(id);
- });
- angular.extend($scope, projectData);
- angular.extend($scope, roleAction);
- angular.extend($scope, projectAction);
- $scope.users = function() {
- return select().kind("User");
- };
- $scope.groups = function() {
- return select().kind("Group");
- };
- }
- ])
-
- .controller('UserCtrl', [
- '$scope',
- '$routeParams',
- '$location',
- 'kubeSelect',
- 'kubeLoader',
- 'projectData',
- 'projectActions',
- 'roleActions',
- 'ListingState',
- 'projectPolicy',
- function($scope, $routeParams, $location, select, loader, projectData, projectAction, roleActions, ListingState, projectPolicy) {
- loader.watch("users", $scope);
- loader.watch("groups", $scope);
- projectPolicy.watch($scope);
- var user = $routeParams["user"] || "";
- $scope.userName = user;
- if (user) {
- $scope.user = function() {
- return select().kind("User")
- .name(user)
- .one();
- };
- $scope.listing = new ListingState($scope);
- $scope.$on("activate", function(ev, id) {
- ev.preventDefault();
- $location.path(id);
- });
- } else {
- $scope.listing = new ListingState($scope);
- $location.path("/projects");
- }
- $scope.projects = function() {
- return select().kind("Project");
- };
- $scope.groups = function() {
- return select().kind("Group");
- };
- $scope.users = function() {
- return select().kind("User");
- };
- angular.extend($scope, projectData);
- angular.extend($scope, projectAction);
- angular.extend($scope, roleActions);
- }
- ])
-
- .controller('GroupCtrl', [
- '$scope',
- '$routeParams',
- '$location',
- 'kubeSelect',
- 'kubeLoader',
- 'projectData',
- 'projectActions',
- 'roleActions',
- 'ListingState',
- 'projectPolicy',
- function($scope, $routeParams, $location, select, loader, projectData, projectAction, roleActions, ListingState, projectPolicy) {
- loader.watch("users", $scope);
- loader.watch("groups", $scope);
- projectPolicy.watch($scope);
- var group = $routeParams["group"] || "";
- $scope.groupName = group;
- if (group) {
- $scope.group = function() {
- return select().kind("Group")
- .name(group)
- .one();
- };
- $scope.listing = new ListingState($scope);
- $scope.$on("activate", function(ev, id) {
- ev.preventDefault();
- $location.path(id);
- });
- } else {
- $scope.listing = new ListingState($scope);
- $location.path("/projects");
- }
- $scope.projects = function() {
- return select().kind("Project");
- };
- $scope.groups = function() {
- return select().kind("Group");
- };
- $scope.users = function() {
- return select().kind("User");
- };
- angular.extend($scope, projectData);
- angular.extend($scope, projectAction);
- angular.extend($scope, roleActions);
- }
- ])
-
- .factory("projectData", [
- '$q',
- 'kubeSelect',
- 'kubeLoader',
- 'projectPolicy',
- function($q, select, loader, policy) {
- var registryRoles = [{ ocRole: "registry-admin", displayRole :"Admin" },
- { ocRole:"registry-editor", displayRole :"Push" },
- { ocRole:"registry-viewer", displayRole :"Pull" }];
-
- function getRegistryRolesMap() {
- return registryRoles;
- }
- function getDisplayRole(ocRole) {
- var i;
- var displayRole;
- for (i = registryRoles.length - 1; i >= 0; i--) {
- if (registryRoles[i].ocRole === ocRole) {
- displayRole = registryRoles[i].displayRole;
- break;
- }
- }
- return displayRole;
- }
- function getOcRolesList() {
- var ocRoles = [];
- angular.forEach(registryRoles, function(r) {
- ocRoles.push(r.ocRole);
- });
- return ocRoles;
- }
- function getAllRoles(member, project) {
- if (!member && !project)
- return [];
- var projectName = toName(project);
- var roleBinds = subjectRoleBindings(member, projectName);
- var meta;
- var ret = [];
- angular.forEach(roleBinds, function(roleBind) {
- meta = roleBind.metadata || { };
- if (meta.name)
- ret.push(meta.name);
- });
- return ret;
- }
- function getRegistryRoles(member, project) {
- if (!member && !project)
- return [];
- var projectName = toName(project);
- var roleBinds = subjectRoleBindings(member, projectName);
- var ocRegistryRoles = getOcRolesList();
- var roles = [];
- var meta;
- angular.forEach(roleBinds, function(roleBind) {
- meta = roleBind.metadata || { };
- if (meta.name && ocRegistryRoles.indexOf(meta.name) !== -1) {
- if (roles.indexOf(getDisplayRole(meta.name) === -1))
- roles.push(getDisplayRole(meta.name));
- }
- });
- return roles;
- }
- function isRegistryRole(member, displayRole, project) {
- var oc_roles = getRegistryRoles(member, project);
- if (oc_roles.indexOf(displayRole) !== -1) {
- return true;
- }
- return false;
- }
- function hasRegistryRole(member, project) {
- var oc_roles = getRegistryRoles(member, project);
- if (oc_roles.length === 0) {
- return false;
- }
- return true;
- }
- function isRoles(member, namespace) {
- var oc_roles = getAllRoles(member, namespace);
- if (oc_roles.length === 0) {
- return false;
- }
- return true;
- }
- function getProjectsWithMember(projects, member) {
- if (!projects && !member)
- return [];
- var projList = [];
- if (member) {
- angular.forEach(projects, function(project) {
- if (project && subjectIsMember(member, project.metadata.name))
- projList.push(project);
- });
- }
- return projList;
- }
-
- function getGroupsWithMember(groups, member) {
- if (!groups && !member)
- return [];
- var grpList = [];
- if (member) {
- angular.forEach(groups, function(group) {
- if (group && group.users && group.users.indexOf(member) != -1)
- grpList.push(group);
- });
- }
- return grpList;
- }
- function getMembershipOfUser(projects, groups, user) {
- var members = [];
- var userProjects = getProjectsWithMember(projects, user);
- angular.forEach(userProjects, function(project) {
- members.push(project.metadata.name);
- });
- var userGroups = getGroupsWithMember(groups, user);
- angular.forEach(userGroups, function(group) {
- members.push(group.metadata.name);
- });
- return members;
- }
- /*
- * To use this you would have a user or group, and do:
- *
- * rolebindings = select().kind("RoleBindings").containsSubject(user_name);
- * rolebindings = select().kind("RoleBindings").containsSubject(user_object);
- * rolebindings = select().kind("RoleBindings").containsSubject(group_object);
- */
- select.register({
- name: "containsSubject",
- digests: function(arg) {
- var meta, i, len, subjects;
- var ret = [];
- if (typeof arg == "string") {
- ret.push(arg);
- } else if (arg.kind == "User" || arg.kind == "Group") {
- meta = arg.metadata || { };
- ret.push(meta.name + ":" + arg.kind);
- } else if (arg.kind == "RoleBinding") {
- subjects = arg.subjects || [];
- for (i = 0, len = subjects.length; i < len; i++) {
- ret.push(subjects[i].name);
- ret.push(subjects[i].name + ":" + subjects[i].kind);
- }
- }
- return ret;
- }
- });
-
- function subjectRoleBindings(subject, namespace) {
- return select().kind("RoleBinding")
- .namespace(namespace)
- .containsSubject(subject);
- }
-
- function subjectIsMember(subject, namespace) {
- if (!subject || !namespace)
- return null;
- namespace = toName(namespace);
- return !!subjectRoleBindings(subject, namespace).one();
- }
-
- function formatMembers(members, kind) {
- var mlist = "";
- var i;
- if (!members || members.length === 0)
- return mlist;
- if (members.length <= 3) {
- for (i = members.length - 1; i >= 0; i--) {
- if (i > 0)
- mlist += ",";
- mlist += members[i];
- }
- } else {
- if (kind === "Groups") {
- mlist = members.length + " " + kind;
- } else if (kind === "Users") {
- mlist = members.length + " " + kind;
- }
- }
- return mlist;
- }
-
- var sharedVerb = "get";
- var sharedResource = "imagestreams/layers";
- var sharedRole = "registry-viewer";
- var sharedKind = "Group";
- var anonymousGroup = "system:unauthenticated";
- var sharedGroup = "system:authenticated";
- var registryAdmin = "registry-admin";
-
- function shareImages(project, accessPolicy) {
- var anonSubject = {
- kind: sharedKind,
- name: anonymousGroup,
- };
- var sharedSubject = {
- kind: sharedKind,
- name: sharedGroup,
- };
- if (accessPolicy === "anonymous") {
- return policy.addToRole(project, sharedRole, anonSubject)
- .then(function() {
- return policy.addToRole(project, sharedRole, sharedSubject);
- });
- } else if (accessPolicy === "shared") {
- return policy.removeFromRole(project, sharedRole, anonSubject)
- .then(function() {
- return policy.addToRole(project, sharedRole, sharedSubject);
- });
- } else {
- return policy.removeFromRole(project, sharedRole, anonSubject)
- .then(function() {
- return policy.removeFromRole(project, sharedRole, sharedSubject);
- });
- }
- }
-
- function sharedImages(project) {
- if (!project)
- return null;
-
- var response = policy.whoCan(project, sharedVerb, sharedResource);
- if (!response)
- return null;
-
- var projState = {};
- projState[anonymousGroup] = null;
- projState[sharedGroup] = null;
-
- var i, len;
- var groups = response.groups || [];
- for (i = 0, len = groups.length; i < len; i++) {
- if (projState.hasOwnProperty(groups[i]))
- projState[groups[i]] = true;
- }
-
- if (projState[anonymousGroup])
- return "anonymous";
- else if (projState[sharedGroup])
- return "shared";
- return "private";
- }
-
- function makeRegistryAdmin(project, currentUser) {
- var subject = {
- kind: 'User',
- name: toName(currentUser),
- };
- // if system:admin then return
- if (currentUser && currentUser.groups &&
- currentUser.groups.indexOf("system:cluster-admins") !== -1) {
- return $q.when({ });
- }
- var oc_roles = getRegistryRoles(currentUser, project);
- if (oc_roles.indexOf(registryAdmin) !== -1) {
- // for templates with registryAdmin
- // if registryAdmin role exists then return
- return $q.when({ });
- }
- return policy.addToRole(project, registryAdmin, subject);
- }
-
- function isSameUser(currUser, userName) {
- return currUser ? toName(currUser) === toName(userName) : false;
- }
-
- return {
- subjectRoleBindings: subjectRoleBindings,
- subjectIsMember: subjectIsMember,
- formatMembers: formatMembers,
- shareImages: shareImages,
- sharedImages: sharedImages,
- getAllRoles: getAllRoles,
- isRegistryRole: isRegistryRole,
- isRoles: isRoles,
- getRegistryRolesMap: getRegistryRolesMap,
- getRegistryRoles: getRegistryRoles,
- getGroupsWithMember: getGroupsWithMember,
- getProjectsWithMember: getProjectsWithMember,
- getMembershipOfUser: getMembershipOfUser,
- isSameUser: isSameUser,
- makeRegistryAdmin: makeRegistryAdmin,
- hasRegistryRole: hasRegistryRole,
- };
- }
- ])
-
- .directive('projectPanel', [
- 'kubeLoader',
- 'kubeSelect',
- 'projectData',
- 'roleActions',
- function(loader, select, projectData, roleActions) {
- return {
- restrict: 'A',
- scope: true,
- link: function(scope, element, attrs) {
- var tab = 'main';
- scope.tab = function(name, ev) {
- if (ev) {
- tab = name;
- ev.stopPropagation();
- }
- return tab === name;
- };
- var currProject = scope.id;
- angular.extend(scope, projectData);
- angular.extend(scope, roleActions);
- loader.load("Project", null, currProject);
- scope.project = function() {
- return select().kind("Project")
- .name(currProject)
- .one();
- };
- },
- templateUrl: "views/project-panel.html"
- };
- }
- ])
-
- .directive('projectBody', [
- 'projectData',
- function(data) {
- return {
- restrict: 'A',
- templateUrl: 'views/project-body.html',
- link: function(scope, element, attrs) {
- scope.sharedImages = data.sharedImages;
- },
- };
- }
- ])
-
- .directive('userBody', [
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/user-body.html',
- link: function(scope, element, attrs) {
- },
- };
- }
- ])
-
- .directive('groupPanel', [
- 'kubeLoader',
- 'kubeSelect',
- 'projectData',
- function(loader, select, projectData) {
- return {
- restrict: 'A',
- scope: true,
- link: function(scope, element, attrs) {
- var tab = 'main';
- scope.tab = function(name, ev) {
- if (ev) {
- tab = name;
- ev.stopPropagation();
- }
- return tab === name;
- };
-
- var currGroup = scope.id;
- loader.load("Groups");
- scope.group = function() {
- return select().kind("Group")
- .name(currGroup)
- .one();
- };
- scope.projects = function() {
- return select().kind("Project");
- };
- angular.extend(scope, projectData);
- },
- templateUrl: "views/group-panel.html"
- };
- }
- ])
-
- .directive('userPanel', [
- 'kubeLoader',
- 'kubeSelect',
- 'projectData',
- 'projectActions',
- function(loader, select, projectData, projectAction) {
- return {
- restrict: 'A',
- scope: true,
- link: function(scope, element, attrs) {
- var tab = 'main';
- scope.tab = function(name, ev) {
- if (ev) {
- tab = name;
- ev.stopPropagation();
- }
- return tab === name;
- };
-
- var currUser = scope.id;
- loader.load("Users");
- angular.extend(scope, projectData);
- angular.extend(scope, projectAction);
- scope.user = function() {
- return select().kind("User")
- .name(currUser)
- .one();
- };
- scope.groups = function() {
- return select().kind("Group");
- };
- scope.projects = function() {
- return select().kind("Project");
- };
- },
- templateUrl: "views/user-panel.html"
- };
- }
- ])
-
- .directive('projectListing',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/project-listing.html'
- };
- }
- )
-
- .factory('projectActions', [
- '$modal',
- 'projectData',
- function($modal, projectData) {
- function createProject(currentUser) {
- return $modal.open({
- controller: 'ProjectModifyCtrl',
- templateUrl: 'views/project-modify.html',
- resolve: {
- dialogData: function() {
- return { currUser: currentUser };
- }
- },
- }).result;
- }
-
- function modifyProject(project) {
- return $modal.open({
- animation: false,
- controller: 'ProjectModifyCtrl',
- templateUrl: 'views/project-modify.html',
- resolve: {
- dialogData: function() {
- return { project: project };
- }
- },
- }).result;
- }
- function removeProject(project) {
- return $modal.open({
- animation: false,
- controller: 'ProjectModifyCtrl',
- templateUrl: 'views/project-delete.html',
- resolve: {
- dialogData: function() {
- return { project: project };
- }
- },
- }).result;
- }
- function createGroup() {
- return $modal.open({
- controller: 'GroupNewCtrl',
- templateUrl: 'views/add-group-dialog.html',
- });
- }
- function addUserToGroup(groupObj) {
- return $modal.open({
- controller: 'GroupChangeCtrl',
- templateUrl: 'views/user-group-add.html',
- resolve:{
- fields: function() {
- return { group: groupObj };
- }
- }
- });
- }
- function removeUserFromGroup(user, groupObj) {
- return $modal.open({
- controller: 'GroupChangeCtrl',
- templateUrl: 'views/user-group-remove.html',
- resolve:{
- fields: function() {
- return { group: groupObj, user: user };
- }
- }
- });
- }
- function removeGroup(projects, groupObj) {
- return $modal.open({
- controller: 'GroupChangeCtrl',
- templateUrl: 'views/group-delete.html',
- resolve:{
- fields: function() {
- var members = projectData.getProjectsWithMember(projects, groupObj.metadata.name);
- return { group: groupObj, projects: projects, members: members };
- }
- }
- });
- }
- function createUser() {
- return $modal.open({
- controller: 'UserNewCtrl',
- templateUrl: 'views/add-user-dialog.html',
- });
- }
- function modifyUser(userObj) {
- return $modal.open({
- animation: false,
- controller: 'UserChangeCtrl',
- templateUrl: 'views/user-modify.html',
- resolve: {
- fields: function() {
- return { user: userObj };
- }
- },
- }).result;
- }
- function addMemberToParent(memberObj) {
- return $modal.open({
- controller: 'UserChangeCtrl',
- templateUrl: 'views/user-add-membership.html',
- resolve:{
- fields: function() {
- return { memberObj: memberObj };
- }
- }
- });
- }
- function removeMemberFromParent(memberObj, parentObj) {
- return $modal.open({
- controller: 'UserChangeCtrl',
- templateUrl: 'views/user-remove-membership.html',
- resolve:{
- fields: function() {
- return { parentObj: parentObj, memberObj: memberObj };
- }
- }
- });
- }
- function removeUser(projects, groups, userObj) {
- return $modal.open({
- controller: 'UserChangeCtrl',
- templateUrl: 'views/user-delete.html',
- resolve:{
- fields: function() {
- var members = projectData.getMembershipOfUser(projects, groups, userObj.metadata.name);
- return { user: userObj, projects: projects, groups: groups,
- members: members };
- }
- }
- });
- }
- return {
- createProject: createProject,
- modifyProject: modifyProject,
- createGroup: createGroup,
- createUser: createUser,
- removeProject: removeProject,
- removeUser: removeUser,
- modifyUser: modifyUser,
- addMemberToParent: addMemberToParent,
- removeMemberFromParent: removeMemberFromParent,
- removeGroup: removeGroup,
- addUserToGroup: addUserToGroup,
- removeUserFromGroup: removeUserFromGroup,
- };
- }
- ])
-
- .factory('roleActions', [
- '$modal',
- function($modal) {
- function addMember(project) {
- return $modal.open({
- controller: 'MemberNewCtrl',
- templateUrl: 'views/add-member-role-dialog.html',
- resolve: {
- fields: function() {
- return { namespace: toName(project) };
- }
- },
- });
- }
- function changeRole(member, roleMp, roles, project) {
- return $modal.open({
- controller: 'ChangeRoleCtrl',
- templateUrl: function() {
- if (roles.indexOf(roleMp.displayRole) >= 0) {
- return 'views/remove-role-dialog.html';
- } else {
- return 'views/add-role-dialog.html';
- }
- },
- resolve: {
- fields: function() {
- return { member: member, ocRole: roleMp.ocRole,
- displayRole: roleMp.displayRole, roles: roles,
- namespace: toName(project) };
- }
- },
- });
- }
- return {
- addMember: addMember,
- changeRole: changeRole,
- };
- }
- ])
-
- .controller('ChangeRoleCtrl', [
- '$q',
- '$scope',
- 'projectPolicy',
- 'kubeLoader',
- 'kubeSelect',
- 'fields',
- function($q, $scope, projectPolicy, loader, kselect, fields) {
- $scope.fields = fields;
- var namespace = $scope.fields.namespace;
-
- $scope.performCreate = function performCreate() {
- var role = $scope.fields.ocRole;
- var memberObj = $scope.fields.member;
- var subject = {
- kind: memberObj.kind,
- name: memberObj.metadata.name,
- };
- return projectPolicy.addToRole(namespace, role, subject);
- };
-
- $scope.performRemove = function performRemove() {
- var role = $scope.fields.ocRole;
- var memberObj = $scope.fields.member;
- var subject = {
- kind: memberObj.kind,
- name: memberObj.metadata.name,
- };
- return projectPolicy.removeFromRole(namespace, role, subject);
- };
- }
- ])
-
- .controller('MemberNewCtrl', [
- '$q',
- '$scope',
- 'projectData',
- 'projectPolicy',
- 'kubeLoader',
- 'kubeSelect',
- 'fields',
- 'gettextCatalog',
- function($q, $scope, projectData, projectPolicy, loader, kselect, fields, gettextCatalog) {
- const _ = gettextCatalog.getString.bind(gettextCatalog);
- var selectMember = _("Select Member");
- var NAME_RE = /^[a-z0-9_.]([-a-z0-9@._:]*[a-z0-9._:])?$/;
- var selectRole = _("Select Role");
-
- loader.watch("User", $scope);
- loader.watch("Group", $scope);
-
- $scope.selected = {
- member: selectMember,
- getMembers: getAllMembers,
- displayRole: selectRole,
- roles: projectData.getRegistryRolesMap(),
- kind: "",
- ocRole: "",
- };
- $scope.itemTracker = function(item) {
- return item.kind + "/" + item.metadata.name;
- };
- var namespace = fields.namespace;
-
- /*
- * This function is called during Angular rendering. Make sure we
- * use the same array over and over again, so angular doesn't
- * try to digest again.
- */
- function getAllMembers() {
- var users = kselect().kind("User");
- var groups = kselect().kind("Group");
- var members = [];
- angular.forEach(users, function(user) {
- members.push(user);
- });
- angular.forEach(groups, function(group) {
- members.push(group);
- });
- return members;
- }
- function validate(memberName, role) {
- var defer = $q.defer();
- var ex;
- if (memberName !== undefined) {
- if (!memberName)
- ex = new Error("The member name cannot be empty.");
- else if (memberName === selectMember)
- ex = new Error("Please select a valid Member.");
- else if (!NAME_RE.test(memberName))
- ex = new Error("The member name contains invalid characters. Only letters, numbers, spaces and the following symbols are allowed: , = @ . _");
-
- if (ex) {
- ex.target = "#add_member_group";
- defer.reject(ex);
- }
- }
- if (!role || role === selectRole) {
- ex = new Error("Please select a valid Role.");
- ex.target = "#add_role";
- defer.reject(ex);
- }
-
- if (!ex) {
- defer.resolve();
- }
-
- return defer.promise;
- }
- $scope.performCreate = function performCreate() {
- var role = $scope.selected.ocRole;
- var memberName = $scope.selected.memberName;
- var member = $scope.selected.member;
- var memberObj, kind;
- if (memberName && memberName === member) {
- // dropdown value selected
- memberObj = $scope.selected.memberObj;
- memberName = memberObj.metadata.name;
- kind = memberObj.kind;
- } else if (memberName && member === selectMember) {
- // input field has value
- kind = "User";
- } else if (!memberName && member === selectMember) {
- // nothing selected
- memberName = selectMember;
- kind = null;
- }
-
- return validate(memberName, role).then(function() {
- var subject = {
- kind: kind,
- name: memberName,
- };
- return projectPolicy.addToRole(namespace, role, subject);
- });
- };
- }
- ])
-
- .controller('ProjectModifyCtrl', [
- '$q',
- '$scope',
- 'kubeSelect',
- "dialogData",
- "projectData",
- '$location',
- '$timeout',
- "kubeMethods",
- "gettextCatalog",
- function($q, $scope, kselect, dialogData, projectData, $location, $timeout, methods, gettextCatalog) {
- var project = dialogData.project || { };
- var meta = project.metadata || { };
- var annotations = meta.annotations || { };
- const _ = gettextCatalog.getString.bind(gettextCatalog);
-
- var DISPLAY = "openshift.io/display-name";
- var DESCRIPTION = "openshift.io/description";
-
- var fields = {
- name: meta.name || "",
- display: annotations[DISPLAY] || "",
- description: annotations[DESCRIPTION] || "",
- access: null,
- };
-
- /*
- * This data may not be available yet, so continue to ask until it is.
- * The called function takes care of not making duplicate requests.
- */
- var timr;
- function updateShared() {
- timr = null;
- if (fields.access === null)
- fields.access = projectData.sharedImages(meta.name);
- if (fields.access === null)
- timr = $timeout(updateShared, 500);
- }
- updateShared();
- $scope.$on("$destroy", function() {
- if (timr !== null)
- $timeout.cancel(timr);
- });
-
- angular.extend($scope, projectData);
- $scope.fields = fields;
- $scope.labels = {
- access: {
- "private": _("Private: Allow only specific users or groups to pull images"),
- "shared": _("Shared: Allow any authenticated user to pull images"),
- "anonymous" : _("Anonymous: Allow all unauthenticated users to pull images"),
- }
- };
-
- $scope.performDelete = function performDelete(project) {
- var promise = methods.delete(project)
- .then(function() {
- $location.path("/projects");
- }, function(ex) {
- return $q.reject(ex);
- });
-
- return promise;
- };
- $scope.performCreate = function performCreate() {
- var name = fields.name.trim();
- var request = {
- kind: "ProjectRequest",
- apiVersion:"v1",
- metadata:{ name: name, },
- displayName: fields.display.trim(),
- description: fields.description.trim()
- };
-
- return methods.check(request, { "metadata.name": "#project-new-name" })
- .then(function() {
- return methods.create(request);
- })
- .then(function() {
- return projectData.shareImages(name, fields.access);
- })
- .then(function() {
- return projectData.makeRegistryAdmin(name, dialogData.currUser);
- });
- };
-
- $scope.performModify = function performModify() {
- var anno = { };
- var data = { metadata: { annotations: anno } };
-
- var value = fields.display.trim();
- if (value !== annotations[DISPLAY])
- anno[DISPLAY] = value;
- value = fields.description.trim();
- if (value !== annotations[DESCRIPTION])
- anno[DESCRIPTION] = value;
-
- return methods.check(data, { })
- .then(function() {
- return $q.all([
- methods.patch(project, data),
- projectData.shareImages(project, fields.access)
- ]);
- });
- };
-
- angular.extend($scope, dialogData);
- }
- ])
-
- .controller('UserNewCtrl', [
- '$q',
- '$scope',
- "kubeMethods",
- function($q, $scope, methods) {
- var fields = {
- name: "",
- identities: ""
- };
-
- $scope.fields = fields;
-
- $scope.performCreate = function performCreate() {
- var identities = [];
- if (fields.identities.trim() !== "")
- identities = [fields.identities.trim()];
-
- var user = {
- "kind": "User",
- "apiVersion": "v1",
- "metadata": {
- "name": fields.name.trim()
- },
- "identities": identities
- };
-
- return methods.check(user, { "metadata.name": "#user_name" })
- .then(function() {
- return methods.create(user);
- });
- };
- }
- ])
-
- .factory('memberActions', [
- "kubeMethods",
- function(methods) {
- function removeUserFromGroup(user, group) {
- var userName = toName(user);
- var users = group.users || [];
- var index = users.indexOf(userName);
- if (index >= 0)
- users.splice(index, 1);
- var patchData = { "users": users };
- return methods.patch(group, patchData);
- }
- function addUserToGroup(user, group) {
- var userName = toName(user);
- var users = group.users || [];
- var index = users.indexOf(userName);
- if (index == -1)
- users.push(userName);
- var patchData = { "users": users };
- return methods.patch(group, patchData);
- }
- return {
- removeUserFromGroup: removeUserFromGroup,
- addUserToGroup: addUserToGroup,
- };
- }
- ])
-
- .controller('UserChangeCtrl', [
- '$q',
- '$scope',
- 'kubeSelect',
- 'kubeLoader',
- "kubeMethods",
- 'projectData',
- 'projectPolicy',
- '$location',
- 'memberActions',
- "fields",
- "gettextCatalog",
- function($q, $scope, kselect, loader, methods, projectData, projectPolicy, $location, memberActions, fields, gettextCatalog) {
- const _ = gettextCatalog.getString.bind(gettextCatalog);
- loader.watch("Group", $scope);
- loader.watch("Project", $scope);
-
- function getMembers() {
- var members = [];
- var groups = getGroups();
- var projects = getProjects();
- angular.forEach(groups, function(group) {
- members.push(group);
- });
- angular.forEach(projects, function(project) {
- members.push(project);
- });
- return members;
- }
- function getProjects() {
- return kselect().kind("Project");
- }
- function getGroups() {
- return kselect().kind("Group");
- }
- $scope.itemTracker = function(item) {
- return item.kind + "/" + item.metadata.name;
- };
- $scope.selected = {
- member: _("Select Member"),
- getMembers: getMembers,
- roles: projectData.getRegistryRolesMap,
- role: _("Select Role"),
- };
- angular.extend($scope, projectData);
- $scope.fields = fields;
- if (fields.user && fields.user.identities)
- $scope.fields.identities = fields.user.identities.toString();
- else
- $scope.fields.identities = '';
-
- $scope.performModify = function performModify() {
- var identities = [];
- var user = $scope.fields.user;
- var data = { "identities": identities };
-
- if (fields.identities.trim() !== "") {
- var idList = fields.identities.trim().split(",");
- identities.push.apply(identities, idList);
- }
-
- return methods.check(data, { })
- .then(function() {
- return $q.all([
- methods.patch(user, data),
- ]);
- });
- };
-
- $scope.performDelete = function performDelete(user) {
- var chain = $q.when();
-
- chain = removeMemberFromParents(user);
- var promise = chain.then(function() {
- $location.path("/projects");
- }, function(ex) {
- if (ex.code === 404) {
- loader.handle(user, true, "User");
- $location.path("/projects");
- } else {
- return $q.reject(ex);
- }
- });
-
- return promise;
- };
- function removeMemberFromParents(member) {
- var chain = $q.when();
- var groups = projectData.getGroupsWithMember(getGroups(), member.metadata.name);
- angular.forEach(groups, function(g) {
- chain = chain.then(function() {
- return memberActions.removeUserFromGroup(member, g);
- });
- });
- var projects = projectData.getProjectsWithMember(getProjects(), member.metadata.name);
- angular.forEach(projects, function(project) {
- var subjectRoleBindings = projectData.subjectRoleBindings(member.metadata.name, project.metadata.name);
- var subject = {
- kind: member.kind,
- name: member.metadata.name,
- };
- chain = chain.then(function() {
- return projectPolicy.removeMemberFromProject(
- project.metadata.name, subjectRoleBindings, subject);
- });
- });
- chain = chain.then(function() {
- return methods.delete(member);
- });
- return chain;
- }
-
- $scope.addMemberToParent = function addMemberToParent() {
- if ($scope.selected.parentObj.kind === "Project") {
- var project = $scope.selected.parentObj.metadata.name;
- var memberObj = $scope.fields.memberObj;
- var role = $scope.selected.ocRole;
- var subject = {
- kind: memberObj.kind,
- name: memberObj.metadata.name,
- };
- return projectPolicy.addToRole(project, role, subject);
- } else if ($scope.selected.parentObj.kind === "Group") {
- return memberActions.addUserToGroup($scope.fields.memberObj, $scope.selected.parentObj);
- }
- };
-
- $scope.removeMemberFromParent = function removeMemberFromParent() {
- if ($scope.fields.parentObj.kind === "Group") {
- return memberActions.removeUserFromGroup($scope.fields.memberObj, $scope.fields.parentObj);
- } else {
- // Project
- var member = $scope.fields.memberObj;
- var project = $scope.fields.parentObj.metadata.name;
- var subjectRoleBindings = projectData.subjectRoleBindings(member.metadata.name, project);
- var subject = {
- kind: member.kind,
- name: member.metadata.name,
- };
- return projectPolicy.removeMemberFromProject(project, subjectRoleBindings, subject);
- }
- };
- }
- ])
-
- .controller('GroupChangeCtrl', [
- '$q',
- '$scope',
- 'kubeLoader',
- 'kubeSelect',
- "kubeMethods",
- 'projectData',
- 'memberActions',
- 'projectPolicy',
- '$location',
- "fields",
- 'gettextCatalog',
- function($q, $scope, loader, kselect, methods, projectData, memberActions, projectPolicy, $location, fields, gettextCatalog) {
- const _ = gettextCatalog.getString.bind(gettextCatalog);
- loader.watch("User", $scope);
- loader.watch("Project", $scope);
-
- function getUsers() {
- return kselect().kind("User");
- }
- function getProjects() {
- return kselect().kind("Project");
- }
- $scope.select = {
- member: _("Select Member"),
- getMembers: getUsers,
- };
- angular.extend($scope, projectData);
- $scope.fields = fields;
- $scope.fields.grpProjects = projectData.getProjectsWithMember(getProjects(), fields.group.metadata.name);
- function removeMemberFromParents(member) {
- var chain = $q.when();
- var projects = projectData.getProjectsWithMember(getProjects(), member.metadata.name);
- angular.forEach(projects, function(project) {
- var subjectRoleBindings = projectData.subjectRoleBindings(member.metadata.name, project.metadata.name);
- var subject = {
- kind: member.kind,
- name: member.metadata.name,
- };
- chain = chain.then(function() {
- return projectPolicy.removeMemberFromProject(
- project.metadata.name, subjectRoleBindings, subject);
- });
- });
- chain = chain.then(function() {
- return methods.delete(member);
- });
- return chain;
- }
- $scope.performDelete = function performDelete(group) {
- var chain = $q.when();
-
- chain = removeMemberFromParents(group);
- var promise = chain.then(function() {
- $location.path("/projects");
- }, function(ex) {
- if (ex.code === 404) {
- $location.path("/projects");
- } else {
- return $q.reject(ex);
- }
- });
-
- return promise;
- };
- $scope.addUserToGroup = function addUserToGroup() {
- return memberActions.addUserToGroup($scope.select.member, $scope.fields.group);
- };
- $scope.removeUserFromGroup = function removeUserFromGroup() {
- return memberActions.removeUserFromGroup($scope.fields.user, $scope.fields.group);
- };
- }
- ])
-
- .controller('GroupNewCtrl', [
- '$q',
- '$scope',
- "kubeMethods",
- function($q, $scope, methods) {
- var fields = {
- name: ""
- };
-
- $scope.fields = fields;
- $scope.performCreate = function performCreate() {
- var group = {
- "kind": "Group",
- "apiVersion": "v1",
- "metadata": {
- "name": fields.name.trim()
- }
- };
-
- return methods.check(group, { "metadata.name": "#group_name" })
- .then(function() {
- return methods.create(group);
- });
- };
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/registry.js b/pkg/kubernetes/scripts/registry.js
deleted file mode 100644
index d256abb65..000000000
--- a/pkg/kubernetes/scripts/registry.js
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
- require('angular-route');
- require('angular-gettext/dist/angular-gettext.js');
- require('angular-bootstrap-npm/dist/angular-bootstrap.js');
-
- require('./app');
- require('./date');
- require('./images');
- require('./projects');
- require('./policy');
- require('./kube-client');
- require('./kube-client-cockpit');
-
- require('../views/registry-dashboard-page.html');
-
- var MAX_RECENT_STREAMS = 15;
- var MAX_RECENT_TAGS = 8;
-
- angular.module('registry', [
- 'ngRoute',
- 'ui.bootstrap',
- 'ui.bootstrap.popover',
- 'gettext',
- 'kubernetes.app',
- 'kubernetes.date',
- 'registry.images',
- 'registry.projects',
- 'registry.policy',
- 'registryUI.date',
- 'kubeClient',
- 'kubeClient.cockpit'
- ])
-
- .config([
- '$routeProvider',
- 'KubeWatchProvider',
- 'KubeRequestProvider',
- 'KubeDiscoverSettingsProvider',
- 'MomentLibProvider',
- '$provide',
- function($routeProvider, KubeWatchProvider, KubeRequestProvider,
- KubeDiscoverSettingsProvider, MomentLibProvider, $provide) {
- $routeProvider
- .when('/', {
- templateUrl: 'views/registry-dashboard-page.html',
- controller: 'DashboardCtrl',
- reloadOnSearch: false,
- })
- .otherwise({ redirectTo: '/' });
-
- /* Tell the kube-client code to use cockpit watches and requests */
- KubeWatchProvider.KubeWatchFactory = "CockpitKubeWatch";
- KubeRequestProvider.KubeRequestFactory = "CockpitKubeRequest";
- KubeDiscoverSettingsProvider.KubeDiscoverSettingsFactory = "cockpitKubeDiscoverSettings";
- MomentLibProvider.MomentLibFactory = "momentLib";
-
- $provide.decorator("$exceptionHandler",
- ['$delegate',
- '$log',
- function($delegate, $log) {
- return function (exception, cause) {
- /* Displays an oops if we're running in cockpit */
- if (window.parent !== window && window.name.indexOf("cockpit1:") === 0)
- window.parent.postMessage("\n{ \"command\": \"oops\" }", "*");
-
- $delegate(exception, cause);
- };
- }]);
- }
- ])
-
- .controller('DashboardCtrl', [
- '$scope',
- 'kubeLoader',
- 'kubeSelect',
- 'KubeDiscoverSettings',
- 'imageData',
- 'imageActions',
- 'projectActions',
- 'projectData',
- 'projectPolicy',
- 'filterService',
- function($scope, loader, select, discoverSettings, imageData, imageActions, projectActions, projectData, projectPolicy, filter) {
- loader.load("projects");
- /* Watch the for project access changes */
- projectPolicy.watch($scope);
-
- /*
- * For now the dashboard has to watch all images in
- * order to display the 'Images pushed recently' data
- *
- * In the future we want to have a metadata or filtering
- * service that we can query for that data.
- */
- imageData.watchImages($scope);
-
- function compareVersion(a, b) {
- a = (a.metadata || { }).resourceVersion || 0;
- b = (b.metadata || { }).resourceVersion || 0;
- return b - a;
- }
- function compareCreated(a, b) {
- a = a.items ? a.items[0] : {};
- b = b.items ? b.items[0] : {};
- a = a.created || "";
- b = b.created || "";
- return (b < a ? -1 : (b > a ? 1 : 0));
- }
-
- select.register("buildRecentStreams", function() {
- var link;
- var array = [];
- for (link in this)
- array.push(this[link]);
- array.sort(compareVersion);
- array.splice(MAX_RECENT_STREAMS);
-
- var result = [];
- var status, tags, stream, i, len, total;
- for (i = 0, len = array.length; i < len; i++) {
- stream = array[i];
-
- status = stream.status || { };
- tags = (status.tags || []).slice();
- tags.sort(compareCreated);
- total = tags.length;
- tags.splice(MAX_RECENT_TAGS);
-
- if (tags.length > 0)
- result.push({ stream: stream, tags: tags, truncated: total > tags.length });
- }
-
- return result;
- });
-
- function setShowDockerPushCommands(visible) {
- if (visible != $scope.showDockerPushCommands) {
- $scope.showDockerPushCommands = visible;
- $scope.$applyAsync();
- }
- }
-
- function updateShowDockerPushCommands() {
- var ns = filter.namespace();
-
- if (ns) {
- discoverSettings().then(function(settings) {
- projectPolicy.subjectAccessReview(ns, settings.currentUser, 'update', 'imagestreamimages')
- .then(setShowDockerPushCommands);
- });
- } else {
- // no current project, always show push commands; too expensive to iterate through all projects
- setShowDockerPushCommands(true);
- }
- }
-
- // watch for project changes to update showDockerPushCommands, and initialize it
- $scope.$on("$routeUpdate", updateShowDockerPushCommands);
- updateShowDockerPushCommands();
-
- $scope.createProject = projectActions.createProject;
- $scope.createImageStream = imageActions.createImageStream;
- $scope.sharedImages = projectData.sharedImages;
-
- $scope.recentlyUpdated = function recentlyUpdated() {
- return select().kind("ImageStream")
- .buildRecentStreams();
- };
-
- $scope.projects = function projects() {
- return select().kind("Project")
- .statusPhase("Active");
- };
-
- $scope.filter = filter;
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/tags.js b/pkg/kubernetes/scripts/tags.js
deleted file mode 100644
index 5af838b6c..000000000
--- a/pkg/kubernetes/scripts/tags.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
-
- var REGTAG = /[\u200B\s,]+/;
- function parseNodes(parent) {
- var child, text;
- var names = [];
- function pushName(name) {
- if (name)
- names.push(name);
- }
- for (child = parent.firstChild; child; child = child.nextSibling) {
- text = "";
- if (child.nodeType == 3)
- text = child.nodeValue.trim();
- else if (child.nodeType == 1 && child.hasAttribute("value"))
- text = child.getAttribute("value");
- text.split(REGTAG).forEach(pushName);
- }
- return names;
- }
-
- function buildNodes(names) {
- var elements = [ document.createTextNode("\u200B") ];
- angular.forEach(names, function(name) {
- var span = document.createElement("span");
- span.setAttribute("contenteditable", "false");
- span.setAttribute("class", "image-tag");
- span.setAttribute("value", name);
- span.appendChild(document.createTextNode(name));
- var close = document.createElement("a");
- close.setAttribute("class", "pficon pficon-close");
- span.appendChild(close);
- elements.push(span);
- elements.push(document.createTextNode("\u00A0"));
- });
- return elements;
- }
-
- function parseSpec(spec) {
- var names = [];
- angular.forEach(spec.tags || [ ], function(tag) {
- names.push(tag.name);
- });
- return names;
- }
-
- function buildSpec(names, spec, insecure, pull) {
- var already = { };
- if (!spec)
- spec = { };
- angular.forEach(spec.tags || [], function(tag) {
- already[tag.name] = tag;
- });
- var tags = [ ];
- angular.forEach(names, function(name) {
- if (name in already) {
- already[name].importPolicy = { "insecure": insecure };
- tags.push(already[name]);
- } else {
- tags.push({
- name: name,
- "importPolicy": { "insecure": insecure },
- from: {
- kind: "DockerImage",
- name: pull + ":" + name,
- },
- });
- }
- });
- spec.tags = tags;
- return spec;
- }
-
- angular.module('registry.tags', [ ])
-
- .directive('imageTagEditor', [
- function() {
- return {
- restrict: 'A',
- transclude: true,
- scope: {
- tags: "=",
- },
- link: function(scope, element, attrs) {
- element.addClass("image-tag-editor");
- element.attr("tabindex", "0");
- element.attr("contenteditable", "true");
-
- var spans = buildNodes(scope.tags);
- element.append(spans);
-
- /* Select the last item when we get focus */
- var range = document.createRange();
- range.selectNodeContents(spans[spans.length - 1]);
- range.collapse(false);
- var sel = window.getSelection();
- sel.removeAllRanges();
- sel.addRange(range);
-
- element.on("click", function(ev) {
- var target = ev.target;
- var span = target.parentNode;
- if (target.nodeName.toLowerCase() == "a" && span.nodeName.toLowerCase() == "span")
- span.parentNode.removeChild(span);
- });
-
- /* When things change retag */
- element.on("blur keyup paste copy cut mouseup", function() {
- var tags = parseNodes(element[0]);
- while (scope.tags.length > 0)
- scope.tags.pop();
- tags.forEach(function(tag) {
- scope.tags.push(tag);
- });
- });
- }
- };
- }
- ])
-
- .factory('imageTagData', [
- function() {
- return {
- parseSpec: parseSpec,
- buildSpec: buildSpec,
- buildNodes: buildNodes,
- parseNodes: parseNodes,
- };
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/test-connection.js b/pkg/kubernetes/scripts/test-connection.js
deleted file mode 100644
index 84fa8a933..000000000
--- a/pkg/kubernetes/scripts/test-connection.js
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-import QUnit from "qunit-tests";
-
-var angular = require("angular");
-require("./connection");
-
-(function() {
- var fixtures = [];
-
- var configJson;
-
- /* Filled in with a function */
- var inject;
-
- var module = angular.module("kubernetes.connection.tests", [
- "kubeClient",
- 'kubeClient.cockpit',
- "kubernetes.connection",
- ]);
-
- function injectLoadFixtures(fixtures) {
- inject([
- "kubeLoader",
- function(loader, data) {
- loader.reset(true);
- if (fixtures)
- loader.handle(fixtures);
- }
- ]);
- }
-
- QUnit.test("sessionCertificates test", function(assert) {
- var done = assert.async();
- assert.expect(5);
-
- injectLoadFixtures(fixtures);
- inject([
- "sessionCertificates",
- function(sessionCertificates) {
- sessionCertificates.trustCert(null, "data");
- assert.equal(sessionCertificates.getCert("localhost"), "data", "data retrive");
- assert.equal(sessionCertificates.getCert(null), "data", "null is localhost");
- sessionCertificates.trustCert({}, "data1");
- assert.equal(sessionCertificates.getCert("localhost"), "data1", "blank server retrive");
- assert.equal(sessionCertificates.getCert("address"), undefined, "missing is undefined");
- sessionCertificates.trustCert({ server: "address" }, "address-data");
- assert.equal(sessionCertificates.getCert("address"), undefined, "address data");
- done();
- }
- ]);
- });
-
- QUnit.test("cockpitKubectlConfig parseKubeConfig", function (assert) {
- var done = assert.async();
- assert.expect(5);
-
- injectLoadFixtures(fixtures);
- inject(["cockpitKubectlConfig", function (ckg) {
- var alpha = {
- "address": "alfa.org",
- "headers": {
- "Authorization": "Bearer provider-token"
- },
- "port": 443,
- "tls": {
- "validate": false,
- "authority": undefined,
- "certificate": undefined,
- "key": undefined,
- }
- };
-
- var bravo = {
- "address": "bravo.org",
- "headers": {
- "Authorization": "Bearer provider-access-token"
- },
- "port": 8080,
- "tls": {
- "authority": {
- "file": "cert-authority-file"
- },
- "certificate": undefined,
- "key": undefined,
- "validate": true
- }
- };
-
- var charlie = {
- "address": "charlie.org",
- "headers": {
- "Authorization": "Bearer token"
- },
- "port": 8080
- };
-
- var delta1 = {
- "address": "delta.org",
- "headers": {},
- "port": 443,
- "tls": {
- "authority": undefined,
- "certificate": {
- "file": "cert-file"
- },
- "key": {
- "file": "key-file"
- },
- "validate": true
- }
- };
-
- var delta2 = {
- "address": "delta.org",
- "headers": {
- "Authorization": "Basic dXNlcjpwYXNzd29yZA=="
- },
- "port": 443,
- "tls": {
- "validate": true,
- "authority": undefined,
- "certificate": undefined,
- "key": undefined,
- }
- };
- var configData = JSON.stringify(configJson);
- assert.deepEqual(ckg.parseKubeConfig(configData), alpha);
- assert.deepEqual(ckg.parseKubeConfig(configData, "bravo-with-access-token-auth-provider"), bravo);
- assert.deepEqual(ckg.parseKubeConfig(configData, "charlie-with-token"), charlie);
- assert.deepEqual(ckg.parseKubeConfig(configData, "delta-with-cert"), delta1);
- assert.deepEqual(ckg.parseKubeConfig(configData, "delta-with-basic"), delta2);
- done();
- }]);
- });
-
- QUnit.test("connectionActions prepareData", function (assert) {
- var done = assert.async();
- assert.expect(6);
-
- injectLoadFixtures(fixtures);
- inject(["connectionActions", function(connectionActions) {
- var cluster, context, user, data, config;
- data = connectionActions.prepareData();
- assert.deepEqual(data, {
- "cluster": {
- "cluster": {
- "server": "http://localhost:8080"
- },
- "name": "localhost:8080"
- },
- "context": {
- "context": {
- "cluster": "localhost:8080",
- "user": undefined
- },
- "name": "localhost:8080/noauth"
- },
- "user": undefined
- }, "got right empty values");
-
- cluster = {
- "cluster": { "server": "https://127.0.0.1:8000" },
- "name": "name"
- };
- user = {
- "user": { "token": "token" },
- "name": "user"
- };
-
- context = {
- "context": {
- "user": "user",
- "cluster": "name"
- },
- name : "existing"
- };
-
- config = {
- users: [user],
- clusters: [cluster],
- contexts: [ context ]
- };
-
- data = connectionActions.prepareData(config, cluster, user);
- assert.deepEqual(data, {
- "cluster": {
- "cluster": { "server": "https://127.0.0.1:8000" },
- "name": "name"
- },
- "context": { "name" : "existing" },
- "user": {
- "user": { "token": "token" },
- "name": "user"
- }
- }, "matched existing");
-
- // remove names
- delete cluster.name;
- delete user.name;
- data = connectionActions.prepareData({}, cluster, user);
- assert.deepEqual(data, {
- "cluster": {
- "cluster": { "server": "https://127.0.0.1:8000" },
- "name": "127-0-0-1:8000"
- },
- "context": {
- "name": "127-0-0-1:8000/user/127-0-0-1:8000",
- "context": {
- "user": "user/127-0-0-1:8000",
- "cluster": "127-0-0-1:8000"
- }
- },
- "user": {
- "user": { "token": "token" },
- "name": "user/127-0-0-1:8000"
- },
- }, "generated names");
-
- // No dups
- config = {
- contexts: [{ "name": "127-0-0-1:8000/user/127-0-0-1:8000" }],
- };
- data = connectionActions.prepareData(config, cluster, user);
- var pos = data.context.name.indexOf("127-0-0-1:8000/user/127-0-0-1:8000");
- assert.ok(data.context.name != "127-0-0-1:8000/user/127-0-0-1:8000" && pos === 0, "dedup context name");
-
- config = {
- clusters: [{ "name": "127-0-0-1:8000" }],
- };
- delete cluster.name;
- data = connectionActions.prepareData(config, cluster, user);
- pos = data.cluster.name.indexOf("127-0-0-1:8000");
- assert.ok(data.cluster.name != "127-0-0-1:8000" && pos === 0, "dedup cluster name");
-
- config = {
- users: [{ "name": "user/127-0-0-1:8000" }],
- };
- delete user.name;
- data = connectionActions.prepareData(config, cluster, user);
- pos = data.user.name.indexOf("user/127-0-0-1:8000");
- assert.ok(data.user.name != "user/127-0-0-1:8000" && pos === 0, "dedup user name");
-
- done();
- }]);
- });
-
- angular.module('exceptionOverride', []).factory('$exceptionHandler', function() {
- return function(exception, cause) {
- exception.message += ' (caused by "' + cause + '")';
- throw exception;
- };
- });
-
- configJson = {
- "clusters": [{
- "name": "alfa",
- "cluster": {
- "insecure-skip-tls-verify": true,
- "server": "https://alfa.org"
- }
- }, {
- "name": "bravo",
- "cluster": {
- "server": "https://bravo.org:8080",
- "certificate-authority": "cert-authority-file"
- }
- }, {
- "name": "charlie",
- "cluster": {
- "server": "http://charlie.org"
- }
- }, {
- "name": "delta",
- "cluster": {
- "server": "https://delta.org:443"
- }
- }],
- "contexts": [{
- "name": "alfa-with-token-auth-provider",
- "context": {
- "cluster": "alfa",
- "user": "token-auth-provider"
- }
- }, {
- "name": "bravo-with-access-token-auth-provider",
- "context": {
- "cluster": "bravo",
- "user": "access-token-auth-provider"
- }
- }, {
- "name": "charlie-with-token",
- "context": {
- "cluster": "charlie",
- "user": "token"
- }
- }, {
- "name": "delta-with-cert",
- "context": {
- "cluster": "delta",
- "user": "cert"
- }
- }, {
- "name": "delta-with-basic",
- "context": {
- "cluster": "delta",
- "user": "basic"
- }
- }],
- "current-context": "alfa-with-token-auth-provider",
- "users": [{
- "name": "token-auth-provider",
- "user": {
- "auth-provider": {
- "config": {
- "token": "provider-token"
- },
- "name": "gcp"
- }
- }
- }, {
- "name": "access-token-auth-provider",
- "user": {
- "auth-provider": {
- "config": {
- "access-token": "provider-access-token"
- },
- "name": "gcp"
- }
- }
- }, {
- "name": "token",
- "user": {
- "token": "token"
- }
- }, {
- "name": "cert",
- "user": {
- "client-certificate": "cert-file",
- "client-key": "key-file"
- }
- }, {
- "name": "basic",
- "user": {
- "username": "user",
- "password": "password"
- }
- }]
- };
-
- module.run([
- '$injector',
- function($injector) {
- inject = function inject(func) {
- return $injector.invoke(func);
- };
- QUnit.start();
- }
- ]);
-
- angular.bootstrap(document, ['kubernetes.connection.tests']);
-}());
diff --git a/pkg/kubernetes/scripts/test-images.js b/pkg/kubernetes/scripts/test-images.js
deleted file mode 100644
index 955bf2529..000000000
--- a/pkg/kubernetes/scripts/test-images.js
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-import QUnit from "qunit-tests";
-
-var angular = require("angular");
-
-require('angular-gettext/dist/angular-gettext.js');
-require("./images");
-
-function suite(fixtures) {
- /* Filled in with a function */
- var inject;
-
- var module = angular.module("registry.images.tests", [
- "kubeClient",
- "registry.images",
- ]);
-
- function injectLoadFixtures(fixtures) {
- inject([
- "kubeLoader",
- function(loader) {
- loader.reset(true);
- if (fixtures)
- loader.handle(fixtures);
- }
- ]);
- }
-
- QUnit.test("filter containsTagImage", function (assert) {
- var done = assert.async();
- assert.expect(7);
-
- injectLoadFixtures(fixtures);
-
- inject([ "kubeSelect", "imageData", function(select, data) {
- var streams = select().containsTagImage("sha256:c1ee91e9f0f96ea280d17befdd968ce4e37653939fc9e5e36429cd9674a28719");
- assert.equal(streams.length, 2, "number ofstreams");
- assert.ok("/oapi/v1/namespaces/marmalade/imagestreams/busybee" in streams, "matched busybee");
- assert.ok("/oapi/v1/namespaces/marmalade/imagestreams/juggs" in streams, "matched juggs");
-
- streams = select().containsTagImage("sha256:0885eeaec4514820b2c879100425e9ea10beaf4412db7f67acfe53b4df2b9450");
- assert.equal(streams.length, 1, "one stream matched");
- assert.ok("/oapi/v1/namespaces/marmalade/imagestreams/juggs" in streams, "other stream matched juggs");
- assert.ok(!("/oapi/v1/namespaces/marmalade/imagestreams/busybee" in streams), "other stream not busybee");
-
- /* An unknown image */
- streams = select().containsTagImage("sha256:2077956b196342f92271663ec85124aef44ee486f141b7d48e6ce5be410d78f1");
- assert.equal(streams.length, 0, "no streams selected");
-
- done();
- }]);
- });
-
- QUnit.test("filter taggedBy", function (assert) {
- var done = assert.async();
- assert.expect(4);
-
- injectLoadFixtures(fixtures);
-
- inject(["kubeSelect", "imageData", function(select, data) {
- var tag = { "tag": "2.5", "items": [
- { "image": "sha256:beadfbc3da8d183c245ab5bad4dd185dacde72dbe81b270926e60e705e534afb" },
- { "image": "sha256:0885eeaec4514820b2c879100425e9ea10beaf4412db7f67acfe53b4df2b9450" }
- ] };
-
- var images = select().kind("Image")
- .taggedBy(tag);
- assert.equal(images.length, 2, "number of images");
- assert.ok("/oapi/v1/images/sha256:beadfbc3da8d183c245ab5bad4dd185dacde72dbe81b270926e60e705e534afb" in images, "matched busybee");
- assert.ok("/oapi/v1/images/sha256:0885eeaec4514820b2c879100425e9ea10beaf4412db7f67acfe53b4df2b9450" in images, "matched juggs");
-
- tag = { "tag": "2.5", "items": [
- { "image": "sha256:00329beccad118aa937e839d536d753ee612b67f8feb6adb519e7f5aa6e75fbe" },
- { "image": "sha256:0085eeaec4514820b2c879100425e9ea10beaf4412db7f67acfe53b4df2b9450" }
- ] };
-
- images = select().kind("Image")
- .taggedBy(tag);
- assert.equal(images.length, 0, "no images matched");
-
- done();
- }]);
- });
-
- QUnit.test("filter taggedFirst", function (assert) {
- var done = assert.async();
- assert.expect(4);
-
- injectLoadFixtures(fixtures);
-
- inject(["kubeSelect", "imageData", function(select, data) {
- var tag = { "tag": "2.5", "items": [
- { "image": "sha256:beadfbc3da8d183c245ab5bad4dd185dacde72dbe81b270926e60e705e534afb" },
- { "image": "sha256:0885eeaec4514820b2c879100425e9ea10beaf4412db7f67acfe53b4df2b9450" }
- ] };
-
- var images = select().kind("Image")
- .taggedFirst(tag);
- assert.equal(images.length, 1, "number of images");
- assert.ok("/oapi/v1/images/sha256:beadfbc3da8d183c245ab5bad4dd185dacde72dbe81b270926e60e705e534afb" in images, "matched busybee");
- assert.ok(!("/oapi/v1/images/sha256:0885eeaec4514820b2c879100425e9ea10beaf4412db7f67acfe53b4df2b9450" in images), "didn't match juggs");
-
- tag = { "tag": "2.5", "items": [
- { "image": "sha256:00329beccad118aa937e839d536d753ee612b67f8feb6adb519e7f5aa6e75fbe" },
- { "image": "sha256:0085eeaec4514820b2c879100425e9ea10beaf4412db7f67acfe53b4df2b9450" }
- ] };
-
- images = select().kind("Image")
- .taggedFirst(tag);
- assert.equal(images.length, 0, "no images matched");
-
- done();
- }]);
- });
-
- QUnit.test("filter listTagNames", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(fixtures);
-
- inject(["kubeSelect", "imageData", function(select, data) {
- var names = select().listTagNames("sha256:c1ee91e9f0f96ea280d17befdd968ce4e37653939fc9e5e36429cd9674a28719");
- assert.deepEqual(names, ["marmalade/busybee:latest", "marmalade/juggs:extratag"], "got right names");
-
- names = select().listTagNames("sha256:0885eeaec4514820b2c879100425e9ea10beaf4412db7f67acfe53b4df2b9450");
- assert.deepEqual(names, ["marmalade/juggs:latest"], "got another image tag name");
-
- names = select().listTagNames("sha256:2077956b196342f92271663ec85124aef44ee486f141b7d48e6ce5be410d78f1");
- assert.deepEqual(names, [], "no names returned");
-
- done();
- }]);
- });
-
- QUnit.test("split dockerImageManifest", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(fixtures);
-
- inject(["kubeSelect", "imageData", function(select, data) {
- var items = select().kind("DockerImageManifest")
- .name("sha256:63da16dc866fa7bfca4dd9d45b70feda28aa383c9ca1f1766c127ccc715a8cb7");
- assert.equal(items.length, 1, "only manifest returned");
-
- var item = items["/internal/manifests/sha256:63da16dc866fa7bfca4dd9d45b70feda28aa383c9ca1f1766c127ccc715a8cb7"];
- assert.ok(!!item, "got right manifest");
-
- assert.equal(item.manifest.history[0].v1Compatibility.config.Hostname, "13709f13afe1", "parsed manifest and compat");
-
- done();
- }]);
- });
-
- QUnit.test("filter dockerConfigLabels", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(fixtures);
-
- inject(["kubeSelect", "imageData", function(select, data) {
- var results = select().kind("Image")
- .dockerImageConfig()
- .dockerConfigLabels();
- assert.equal(results.length, 1, "got one set of labels");
-
- var again = select().kind("Image")
- .dockerImageConfig()
- .dockerConfigLabels();
- assert.strictEqual(results, again, "cached results");
-
- var labels = results["/oapi/v1/images/sha256:63da16dc866fa7bfca4dd9d45b70feda28aa383c9ca1f1766c127ccc715a8cb7"];
- assert.deepEqual(labels, { "Test": "Value", "version": "1.0" }, "got right labels");
-
- done();
- }]);
- });
-
- angular.module('exceptionOverride', []).factory('$exceptionHandler', function() {
- return function(exception, cause) {
- exception.message += ' (caused by "' + cause + '")';
- throw exception;
- };
- });
-
- module.run([
- '$injector',
- function($injector) {
- inject = function inject(func) {
- return $injector.invoke(func);
- };
- QUnit.start();
- }
- ]);
-
- angular.bootstrap(document, ['registry.images.tests']);
-}
-
-/* Invoke the test suite with this data */
-suite([
- { "kind": "ImageStream", "apiVersion": "v1",
- "metadata": { "name": "busybee", "namespace": "marmalade",
- "selfLink": "/oapi/v1/namespaces/marmalade/imagestreams/busybee",
- "uid": "4612c052-b44e-11e5-a4da-5254009e00f1"
- },
- "spec": {},
- "status": {
- "dockerImageRepository": "172.30.87.3:5000/marmalade/busybee",
- "tags": [
- { "tag": "0.x", "items": [
- { "created": "2016-01-06T08:19:58Z",
- "dockerImageReference": "172.30.87.3:5000/marmalade/busybee@sha256:beadfbc3da8d183c245ab5bad4dd185dacde72dbe81b270926e60e705e534afb",
- "image": "sha256:beadfbc3da8d183c245ab5bad4dd185dacde72dbe81b270926e60e705e534afb"
- } ]
- },
- { "tag": "latest", "items": [
- { "created": "2016-01-06T08:19:58Z",
- "dockerImageReference": "172.30.87.3:5000/marmalade/busybee@sha256:c1ee91e9f0f96ea280d17befdd968ce4e37653939fc9e5e36429cd9674a28719",
- "image": "sha256:c1ee91e9f0f96ea280d17befdd968ce4e37653939fc9e5e36429cd9674a28719"
- } ]
- }
- ]
- }
- },
- { "kind": "ImageStream", "apiVersion": "v1",
- "metadata": { "name": "juggs", "namespace": "marmalade",
- "selfLink": "/oapi/v1/namespaces/marmalade/imagestreams/juggs",
- "uid": "84e3a672-b44e-11e5-a4da-5254009e00f1"
- },
- "spec": {},
- "status": {
- "dockerImageRepository": "172.30.87.3:5000/marmalade/juggs",
- "tags": [
- { "tag": "2.11", "items": [
- { "created": "2016-01-06T08:21:43Z",
- "dockerImageReference": "172.30.87.3:5000/marmalade/juggs@sha256:b074b7b7905895741f7425ab4e78b9df384aaa518258d2e81d9e904ecf6c9f0f",
- "image": "sha256:b074b7b7905895741f7425ab4e78b9df384aaa518258d2e81d9e904ecf6c9f0f"
- } ]
- },
- { "tag": "2.5", "items": [
- { "created": "2016-01-06T08:21:46Z",
- "dockerImageReference": "172.30.87.3:5000/marmalade/juggs@sha256:d0329beccad118aa937e839d536d753ee612b67f8feb6adb519e7f5aa6e75fbe",
- "image": "sha256:d0329beccad118aa937e839d536d753ee612b67f8feb6adb519e7f5aa6e75fbe"
- } ]
- },
- { "tag": "latest", "items": [
- { "created": "2016-01-06T08:21:43Z",
- "dockerImageReference": "172.30.87.3:5000/marmalade/juggs@sha256:0885eeaec4514820b2c879100425e9ea10beaf4412db7f67acfe53b4df2b9450",
- "image": "sha256:0885eeaec4514820b2c879100425e9ea10beaf4412db7f67acfe53b4df2b9450"
- } ]
- },
- { "tag": "extratag", "items": [
- { "created": "2016-01-06T08:19:58Z",
- "dockerImageReference": "172.30.87.3:5000/marmalade/busybee@sha256:c1ee91e9f0f96ea280d17befdd968ce4e37653939fc9e5e36429cd9674a28719",
- "image": "sha256:c1ee91e9f0f96ea280d17befdd968ce4e37653939fc9e5e36429cd9674a28719"
- } ]
- }
- ]
- }
- },
- { "kind": "ImageStream", "apiVersion": "v1",
- "metadata": { "name": "origin", "namespace": "marmalade",
- "selfLink": "/oapi/v1/namespaces/marmalade/imagestreams/origin",
- "uid": "94813e0a-b44e-11e5-a4da-5254009e00f1"
- },
- "spec": {},
- "status": {
- "dockerImageRepository": "172.30.87.3:5000/marmalade/origin",
- "tags": [
- { "tag": "latest", "items": [
- { "created": "2016-01-06T08:22:10Z",
- "dockerImageReference": "172.30.87.3:5000/marmalade/origin@sha256:6077956b196342f92271663ec85124aef44ee486f141b7d48e6ce5be410d78f1",
- "image": "sha256:6077956b196342f92271663ec85124aef44ee486f141b7d48e6ce5be410d78f1"
- } ]
- }
- ]
- }
- },
-
- { "kind": "Image", "apiVersion": "v1", "metadata": {
- "name": "sha256:0885eeaec4514820b2c879100425e9ea10beaf4412db7f67acfe53b4df2b9450",
- "selfLink": "/oapi/v1/images/sha256:0885eeaec4514820b2c879100425e9ea10beaf4412db7f67acfe53b4df2b9450",
- },
- "dockerImageReference": "172.30.87.3:5000/marmalade/juggs@sha256:0885eeaec4514820b2c879100425e9ea10beaf4412db7f67acfe53b4df2b9450",
- "dockerImageMetadata": { "kind": "DockerImage", "apiVersion": "1.0", "Id": "",
- "Created": null, "ContainerConfig": {} },
- "dockerImageMetadataVersion": "1.0",
- },
- {
- "kind": "Image", "apiVersion": "v1", "metadata": {
- "name": "sha256:6077956b196342f92271663ec85124aef44ee486f141b7d48e6ce5be410d78f1",
- "selfLink": "/oapi/v1/images/sha256:6077956b196342f92271663ec85124aef44ee486f141b7d48e6ce5be410d78f1",
- },
- "dockerImageReference": "172.30.87.3:5000/marmalade/origin@sha256:6077956b196342f92271663ec85124aef44ee486f141b7d48e6ce5be410d78f1",
- "dockerImageMetadata": { "kind": "DockerImage", "apiVersion": "1.0", "Id": "",
- "Created": null, "ContainerConfig": {} },
- "dockerImageMetadataVersion": "1.0",
- },
- { "kind": "Image", "apiVersion": "v1",
- "metadata": {
- "name": "sha256:98842019ab49391fe6b419eb131211ceb1aa17a89f655b05e7305366fecea5f2",
- "selfLink": "/oapi/v1/images/sha256:98842019ab49391fe6b419eb131211ceb1aa17a89f655b05e7305366fecea5f2",
- },
- "dockerImageReference": "172.30.87.3:5000/zerog/test@sha256:98842019ab49391fe6b419eb131211ceb1aa17a89f655b05e7305366fecea5f2",
- "dockerImageMetadata": { "kind": "DockerImage", "apiVersion": "1.0", "Id": "",
- "Created": null, "ContainerConfig": {} },
- "dockerImageMetadataVersion": "1.0",
- },
- {
- "kind": "Image", "apiVersion": "v1", "metadata": {
- "name": "sha256:a7ca0c3e270a994cfdef0a1d77d8bd41d401135f2f9e02e0a3661cd026e81a77",
- "selfLink": "/oapi/v1/images/sha256:a7ca0c3e270a994cfdef0a1d77d8bd41d401135f2f9e02e0a3661cd026e81a77",
- },
- "dockerImageReference": "172.30.87.3:5000/zerog/test@sha256:a7ca0c3e270a994cfdef0a1d77d8bd41d401135f2f9e02e0a3661cd026e81a77",
- "dockerImageMetadata": { "kind": "DockerImage", "apiVersion": "1.0", "Id": "",
- "Created": null, "ContainerConfig": {} },
- "dockerImageMetadataVersion": "1.0",
- },
- {
- "kind": "Image", "apiVersion": "v1", "metadata": {
- "name": "sha256:b074b7b7905895741f7425ab4e78b9df384aaa518258d2e81d9e904ecf6c9f0f",
- "selfLink": "/oapi/v1/images/sha256:b074b7b7905895741f7425ab4e78b9df384aaa518258d2e81d9e904ecf6c9f0f",
- },
- "dockerImageReference": "172.30.87.3:5000/marmalade/juggs@sha256:b074b7b7905895741f7425ab4e78b9df384aaa518258d2e81d9e904ecf6c9f0f",
- "dockerImageMetadata": { "kind": "DockerImage", "apiVersion": "1.0", "Id": "",
- "Created": null, "ContainerConfig": {} },
- "dockerImageMetadataVersion": "1.0",
- },
- {
- "kind": "Image", "apiVersion": "v1", "metadata": {
- "name": "sha256:beadfbc3da8d183c245ab5bad4dd185dacde72dbe81b270926e60e705e534afb",
- "selfLink": "/oapi/v1/images/sha256:beadfbc3da8d183c245ab5bad4dd185dacde72dbe81b270926e60e705e534afb",
- },
- "dockerImageReference": "172.30.87.3:5000/marmalade/busybee@sha256:beadfbc3da8d183c245ab5bad4dd185dacde72dbe81b270926e60e705e534afb",
- "dockerImageMetadata": { "kind": "DockerImage", "apiVersion": "1.0", "Id": "",
- "Created": null, "ContainerConfig": {} },
- "dockerImageMetadataVersion": "1.0",
- },
- {
- "kind": "Image", "apiVersion": "v1", "metadata": {
- "name": "sha256:c1ee91e9f0f96ea280d17befdd968ce4e37653939fc9e5e36429cd9674a28719",
- "selfLink": "/oapi/v1/images/sha256:c1ee91e9f0f96ea280d17befdd968ce4e37653939fc9e5e36429cd9674a28719",
- },
- "dockerImageReference": "172.30.87.3:5000/marmalade/busybee@sha256:c1ee91e9f0f96ea280d17befdd968ce4e37653939fc9e5e36429cd9674a28719",
- "dockerImageMetadata": { "kind": "DockerImage", "apiVersion": "1.0", "Id": "",
- "Created": null, "ContainerConfig": {} },
- "dockerImageMetadataVersion": "1.0",
- },
- {
- "kind": "Image", "apiVersion": "v1", "metadata": {
- "name": "sha256:63da16dc866fa7bfca4dd9d45b70feda28aa383c9ca1f1766c127ccc715a8cb7",
- "selfLink": "/oapi/v1/images/sha256:63da16dc866fa7bfca4dd9d45b70feda28aa383c9ca1f1766c127ccc715a8cb7",
- "annotations": { "openshift.io/image.managed": "true" }
- },
- "dockerImageReference": "172.30.198.253:5000/marmalade/juggs@sha256:63da16dc866fa7bfca4dd9d45b70feda28aa383c9ca1f1766c127ccc715a8cb7",
- "dockerImageMetadata": { "kind": "DockerImage", "apiVersion": "1.0",
- "Id": "fc5cd5d8ca78a17843aba9b1b66e9d0e17200d86b0aad9a4f70d893a10c26b6d",
- "Parent": "9192c6aa777087e5c06e1d5f1771295f7cd79d9473d71dba2241e68aa2d36807",
- "Created": "2016-03-04T16:50:11Z",
- "Container": "7a453b461abfb9410f73e4449ed50d5840a44afb25b0144715b4266ee6d48f2d",
- "ContainerConfig": { "Hostname": "13709f13afe1",
- "User": "nobody:wheel", "ExposedPorts": { "8888/tcp": {} },
- "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ],
- "Cmd": [ "/bin/sh", "-c", "#(nop) LABEL version=1.0" ],
- "Image": "9192c6aa777087e5c06e1d5f1771295f7cd79d9473d71dba2241e68aa2d36807",
- "Entrypoint": [ "top", "-b" ],
- "OnBuild": [ "ADD . /app/src" ],
- "Labels": { "Test": "Value", "version": "1.0" }
- },
- "DockerVersion": "1.9.1",
- "Config": { "Hostname": "13709f13afe1", "User": "nobody:wheel",
- "ExposedPorts": { "8888/tcp": {} },
- "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ],
- "Cmd": [ "-c" ],
- "Image": "9192c6aa777087e5c06e1d5f1771295f7cd79d9473d71dba2241e68aa2d36807",
- "Entrypoint": [ "top", "-b" ],
- "OnBuild": [ "ADD . /app/src" ],
- "Labels": { "Test": "Value", "version": "1.0" }
- },
- "Architecture": "amd64",
- "Size": 126388696
- },
- "dockerImageMetadataVersion": "1.0",
- "dockerImageManifest": "{\n \"schemaVersion\": 1,\n \"name\": \"marmalade/juggs\",\n \"tag\": \"2.8\",\n \"architecture\": \"amd64\",\n \"fsLayers\": [\n {\n \"blobSum\": \"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4\"\n },\n {\n \"blobSum\": \"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4\"\n },\n {\n \"blobSum\": \"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4\"\n },\n {\n \"blobSum\": \"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4\"\n },\n {\n \"blobSum\": \"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4\"\n },\n {\n \"blobSum\": \"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4\"\n },\n {\n \"blobSum\": \"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4\"\n },\n {\n \"blobSum\": \"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4\"\n },\n {\n \"blobSum\": \"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4\"\n },\n {\n \"blobSum\": \"sha256:74fc2669b7664c1705ea18d946fb92111a2904fdc69c24dc25db546923663c4b\"\n },\n {\n \"blobSum\": \"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4\"\n },\n {\n \"blobSum\": \"sha256:8cbbdaf3178f15e3e23f5eb59c754d16511edf100ba0e57557e47c8a5924d422\"\n },\n {\n \"blobSum\": \"sha256:bc66c3b5709234727e260b55c5553c2bf9608084419271b08bca484914624d84\"\n },\n {\n \"blobSum\": \"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4\"\n },\n {\n \"blobSum\": \"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4\"\n },\n {\n \"blobSum\": \"sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4\"\n },\n {\n \"blobSum\": \"sha256:f810322bba2c5f0a6dd58ba31eba0543baabb4533e479ab2db376aaa8064be55\"\n }\n ],\n \"history\": [\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"fc5cd5d8ca78a17843aba9b1b66e9d0e17200d86b0aad9a4f70d893a10c26b6d\\\",\\\"parent\\\":\\\"9192c6aa777087e5c06e1d5f1771295f7cd79d9473d71dba2241e68aa2d36807\\\",\\\"created\\\":\\\"2016-03-04T16:50:11.993242911Z\\\",\\\"container\\\":\\\"7a453b461abfb9410f73e4449ed50d5840a44afb25b0144715b4266ee6d48f2d\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) LABEL version=1.0\\\"],\\\"Image\\\":\\\"9192c6aa777087e5c06e1d5f1771295f7cd79d9473d71dba2241e68aa2d36807\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[\\\"ADD . /app/src\\\"],\\\"Labels\\\":{\\\"Test\\\":\\\"Value\\\",\\\"version\\\":\\\"1.0\\\"},\\\"StopSignal\\\":\\\"SIGKILL\\\"},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"-c\\\"],\\\"Image\\\":\\\"9192c6aa777087e5c06e1d5f1771295f7cd79d9473d71dba2241e68aa2d36807\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[\\\"ADD . /app/src\\\"],\\\"Labels\\\":{\\\"Test\\\":\\\"Value\\\",\\\"version\\\":\\\"1.0\\\"},\\\"StopSignal\\\":\\\"SIGKILL\\\"},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\"}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"9192c6aa777087e5c06e1d5f1771295f7cd79d9473d71dba2241e68aa2d36807\\\",\\\"parent\\\":\\\"425d372ab4256cc54cbbd1bd6ea9e00ce11fb8685175b72e5193f5a067bb6a31\\\",\\\"created\\\":\\\"2016-03-04T16:50:06.235447946Z\\\",\\\"container\\\":\\\"a13a641996f5d0425de27a7fd80d30174e165acd7bf913432f899ab2f57e0154\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) LABEL Test=Value\\\"],\\\"Image\\\":\\\"425d372ab4256cc54cbbd1bd6ea9e00ce11fb8685175b72e5193f5a067bb6a31\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[\\\"ADD . /app/src\\\"],\\\"Labels\\\":{\\\"Test\\\":\\\"Value\\\"},\\\"StopSignal\\\":\\\"SIGKILL\\\"},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"-c\\\"],\\\"Image\\\":\\\"425d372ab4256cc54cbbd1bd6ea9e00ce11fb8685175b72e5193f5a067bb6a31\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[\\\"ADD . /app/src\\\"],\\\"Labels\\\":{\\\"Test\\\":\\\"Value\\\"},\\\"StopSignal\\\":\\\"SIGKILL\\\"},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\"}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"425d372ab4256cc54cbbd1bd6ea9e00ce11fb8685175b72e5193f5a067bb6a31\\\",\\\"parent\\\":\\\"9a7e5193513a4e07bcdcffacb9f1996ef7162a4d2c196d2eaa5b2b959d641dac\\\",\\\"created\\\":\\\"2016-03-04T16:50:00.89289203Z\\\",\\\"container\\\":\\\"2a9474018a32f776c8470897e6600b6a62503a734ae2775a5fbedd9ba9b28307\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) ARG simple\\\"],\\\"Image\\\":\\\"9a7e5193513a4e07bcdcffacb9f1996ef7162a4d2c196d2eaa5b2b959d641dac\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[\\\"ADD . /app/src\\\"],\\\"Labels\\\":{},\\\"StopSignal\\\":\\\"SIGKILL\\\"},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"-c\\\"],\\\"Image\\\":\\\"9a7e5193513a4e07bcdcffacb9f1996ef7162a4d2c196d2eaa5b2b959d641dac\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[\\\"ADD . /app/src\\\"],\\\"Labels\\\":{},\\\"StopSignal\\\":\\\"SIGKILL\\\"},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\"}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"9a7e5193513a4e07bcdcffacb9f1996ef7162a4d2c196d2eaa5b2b959d641dac\\\",\\\"parent\\\":\\\"dce61bf7ed98793fcfc6c09b6e096a0b74c58648397454660d4a896289f8adc9\\\",\\\"created\\\":\\\"2016-03-04T16:49:55.64958347Z\\\",\\\"container\\\":\\\"6fc564cbd8a2f53f81e1be0cf8b2752448c9b51d69787706bd1a40efc4b53870\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) ARG hello=test\\\"],\\\"Image\\\":\\\"dce61bf7ed98793fcfc6c09b6e096a0b74c58648397454660d4a896289f8adc9\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[\\\"ADD . /app/src\\\"],\\\"Labels\\\":{},\\\"StopSignal\\\":\\\"SIGKILL\\\"},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"-c\\\"],\\\"Image\\\":\\\"dce61bf7ed98793fcfc6c09b6e096a0b74c58648397454660d4a896289f8adc9\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[\\\"ADD . /app/src\\\"],\\\"Labels\\\":{},\\\"StopSignal\\\":\\\"SIGKILL\\\"},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\"}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"dce61bf7ed98793fcfc6c09b6e096a0b74c58648397454660d4a896289f8adc9\\\",\\\"parent\\\":\\\"a6853913f7a2789d8e91b4be6db0f3ca1fa635942981e6289d4cb067289be53f\\\",\\\"created\\\":\\\"2016-03-04T16:49:50.274796262Z\\\",\\\"container\\\":\\\"90360222ef8c7a4978c0a27542d78175b16cf1b559ea3a0c344c21d6596f8878\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) ONBUILD ADD . /app/src\\\"],\\\"Image\\\":\\\"a6853913f7a2789d8e91b4be6db0f3ca1fa635942981e6289d4cb067289be53f\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[\\\"ADD . /app/src\\\"],\\\"Labels\\\":{},\\\"StopSignal\\\":\\\"SIGKILL\\\"},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"-c\\\"],\\\"Image\\\":\\\"a6853913f7a2789d8e91b4be6db0f3ca1fa635942981e6289d4cb067289be53f\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[\\\"ADD . /app/src\\\"],\\\"Labels\\\":{},\\\"StopSignal\\\":\\\"SIGKILL\\\"},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\"}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"a6853913f7a2789d8e91b4be6db0f3ca1fa635942981e6289d4cb067289be53f\\\",\\\"parent\\\":\\\"e4c263ade6bb3cc552dbcd46c38ecdacb871e3e18b4db92451cf89823fb1140d\\\",\\\"created\\\":\\\"2016-03-04T16:49:43.316816134Z\\\",\\\"container\\\":\\\"ada3ba6c28f4d40ad447384f990d4a2075abf86b821cbd5b1f3b339aae2bda7b\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) STOPSIGNAL [SIGKILL]\\\"],\\\"Image\\\":\\\"e4c263ade6bb3cc552dbcd46c38ecdacb871e3e18b4db92451cf89823fb1140d\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[],\\\"Labels\\\":{},\\\"StopSignal\\\":\\\"SIGKILL\\\"},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"-c\\\"],\\\"Image\\\":\\\"e4c263ade6bb3cc552dbcd46c38ecdacb871e3e18b4db92451cf89823fb1140d\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[],\\\"Labels\\\":{},\\\"StopSignal\\\":\\\"SIGKILL\\\"},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\"}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"e4c263ade6bb3cc552dbcd46c38ecdacb871e3e18b4db92451cf89823fb1140d\\\",\\\"parent\\\":\\\"b3dd495a125e98acf8497462f7e59ddc59230f6e49a1e0c0a56a28007475af2e\\\",\\\"created\\\":\\\"2016-03-04T16:49:36.966840962Z\\\",\\\"container\\\":\\\"75a79bb684c3ff1a8b9bccd1f046e87f84b9da4722b8b45853602f0a69f4cb27\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) CMD [\\\\\\\"-c\\\\\\\"]\\\"],\\\"Image\\\":\\\"b3dd495a125e98acf8497462f7e59ddc59230f6e49a1e0c0a56a28007475af2e\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"-c\\\"],\\\"Image\\\":\\\"b3dd495a125e98acf8497462f7e59ddc59230f6e49a1e0c0a56a28007475af2e\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\"}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"b3dd495a125e98acf8497462f7e59ddc59230f6e49a1e0c0a56a28007475af2e\\\",\\\"parent\\\":\\\"2fef6101c97c5ca0a234e41eea1cdd577d6d9b1a21897147f8b662889f1e1890\\\",\\\"created\\\":\\\"2016-03-04T16:49:32.056781057Z\\\",\\\"container\\\":\\\"076b707ed7bf04602d56b714deb3270998c5b145520b925fc9d8029b28e1484e\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) ENTRYPOINT \\\\u0026{[\\\\\\\"top\\\\\\\" \\\\\\\"-b\\\\\\\"]}\\\"],\\\"Image\\\":\\\"2fef6101c97c5ca0a234e41eea1cdd577d6d9b1a21897147f8b662889f1e1890\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":null,\\\"Image\\\":\\\"2fef6101c97c5ca0a234e41eea1cdd577d6d9b1a21897147f8b662889f1e1890\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":[\\\"top\\\",\\\"-b\\\"],\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\"}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"2fef6101c97c5ca0a234e41eea1cdd577d6d9b1a21897147f8b662889f1e1890\\\",\\\"parent\\\":\\\"6559b720edfb44ed193826e8a98181ecd0f8412d36ae141891a6be8ac33f13fe\\\",\\\"created\\\":\\\"2016-03-04T16:49:27.230310779Z\\\",\\\"container\\\":\\\"b1fff8a998363845efbbc77e64e58a2ef8cd422896a40816fe5016a0d66c8804\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) USER [nobody:wheel]\\\"],\\\"Image\\\":\\\"6559b720edfb44ed193826e8a98181ecd0f8412d36ae141891a6be8ac33f13fe\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"nobody:wheel\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"\\\\\\\"/echo-script\\\\\\\"\\\"],\\\"Image\\\":\\\"6559b720edfb44ed193826e8a98181ecd0f8412d36ae141891a6be8ac33f13fe\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\"}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"6559b720edfb44ed193826e8a98181ecd0f8412d36ae141891a6be8ac33f13fe\\\",\\\"parent\\\":\\\"21356dd5eb576b1af9a101f0acb3729b3fe5c6a4a935a0efbe52d328603c6538\\\",\\\"created\\\":\\\"2016-03-04T16:49:19.278707045Z\\\",\\\"container\\\":\\\"a9ec15a2ac6c962d3f7141f789e0a703f68b1b35386b226485a470fdc297c921\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) ADD file:32d397773a81df8feb5d5baf04619f65e2a1e4fddf24bbceb85157ff7f0db752 in /usr/bin\\\"],\\\"Image\\\":\\\"21356dd5eb576b1af9a101f0acb3729b3fe5c6a4a935a0efbe52d328603c6538\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"\\\\\\\"/echo-script\\\\\\\"\\\"],\\\"Image\\\":\\\"21356dd5eb576b1af9a101f0acb3729b3fe5c6a4a935a0efbe52d328603c6538\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\",\\\"Size\\\":125275044}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"21356dd5eb576b1af9a101f0acb3729b3fe5c6a4a935a0efbe52d328603c6538\\\",\\\"parent\\\":\\\"7fd39f4f39c71d76250adac15d7385fd6d68274e8a7ddd032b0b0bb6b3280a39\\\",\\\"created\\\":\\\"2016-03-04T16:48:53.085321054Z\\\",\\\"container\\\":\\\"7749a20ab52bd8714b5cc2823d3c09767f574b8f2d4bd4393b37f0a4964f3376\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) CMD [\\\\\\\"/bin/sh\\\\\\\" \\\\\\\"-c\\\\\\\" \\\\\\\"\\\\\\\\\\\\\\\"/echo-script\\\\\\\\\\\\\\\"\\\\\\\"]\\\"],\\\"Image\\\":\\\"7fd39f4f39c71d76250adac15d7385fd6d68274e8a7ddd032b0b0bb6b3280a39\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"author\\\":\\\"cockpit@example.com\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"\\\\\\\"/echo-script\\\\\\\"\\\"],\\\"Image\\\":\\\"7fd39f4f39c71d76250adac15d7385fd6d68274e8a7ddd032b0b0bb6b3280a39\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\"}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"7fd39f4f39c71d76250adac15d7385fd6d68274e8a7ddd032b0b0bb6b3280a39\\\",\\\"parent\\\":\\\"b6962728b43855b1c803aec38e67e70bd137040543def671e415834cdfc01552\\\",\\\"created\\\":\\\"2016-03-04T16:48:47.790555865Z\\\",\\\"container\\\":\\\"ab835892b5519c2d0ffd84e22fe3d971a4a80d9d3e31757c7dce5379b947887e\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"chmod +x /echo-script\\\"],\\\"Image\\\":\\\"b6962728b43855b1c803aec38e67e70bd137040543def671e415834cdfc01552\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"author\\\":\\\"cockpit@example.com\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"sh\\\"],\\\"Image\\\":\\\"b6962728b43855b1c803aec38e67e70bd137040543def671e415834cdfc01552\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\",\\\"Size\\\":49}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"b6962728b43855b1c803aec38e67e70bd137040543def671e415834cdfc01552\\\",\\\"parent\\\":\\\"b70fe9098263c3c82a67bc22caf523ced24185975088fd1043a799a6b4273882\\\",\\\"created\\\":\\\"2016-03-04T16:48:42.037533681Z\\\",\\\"container\\\":\\\"e16228a90ccf6d29c214833ba202b94b467979f5db03797d0a27da8430509966\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) ADD file:b35fc316562d0e29fa7ae1e767f3597811f4349e30aa74122b67965a103f817a in /\\\"],\\\"Image\\\":\\\"b70fe9098263c3c82a67bc22caf523ced24185975088fd1043a799a6b4273882\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"author\\\":\\\"cockpit@example.com\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"sh\\\"],\\\"Image\\\":\\\"b70fe9098263c3c82a67bc22caf523ced24185975088fd1043a799a6b4273882\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\",\\\"Size\\\":49}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"b70fe9098263c3c82a67bc22caf523ced24185975088fd1043a799a6b4273882\\\",\\\"parent\\\":\\\"6e45971d34d5ecfc0b946014369c8dacab8f2177bbd3751dd5289b9a5ba59df2\\\",\\\"created\\\":\\\"2016-03-04T16:48:36.879318282Z\\\",\\\"container\\\":\\\"a759048c873ac86cef61a9aec0ac72734cfe53feb7acd81a2b4975473675ed20\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) EXPOSE 8888/tcp\\\"],\\\"Image\\\":\\\"6e45971d34d5ecfc0b946014369c8dacab8f2177bbd3751dd5289b9a5ba59df2\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"author\\\":\\\"cockpit@example.com\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"ExposedPorts\\\":{\\\"8888/tcp\\\":{}},\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"sh\\\"],\\\"Image\\\":\\\"6e45971d34d5ecfc0b946014369c8dacab8f2177bbd3751dd5289b9a5ba59df2\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\"}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"6e45971d34d5ecfc0b946014369c8dacab8f2177bbd3751dd5289b9a5ba59df2\\\",\\\"parent\\\":\\\"fef924a0204a00b3ec67318e2ed337b189c99ea19e2bf10ed30a13b87c5e17ab\\\",\\\"created\\\":\\\"2016-03-04T16:48:31.254943299Z\\\",\\\"container\\\":\\\"0484d0202032d11f48613463684f344ddc4f238635dcb640774e00828251f57d\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) MAINTAINER cockpit@example.com\\\"],\\\"Image\\\":\\\"65e4158d96256e032299e07ac28308d644c0e81d52b18dcb08847a5027b4f107\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"author\\\":\\\"cockpit@example.com\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":[\\\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\\\"],\\\"Cmd\\\":[\\\"sh\\\"],\\\"Image\\\":\\\"65e4158d96256e032299e07ac28308d644c0e81d52b18dcb08847a5027b4f107\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":[],\\\"Labels\\\":{}},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\"}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"fef924a0204a00b3ec67318e2ed337b189c99ea19e2bf10ed30a13b87c5e17ab\\\",\\\"parent\\\":\\\"9a163e0b8d138ec700b5a5f7e62509012f7eb34b9f86cd3bbeb3d183958114a9\\\",\\\"created\\\":\\\"2016-02-16T22:59:37.407805421Z\\\",\\\"container\\\":\\\"d23509cd0189de02bef382544ebfab515f29094f3c0e2f161fa7ce09afa8974e\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":null,\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) CMD [\\\\\\\"sh\\\\\\\"]\\\"],\\\"Image\\\":\\\"9a163e0b8d138ec700b5a5f7e62509012f7eb34b9f86cd3bbeb3d183958114a9\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":null,\\\"Labels\\\":{}},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":null,\\\"Cmd\\\":[\\\"sh\\\"],\\\"Image\\\":\\\"9a163e0b8d138ec700b5a5f7e62509012f7eb34b9f86cd3bbeb3d183958114a9\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":null,\\\"Labels\\\":{}},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\"}\"\n },\n {\n \"v1Compatibility\": \"{\\\"id\\\":\\\"9a163e0b8d138ec700b5a5f7e62509012f7eb34b9f86cd3bbeb3d183958114a9\\\",\\\"created\\\":\\\"2016-02-16T22:59:36.792440427Z\\\",\\\"container\\\":\\\"13709f13afe11b7d4a007d2866afd20c5b783f0a89f4e6792a28102a4c12c473\\\",\\\"container_config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":null,\\\"Cmd\\\":[\\\"/bin/sh\\\",\\\"-c\\\",\\\"#(nop) ADD file:7cdf7a89f6a004b2e9501317bd72bd863d93a51255d8f83b2ed3058d385a4938 in /\\\"],\\\"Image\\\":\\\"\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":null,\\\"Labels\\\":null},\\\"docker_version\\\":\\\"1.9.1\\\",\\\"config\\\":{\\\"Hostname\\\":\\\"13709f13afe1\\\",\\\"Domainname\\\":\\\"\\\",\\\"User\\\":\\\"\\\",\\\"AttachStdin\\\":false,\\\"AttachStdout\\\":false,\\\"AttachStderr\\\":false,\\\"Tty\\\":false,\\\"OpenStdin\\\":false,\\\"StdinOnce\\\":false,\\\"Env\\\":null,\\\"Cmd\\\":null,\\\"Image\\\":\\\"\\\",\\\"Volumes\\\":null,\\\"WorkingDir\\\":\\\"\\\",\\\"Entrypoint\\\":null,\\\"OnBuild\\\":null,\\\"Labels\\\":null},\\\"architecture\\\":\\\"amd64\\\",\\\"os\\\":\\\"linux\\\",\\\"Size\\\":1113554}\"\n }\n ],\n \"signatures\": [\n {\n \"header\": {\n \"jwk\": {\n \"crv\": \"P-256\",\n \"kid\": \"VQO7:TVYU:FARI:VIFC:P2YU:W23P:AC7V:7ZXR:I5RO:DTY4:NRES:MGXE\",\n \"kty\": \"EC\",\n \"x\": \"EsCEZHIfgzZDBsbCzgCng884FdTcwyQ8dZbhap2cpgo\",\n \"y\": \"9Hlp74n2G2aMwzyvvM9G-8BbrXDp2dl9rt2RGbidQ8I\"\n },\n \"alg\": \"ES256\"\n },\n \"signature\": \"MFqsTUp-ci7Th-1r02bHj8eDh5xRg_WtjpN7WD4dI2Tuvg96fyGH6rf5bYKIjEVKz1_3Z42Ma06DDw8hSsMOGw\",\n \"protected\": \"eyJmb3JtYXRMZW5ndGgiOjI3NjU1LCJmb3JtYXRUYWlsIjoiQ24wIiwidGltZSI6IjIwMTYtMDMtMDRUMTY6NTA6MzJaIn0\"\n }\n ]\n}"
- }
-]);
diff --git a/pkg/kubernetes/scripts/test-kube-client.js b/pkg/kubernetes/scripts/test-kube-client.js
deleted file mode 100644
index e35767d61..000000000
--- a/pkg/kubernetes/scripts/test-kube-client.js
+++ /dev/null
@@ -1,920 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-import { FIXTURE_BASIC } from "./fixture-basic.js";
-import { FIXTURE_LARGE } from "./fixture-large.js";
-
-import QUnit from "qunit-tests";
-var angular = require("angular");
-
-require("./kube-client");
-require("./kube-client-cockpit");
-require("./kube-client-mock");
-
-(function() {
- /* Filled in with a function */
- var inject;
-
- var module = angular.module("kubeClient.tests", [
- "kubeClient",
- "kubeClient.mock"
- ])
-
- .config([
- 'KubeWatchProvider',
- 'KubeRequestProvider',
- function(KubeWatchProvider, KubeRequestProvider) {
- KubeWatchProvider.KubeWatchFactory = "MockKubeWatch";
- KubeRequestProvider.KubeRequestFactory = "MockKubeRequest";
- }
- ]);
-
- function injectLoadFixtures(fixtures) {
- inject([
- "kubeLoader",
- "MockKubeData",
- function(loader, data) {
- if (fixtures)
- data.load(fixtures);
- loader.reset(true);
- }
- ]);
- }
-
- QUnit.test("loader load", function (assert) {
- var done = assert.async();
- assert.expect(7);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", function(loader) {
- var promise = loader.load("nodes");
- assert.ok(!!promise, "promise returned");
- assert.equal(typeof promise.then, "function", "promise has then");
- assert.equal(typeof promise.catch, "function", "promise has catch");
- assert.equal(typeof promise.finally, "function", "promise has finally");
-
- return promise.then(function(items) {
- assert.ok(angular.isArray(items), "got items array");
- assert.equal(items.length, 1, "one node");
- assert.equal(items[0].metadata.name, "127.0.0.1", "localhost node");
- done();
- });
- }]);
- });
-
- QUnit.test("loader load encoding", function (assert) {
- var done = assert.async();
- assert.expect(2);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeSelect", "$q", function(loader, select, $q) {
- assert.equal(select().kind("Encoded").length, 0);
-
- var defer = $q.defer();
- var x = loader.listen(function() {
- assert.equal(select().kind("Image").length, 1);
- x.cancel();
- defer.resolve();
- done();
- });
-
- loader.handle([{
- "apiVersion": "v1",
- "kind": "Image",
- "metadata": {
- "name": "encoded:one",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100001001",
- "namespace": "default",
- "selfLink": "/oapi/v1/images/encoded%3Aone",
- },
- }, {
- "apiVersion": "v1",
- "kind": "Image",
- "metadata": {
- "name": "encoded:one",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100001001",
- "namespace": "default",
- },
- }, {
- "apiVersion": "v1",
- "kind": "Image",
- "metadata": {
- "name": "encoded:one",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100001001",
- "namespace": "default",
- "selfLink": "/oapi/v1/images/encoded:one",
- },
- }]);
-
- return defer.promise;
- }]);
- });
-
- QUnit.test("loader load fail", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", function(loader) {
- var promise = loader.load("nonexistant");
- return promise.then(function(data) {
- assert.ok(!true, "successfully loaded");
- }, function(response) {
- assert.equal(response.code, 404, "not found");
- assert.equal(response.message, "Not found here", "not found message");
- assert.ok(true, "not sucessfully loaded");
- done();
- });
- }]);
- });
-
- QUnit.test("loader watch", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", function(loader) {
- return loader.watch("nodes").then(function(response) {
- assert.ok("/api/v1/nodes/127.0.0.1" in loader.objects, "found node");
- var node = loader.objects["/api/v1/nodes/127.0.0.1"];
- assert.equal(node.metadata.name, "127.0.0.1", "localhost node");
- assert.equal(typeof node.spec.capacity, "object", "node has resources");
- done();
- });
- }]);
- });
-
- QUnit.test("list nodes", function (assert) {
- var done = assert.async();
- assert.expect(6);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeSelect", function(loader, select) {
- return loader.watch("nodes").then(function() {
- var nodes = select().kind("Node");
- assert.ok("/api/v1/nodes/127.0.0.1" in nodes, "found node");
- var node = nodes["/api/v1/nodes/127.0.0.1"];
- assert.equal(node.metadata.name, "127.0.0.1", "localhost node");
- assert.equal(typeof node.spec.capacity, "object", "node has resources");
-
- /* The same thing should be returned */
- var nodes1 = select().kind("Node");
- assert.strictEqual(nodes, nodes1, "same object returned");
-
- /* Key should not be encoded as JSON */
- var parsed = JSON.parse(JSON.stringify(node));
- assert.ok(!("key" in parsed), "key should not be serialized");
- assert.strictEqual(parsed.key, undefined, "key not be undefined after serialize");
-
- done();
- });
- }]);
- });
-
- QUnit.test("list pods", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeSelect", function(loader, select) {
- return loader.watch("pods").then(function() {
- var pods = select().kind("Pod");
- assert.equal(pods.length, 3, "found pods");
- var pod = pods["/api/v1/namespaces/default/pods/apache"];
- assert.equal(typeof pod, "object", "found pod");
- assert.equal(pod.metadata.labels.name, "apache", "pod has label");
- done();
- });
- }]);
- });
-
- QUnit.test("set namespace", function (assert) {
- var done = assert.async();
- assert.expect(7);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["$q", "kubeLoader", "kubeSelect", function($q, loader, select) {
- return loader.watch("pods").then(function() {
- var pods = select().kind("Pod");
- assert.equal(pods.length, 3, "number of pods");
- assert.strictEqual(loader.limits.namespace, null, "namespace is null");
-
- loader.limit({ namespace: "other" });
- assert.strictEqual(loader.limits.namespace, "other", "namespace is other");
-
- pods = select().kind("Pod");
- assert.equal(pods.length, 1, "pods from namespace other");
- assert.ok("/api/v1/namespaces/other/pods/apache" in pods, "other pod");
-
- loader.limit({ namespace: null });
- assert.strictEqual(loader.limits.namespace, null, "namespace is null again");
- var defer = $q.defer();
- var listened = false;
- var x = loader.listen(function() {
- if (listened) {
- pods = select().kind("Pod");
- assert.equal(pods.length, 3, "all pods back");
- x.cancel();
- defer.resolve();
- done();
- }
- listened = true;
- });
-
- return defer.promise;
- });
- }]);
- });
-
- QUnit.test("add pod", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["$q", "kubeLoader", "kubeSelect", "MockKubeData", function($q, loader, select, data) {
- return loader.watch("pods").then(function() {
- var pods = select().kind("Pod");
- assert.equal(pods.length, 3, "number of pods");
- assert.equal(pods["/api/v1/namespaces/default/pods/apache"].metadata.labels.name,
- "apache", "pod has label");
-
- var defer = $q.defer();
- var x = loader.listen(function() {
- var pods = select().kind("Pod");
- if (pods.length === 4) {
- assert.equal(pods["/api/v1/namespaces/default/pods/aardvark"].metadata.labels.name,
- "aardvark", "new pod present in items");
- x.cancel();
- defer.resolve();
- done();
- }
- });
-
- data.update("namespaces/default/pods/aardvark", {
- "kind": "Pod",
- "metadata": {
- "name": "aardvark",
- "uid": "22768037-ab8a-11e4-9a7c-080027300d85",
- "namespace": "default",
- "labels": {
- "name": "aardvark"
- },
- },
- "spec": {
- "volumes": null,
- "containers": [ ],
- "imagePullPolicy": "IfNotPresent"
- }
- });
-
- return defer.promise;
- });
- }]);
- });
-
- QUnit.test("update pod", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["$q", "kubeLoader", "kubeSelect", "MockKubeData", function($q, loader, select, data) {
- return loader.watch("pods").then(function() {
- var pods = select().kind("Pod");
- assert.equal(pods.length, 3, "number of pods");
- assert.equal(pods["/api/v1/namespaces/default/pods/apache"].metadata.labels.name,
- "apache", "pod has label");
-
- var defer = $q.defer();
- var listened = false;
- var x = loader.listen(function() {
- var pods;
- if (listened) {
- pods = select().kind("Pod");
- assert.equal(pods["/api/v1/namespaces/default/pods/apache"].metadata.labels.name,
- "apachepooo", "pod has changed");
- x.cancel();
- defer.resolve();
- done();
- }
- listened = true;
- });
-
- data.update("namespaces/default/pods/apache", {
- "kind": "Pod",
- "metadata": {
- "name": "apache",
- "uid": "11768037-ab8a-11e4-9a7c-080027300d85",
- "namespace": "default",
- "labels": {
- "name": "apachepooo"
- },
- }
- });
-
- return defer.promise;
- });
- }]);
- });
-
- QUnit.test("remove pod", function (assert) {
- var done = assert.async();
- assert.expect(5);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["$q", "kubeLoader", "kubeSelect", "MockKubeData", function($q, loader, select, data) {
- return loader.watch("pods").then(function() {
- var pods = select().kind("Pod");
- assert.equal(pods.length, 3, "number of pods");
- assert.equal(pods["/api/v1/namespaces/default/pods/apache"].metadata.labels.name,
- "apache", "pod has label");
-
- var defer = $q.defer();
- var listened = false;
- var x = loader.listen(function() {
- var pods;
- if (listened) {
- pods = select().kind("Pod");
- assert.equal(pods.length, 2, "removed a pod");
- assert.strictEqual(pods["/api/v1/namespaces/default/pods/apache"], undefined, "removed pod");
- assert.equal(pods["/api/v1/namespaces/default/pods/database-1"].metadata.labels.name,
- "wordpressreplica", "other pod");
- x.cancel();
- defer.resolve();
- done();
- }
- listened = true;
- });
-
- data.update("namespaces/default/pods/apache", null);
- return defer.promise;
- });
- }]);
- });
-
- QUnit.test("list services", function (assert) {
- var done = assert.async();
- assert.expect(4);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeSelect", function(loader, select) {
- return loader.watch("services").then(function() {
- var services = select().kind("Service");
- var x;
- var svc = null;
- for (x in services) {
- svc = services[x];
- break;
- }
- assert.ok(!!svc, "got a service");
- assert.equal(services.length, 2, "number of services");
- assert.equal(svc.metadata.name, "kubernetes", "service id");
- assert.equal(svc.spec.selector.component, "apiserver", "service has label");
-
- done();
- });
- }]);
- });
-
- var CREATE_ITEMS = [
- {
- "kind": "Pod",
- "apiVersion": "v1",
- "metadata": {
- "name": "pod1",
- "uid": "d072fb85-f70e-11e4-b829-10c37bdb8410",
- "resourceVersion": "634203",
- "labels": {
- "name": "pod1"
- },
- },
- "spec": {
- "volumes": null,
- "containers": [{
- "name": "database",
- "image": "mysql",
- "ports": [{ "containerPort": 3306, "protocol": "TCP" }],
- }],
- "nodeName": "127.0.0.1"
- }
- }, {
- "kind": "Node",
- "apiVersion": "v1",
- "metadata": {
- "name": "node1",
- "uid": "6e51438e-d161-11e4-acbc-10c37bdb8410",
- "resourceVersion": "634539",
- },
- "status": {
- "addresses": [
- {
- "address": "172.2.3.1",
- "type": "ExternalIP"
- }
- ]
- }
- }
- ];
-
- QUnit.test("create", function (assert) {
- var done = assert.async();
- assert.expect(2);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeMethods", function(loader, methods) {
- loader.watch("pods");
- loader.watch("nodes");
- loader.watch("namespaces");
- return methods.create(CREATE_ITEMS, "namespace1").then(function() {
- assert.equal(loader.objects["/api/v1/namespaces/namespace1/pods/pod1"].metadata.name, "pod1", "pod object");
- assert.equal(loader.objects["/api/v1/nodes/node1"].metadata.name, "node1", "node object");
- done();
- });
- }]);
- });
-
- QUnit.test("create namespace exists", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeMethods", function(loader, methods) {
- loader.watch("pods");
- loader.watch("nodes");
- loader.watch("namespaces");
-
- var NAMESPACE_ITEM = {
- "apiVersion" : "v1",
- "kind" : "Namespace",
- "metadata" : { "name": "namespace1" }
- };
-
- return methods.create(NAMESPACE_ITEM).then(function() {
- assert.ok("/api/v1/namespaces/namespace1" in loader.objects, "namespace created");
-
- return methods.create(CREATE_ITEMS, "namespace1").then(function() {
- assert.ok("/api/v1/namespaces/namespace1/pods/pod1" in loader.objects, "pod created");
- assert.ok("/api/v1/nodes/node1" in loader.objects, "node created");
- done();
- });
- });
- }]);
- });
-
- QUnit.test("create namespace default", function (assert) {
- var done = assert.async();
- assert.expect(2);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeMethods", function(loader, methods) {
- loader.watch("pods");
- loader.watch("nodes");
- loader.watch("namespaces");
- return methods.create(CREATE_ITEMS).then(function() {
- assert.equal(loader.objects["/api/v1/namespaces/default/pods/pod1"].metadata.name, "pod1", "pod created");
- assert.equal(loader.objects["/api/v1/nodes/node1"].metadata.name, "node1", "node created");
- done();
- });
- }]);
- });
-
- QUnit.test("create object exists", function (assert) {
- var done = assert.async();
- assert.expect(1);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeMethods", function(loader, methods) {
- loader.watch("pods");
- loader.watch("nodes");
- loader.watch("namespaces");
-
- var items = CREATE_ITEMS.slice();
- items.push(items[0]);
-
- return methods.create(items).then(function(response) {
- assert.equal(response, false, "should have failed");
- done();
- }, function(response) {
- assert.equal(response.code, 409, "http already exists");
- done();
- });
- }]);
- });
-
- QUnit.test("delete pod", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeMethods", function(loader, methods) {
- var watch = loader.watch("pods");
-
- return methods.create(CREATE_ITEMS, "namespace2").then(function() {
- assert.ok("/api/v1/namespaces/namespace2/pods/pod1" in loader.objects, "pod created");
- return methods.delete("/api/v1/namespaces/namespace2/pods/pod1").then(function() {
- assert.ok(true, "remove succeeded");
- return watch.finally(function() {
- assert.ok(!("/api/v1/namespaces/namespace2/pods/pod1" in loader.objects), "pod was removed");
- done();
- });
- });
- });
- }]);
- });
-
- QUnit.test("patch pod", function (assert) {
- var done = assert.async();
- assert.expect(4);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeMethods", function(loader, methods) {
- var watch = loader.watch("pods");
- var path = "/api/v1/namespaces/namespace2/pods/pod1";
-
- return methods.create(CREATE_ITEMS, "namespace2").then(function() {
- assert.ok(path in loader.objects, "pod created");
- return methods.patch(path, { "extra": "blah" }).then(function() {
- assert.ok(true, "patch succeeded");
- return methods.patch(loader.objects[path], { "second": "test" }).then(function() {
- return watch.finally(function() {
- var pod = loader.objects[path];
- assert.equal(pod.extra, "blah", "pod has changed");
- assert.equal(pod.second, "test", "pod changed by own object");
- done();
- });
- });
- });
- });
- }]);
- });
-
- QUnit.test("post", function (assert) {
- var done = assert.async();
- assert.expect(1);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeMethods", function(loader, methods) {
- return methods.post("/api/v1/namespaces/namespace1/pods", CREATE_ITEMS[0]).then(function(response) {
- assert.equal(response.metadata.name, "pod1", "pod object");
- done();
- });
- }]);
- });
-
- QUnit.test("post fail", function (assert) {
- var done = assert.async();
- assert.expect(1);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeMethods", function(loader, methods) {
- return methods.post("/api/v1/nodes", FIXTURE_BASIC["nodes/127.0.0.1"]).then(function() {
- assert.ok(false, "shouldn't succeed");
- }, function(response) {
- assert.deepEqual(response, { "code": 409, "message": "Already exists" }, "got failure code");
- done();
- });
- }]);
- });
-
- QUnit.test("put", function (assert) {
- var done = assert.async();
- assert.expect(1);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeMethods", function(loader, methods) {
- var node = { "kind": "Node", "metadata": { "name": "127.0.0.1", labels: { "test": "value" } } };
- return methods.put("/api/v1/nodes/127.0.0.1", node).then(function(response) {
- assert.deepEqual(response.metadata.labels, { "test": "value" }, "put returned object");
- done();
- });
- }]);
- });
-
- QUnit.test("check resource ok", function (assert) {
- var done = assert.async();
- assert.expect(0);
-
- injectLoadFixtures(null);
-
- inject(["kubeMethods", function(methods) {
- var data = { kind: "Blah", metadata: { name: "test" } };
- done();
- return methods.check(data);
- }]);
- });
-
- QUnit.test("check resource name empty", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(null);
-
- inject(["kubeMethods", function(methods) {
- var data = { kind: "Blah", metadata: { name: "" } };
- return methods.check(data).catch(function(ex) {
- assert.ok(angular.isArray(ex), "threw array of failures");
- assert.equal(ex.length, 1, "number of errors");
- assert.ok(ex[0] instanceof Error, "threw an error");
- done();
- });
- }]);
- });
-
- QUnit.test("check resource name missing", function (assert) {
- var done = assert.async();
- assert.expect(1);
-
- injectLoadFixtures(null);
-
- inject(["kubeMethods", function(methods) {
- var data = { kind: "Blah", metadata: { } };
- return methods.check(data).then(function() {
- assert.ok(true, "passed check");
- done();
- }, null);
- }]);
- });
-
- QUnit.test("check resource name namespace bad", function (assert) {
- var done = assert.async();
- assert.expect(6);
-
- injectLoadFixtures(null);
-
- inject(["kubeMethods", function(methods) {
- var data = { kind: "Blah", metadata: { name: "a#a", namespace: "" } };
- var targets = { "metadata.name": "#name", "metadata.namespace": "#namespace" };
- return methods.check(data, targets).catch(function(ex) {
- assert.ok(angular.isArray(ex), "threw array of failures");
- assert.equal(ex.length, 2, "number of errors");
- assert.ok(ex[0] instanceof Error, "threw an error");
- assert.equal(ex[0].target, "#name", "correct name target");
- assert.ok(ex[1] instanceof Error, "threw an error");
- assert.equal(ex[1].target, "#namespace", "correct name target");
- done();
- });
- }]);
- });
-
- QUnit.test("check resource namespace bad", function (assert) {
- var done = assert.async();
- assert.expect(4);
-
- injectLoadFixtures(null);
-
- inject(["kubeMethods", function(methods) {
- var data = { kind: "Blah", metadata: { name: "aa", namespace: "" } };
- var targets = { "metadata.name": "#name", "metadata.namespace": "#namespace" };
- return methods.check(data, targets).catch(function(ex) {
- assert.ok(angular.isArray(ex), "threw array of failures");
- assert.equal(ex.length, 1, "number of errors");
- assert.ok(ex[0] instanceof Error, "threw an error");
- assert.equal(ex[0].target, "#namespace", "correct name target");
- done();
- });
- }]);
- });
-
- QUnit.test("lookup uid", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeSelect", function(loader, select) {
- return loader.watch("pods").then(function() {
- /* Get the item */
- var item = select().kind("Pod")
- .one();
- var uid = item.metadata.uid;
- assert.ok(uid, "Have uid");
-
- var by_uid_item = select().uid(uid)
- .one();
- assert.strictEqual(item, by_uid_item, "load uid");
-
- /* Shouldn't match */
- item = select().uid("bad")
- .one();
- assert.strictEqual(item, null, "mismatch uid");
-
- done();
- });
- }]);
- });
-
- QUnit.test("lookup host", function (assert) {
- var done = assert.async();
- assert.expect(2);
-
- injectLoadFixtures(FIXTURE_BASIC);
-
- inject(["kubeLoader", "kubeSelect", function(loader, select) {
- return loader.watch("pods").then(function() {
- /* Get the item */
- var item = select().host("127.0.0.1")
- .one();
- assert.deepEqual(item.metadata.selfLink, "/api/v1/namespaces/default/pods/database-1", "correct pod");
-
- /* Shouldn't match */
- item = select().host("127.0.0.2")
- .one();
- assert.strictEqual(item, null, "mismatch host");
-
- done();
- });
- }]);
- });
-
- QUnit.test("lookup", function (assert) {
- var done = assert.async();
- assert.expect(6);
-
- injectLoadFixtures(FIXTURE_LARGE);
-
- inject(["kubeLoader", "kubeSelect", function(loader, select) {
- var expected = {
- "apiVersion": "v1",
- "kind": "ReplicationController",
- "metadata": { "labels": { "example": "mock", "name": "3controller" },
- "name": "3controller",
- "resourceVersion": 10000,
- "uid": "11768037-ab8a-11e4-9a7c-100001001",
- "namespace": "default",
- "selfLink": "/api/v1/namespaces/default/replicationcontrollers/3controller",
- },
- "spec": { "replicas": 1, "selector": { "factor3": "yes" } }
- };
-
- return loader.watch("replicationcontrollers").then(function() {
- /* Get the item */
- var item = select().kind("ReplicationController")
- .name("3controller")
- .namespace("default")
- .one();
- assert.deepEqual(item, expected, "correct item");
-
- /* The same item, without namespace */
- item = select().kind("ReplicationController")
- .name("3controller")
- .one();
- assert.deepEqual(item, expected, "selected without namespace");
-
- /* Any replication controller */
- item = select().kind("ReplicationController")
- .one();
- assert.equal(item.kind, "ReplicationController", "any replication controller");
-
- /* Shouldn't match */
- item = select().kind("BadKind")
- .name("3controller")
- .namespace("default")
- .one();
- assert.strictEqual(item, null, "mismatch kind");
- item = select().kind("ReplicationController")
- .name("badcontroller")
- .namespace("default")
- .one();
- assert.strictEqual(item, null, "mismatch name");
- item = select().kind("ReplicationController")
- .name("3controller")
- .namespace("baddefault")
- .one();
- assert.strictEqual(item, null, "mismatch namespace");
-
- done();
- });
- }]);
- });
-
- QUnit.test("select", function (assert) {
- var done = assert.async();
- assert.expect(12);
-
- injectLoadFixtures(FIXTURE_LARGE);
-
- inject(["kubeLoader", "kubeSelect", function(loader, select) {
- return loader.watch("pods").then(function() {
- var image = { kind: "Image" };
-
- /* same thing twice */
- var first = select(image);
- var second = select(image);
- assert.strictEqual(first, second, "identical for single object");
-
- /* null thing twice */
- first = select(null);
- second = select(null);
- assert.strictEqual(first, second, "identical for null object");
-
- /* Select everything odd, 500 pods */
- var results = select().namespace("default")
- .label({ "type": "odd" });
- assert.equal(results.length, 500, "correct amount");
-
- /* The same thing should be returned */
- var results1 = select().namespace("default")
- .label({ "type": "odd" });
- assert.strictEqual(results, results1, "same object returned");
-
- /* Select everything odd, but wrong namespace, no pods */
- results = select().namespace("other")
- .label({ "type": "odd" });
- assert.equal(results.length, 0, "other namespace no pods");
-
- /* The same ones selected even when a second (present) label */
- results = select().namespace("default")
- .label({ "type": "odd", "tag": "silly" });
- assert.equal(results.length, 500, "with additional label");
-
- /* Nothing selected when additional invalid field */
- results = select().namespace("default")
- .label({ "type": "odd", "tag": "billy" });
- assert.equal(results.length, 0, "no objects");
-
- /* Limit by kind */
- results = select().kind("Pod")
- .namespace("default")
- .label({ "type": "odd" });
- assert.equal(results.length, 500, "by kind");
-
- /* Limit by invalid kind */
- results = select().kind("Ood")
- .namespace("default")
- .label({ "type": "odd" });
- assert.equal(results.length, 0, "nothing for invalid kind");
-
- /* Everything selected when no selector */
- results = select().namespace("default");
- assert.equal(results.length, 1000, "all pods");
-
- /* Nothing selected when bad namespace */
- results = select().namespace("bad");
- assert.equal(results.length, 0, "bad namespace no objects");
-
- /* Nothing selected when empty selector */
- results = select().label({ });
- assert.equal(results.length, 0, "nothing selected");
-
- done();
- });
- }]);
- });
-
- angular.module('exceptionOverride', []).factory('$exceptionHandler', function() {
- return function(exception, cause) {
- exception.message += ' (caused by "' + cause + '")';
- throw exception;
- };
- });
-
- module.run([
- '$injector',
- function($injector) {
- inject = function inject(func) {
- return $injector.invoke(func);
- };
- QUnit.start();
- }
- ]);
-
- angular.bootstrap(document, ['kubeClient.tests']);
-}());
diff --git a/pkg/kubernetes/scripts/test-nodes.js b/pkg/kubernetes/scripts/test-nodes.js
deleted file mode 100644
index 2fda22d2f..000000000
--- a/pkg/kubernetes/scripts/test-nodes.js
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-import QUnit from "qunit-tests";
-var angular = require("angular");
-
-require("./nodes");
-require("./kube-client-cockpit");
-
-function suite(fixtures) {
- /* Filled in with a function */
- var inject;
-
- var module = angular.module("kubernetes.nodes.tests", [
- "kubeClient",
- 'kubeClient.cockpit',
- "kubernetes.nodes",
- ])
-
- .config([
- 'KubeTranslateProvider',
- 'KubeFormatProvider',
- function(KubeTranslateProvider, KubeFormatProvider) {
- KubeTranslateProvider.KubeTranslateFactory = "CockpitTranslate";
- KubeFormatProvider.KubeFormatFactory = "CockpitFormat";
- }
- ]);
-
- function injectLoadFixtures(fixtures) {
- inject([
- "kubeLoader",
- function(loader, data) {
- loader.reset(true);
- if (fixtures)
- loader.handle(fixtures);
- }
- ]);
- }
-
- QUnit.test("nodeStatus tests", function (assert) {
- var done = assert.async();
- assert.expect(10);
-
- injectLoadFixtures(fixtures);
-
- inject(["nodeData", "kubeSelect", function(nodeData, select) {
- var nodes = select().kind("Node");
- assert.equal(nodeData.nodeStatus(), "Unknown", "undefined node");
- assert.equal(nodeData.nodeStatus({}), "Unknown", "empty node");
- assert.equal(nodeData.nodeStatus(nodes['/api/v1/nodes/unknown-node']), "Unknown", "no conditions");
- assert.equal(nodeData.nodeStatus(nodes['/api/v1/nodes/unknown-node2']), "Unknown", "no ready condition");
- assert.equal(nodeData.nodeStatus(nodes['/api/v1/nodes/failed-node']), "Not Ready", "failed");
- assert.equal(nodeData.nodeStatus(nodes['/api/v1/nodes/ready-node']), "Ready", "ready");
- assert.equal(nodeData.nodeStatus(nodes['/api/v1/nodes/unschedulable-node']), "Scheduling Disabled", "ready but unschedulable");
- assert.equal(nodeData.nodeStatus(nodes['/api/v1/nodes/unschedulable-failed-node']), "Not Ready", "not ready and unschedulable");
- assert.equal(nodeData.nodeStatus(nodes['/api/v1/nodes/disk-node']), "Ready", "out of disk");
- assert.equal(nodeData.nodeStatus(nodes['/api/v1/nodes/mem-node']), "Ready", "out of memory");
- done();
- }]);
- });
-
- QUnit.test("nodeStatusIcon tests", function (assert) {
- var done = assert.async();
- assert.expect(10);
-
- injectLoadFixtures(fixtures);
-
- inject(["nodeData", "kubeSelect", function(nodeData, select) {
- var nodes = select().kind("Node");
- assert.equal(nodeData.nodeStatusIcon(), "wait", "undefined node");
- assert.equal(nodeData.nodeStatusIcon({}), "wait", "empty node");
- assert.equal(nodeData.nodeStatusIcon(nodes['/api/v1/nodes/unknown-node']), "wait", "no conditions");
- assert.equal(nodeData.nodeStatusIcon(nodes['/api/v1/nodes/unknown-node2']), "wait", "no ready condition");
- assert.equal(nodeData.nodeStatusIcon(nodes['/api/v1/nodes/failed-node']), "fail", "failed");
- assert.equal(nodeData.nodeStatusIcon(nodes['/api/v1/nodes/ready-node']), "");
- assert.equal(nodeData.nodeStatusIcon(nodes['/api/v1/nodes/unschedulable-node']), "", "ready but unschedulable");
- assert.equal(nodeData.nodeStatusIcon(nodes['/api/v1/nodes/unschedulable-failed-node']), "fail", "not ready and unschedulable");
- assert.equal(nodeData.nodeStatusIcon(nodes['/api/v1/nodes/disk-node']), "warn", "out of disk");
- assert.equal(nodeData.nodeStatusIcon(nodes['/api/v1/nodes/mem-node']), "warn", "out of memory");
- done();
- }]);
- });
-
- QUnit.test("nodeConditions tests", function (assert) {
- var done = assert.async();
- assert.expect(5);
-
- injectLoadFixtures(fixtures);
-
- inject(["nodeData", "kubeSelect", function(nodeData, select) {
- var nodes = select().kind("Node");
- assert.equal(nodeData.nodeConditions(), undefined);
- assert.equal(nodeData.nodeConditions(null), undefined);
- assert.deepEqual(nodeData.nodeConditions({}), {});
- var conditions = nodeData.nodeConditions(nodes['/api/v1/nodes/unschedulable-node']);
- assert.deepEqual(conditions, {
- "OutOfDisk": {
- "status": "False",
- "type": "OutOfDisk"
- },
- "Ready": {
- "status": "True",
- "type": "Ready"
- }
- }, "Correct object");
- assert.strictEqual(conditions, nodeData.nodeConditions(nodes['/api/v1/nodes/unschedulable-node']), "identical when called with the same object");
- done();
- }]);
- });
-
- angular.module('exceptionOverride', []).factory('$exceptionHandler', function() {
- return function(exception, cause) {
- exception.message += ' (caused by "' + cause + '")';
- throw exception;
- };
- });
-
- module.run([
- '$injector',
- function($injector) {
- inject = function inject(func) {
- return $injector.invoke(func);
- };
- QUnit.start();
- }
- ]);
-
- angular.bootstrap(document, ['kubernetes.nodes.tests']);
-}
-
-/* Invoke the test suite with this data */
-suite([
- {
- "kind": "Node",
- "apiVersion": "v1",
- "metadata": {
- "name": "unknown-node",
- "selfLink": "/api/v1/nodes/unknown-node",
- "uid": "4920ab25-1092-11e6-a03c-5254009e00f1",
- "resourceVersion": "17152",
- },
- "status": {
- }
- },
- {
- "kind": "Node",
- "apiVersion": "v1",
- "metadata": {
- "name": "unknown-node2",
- "selfLink": "/api/v1/nodes/unknown-node2",
- "uid": "4920ab25-1092-11e6-a03c-5254009e00f2",
- "resourceVersion": "17152",
- },
- "status": {
- "conditions": [
- {
- "type": "Other",
- "status": "Other",
- },
- ],
- }
- },
- {
- "kind": "Node",
- "apiVersion": "v1",
- "metadata": {
- "name": "failed-node",
- "selfLink": "/api/v1/nodes/failed-node",
- "uid": "4920ab25-1092-11e6-a03c-5254009e00f3",
- "resourceVersion": "17152",
- },
- "status": {
- "conditions": [
- {
- "type": "Ready",
- "status": "Other",
- },
- ],
- }
- },
- {
- "kind": "Node",
- "apiVersion": "v1",
- "metadata": {
- "name": "ready-node",
- "selfLink": "/api/v1/nodes/ready-node",
- "uid": "4920ab25-1092-11e6-a03c-5254009e00f4",
- "resourceVersion": "17152",
- },
- "status": {
- "conditions": [
- {
- "type": "Ready",
- "status": "True",
- },
- ],
- }
- },
- {
- "kind": "Node",
- "apiVersion": "v1",
- "metadata": {
- "name": "unschedulable-node",
- "selfLink": "/api/v1/nodes/unschedulable-node",
- "uid": "4920ab25-1092-11e6-a03c-5254009e00f5",
- "resourceVersion": "17152",
- },
- "spec": {
- "unschedulable": true
- },
- "status": {
- "conditions": [
- {
- "type": "Ready",
- "status": "True",
- },
- {
- "type": "OutOfDisk",
- "status": "False",
- }
- ],
- }
- },
- {
- "kind": "Node",
- "apiVersion": "v1",
- "metadata": {
- "name": "unschedulable-failed-node",
- "selfLink": "/api/v1/nodes/unschedulable-failed-node",
- "uid": "4920ab25-1092-11e6-a03c-5254009e00f7",
- "resourceVersion": "17152",
- },
- "spec": {
- "unschedulable": true
- },
- "status": {
- "conditions": [
- {
- "type": "Ready",
- "status": "False",
- },
- {
- "type": "OutOfDisk",
- "status": "False",
- }
- ],
- }
- },
- {
- "kind": "Node",
- "apiVersion": "v1",
- "metadata": {
- "name": "disk-node",
- "selfLink": "/api/v1/nodes/disk-node",
- "uid": "4920ab25-1092-11e6-a03c-5254009e00f8",
- "resourceVersion": "17152",
- },
- "status": {
- "conditions": [
- {
- "type": "Ready",
- "status": "True",
- },
- {
- "type": "OutOfDisk",
- "status": "True",
- }
- ],
- }
- },
- {
- "kind": "Node",
- "apiVersion": "v1",
- "metadata": {
- "name": "mem-node",
- "selfLink": "/api/v1/nodes/mem-node",
- "uid": "4920ab25-1092-11e6-a03c-5254009e00f7",
- "resourceVersion": "17152",
- },
- "status": {
- "conditions": [
- {
- "type": "Ready",
- "status": "True",
- },
- {
- "type": "OutOfMemory",
- "status": "True",
- }
- ],
- }
- }
-]);
diff --git a/pkg/kubernetes/scripts/test-projects.js b/pkg/kubernetes/scripts/test-projects.js
deleted file mode 100644
index 13f319d07..000000000
--- a/pkg/kubernetes/scripts/test-projects.js
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-import QUnit from "qunit-tests";
-var angular = require("angular");
-
-require("./projects");
-
-function suite(fixtures) {
- /* Filled in with a function */
- var inject;
-
- var module = angular.module("registry.projects.tests", [
- "kubeClient",
- "registry.projects",
- ]);
-
- function injectLoadFixtures(fixtures) {
- inject([
- "kubeLoader",
- function(loader, data) {
- loader.reset(true);
- if (fixtures)
- loader.handle(fixtures);
- }
- ]);
- }
-
- QUnit.test("format Users", function (assert) {
- var done = assert.async();
- assert.expect(4);
-
- injectLoadFixtures(fixtures);
-
- inject(["projectData", 'kubeSelect', function(projectUtil, select) {
- var user = select().kind("User")
- .name("amanda");
- assert.equal(user.length, 1, "number of users");
- assert.equal(projectUtil.formatMembers(user.one().groups, 'Groups'),
- "finance", "number of groups");
- user = select().kind("User")
- .name("jay");
- assert.equal(projectUtil.formatMembers(user.one().groups, 'Groups'),
- "4 Groups", "number of groups");
- assert.equal(projectUtil.formatMembers(user.one().groups, 'Users'),
- "4 Users", "number of users");
- done();
- }]);
- });
-
- QUnit.test("policy checks", function (assert) {
- var done = assert.async();
- assert.expect(11);
-
- injectLoadFixtures(fixtures);
-
- inject(["projectData", 'kubeSelect', function(projectUtil, select) {
- var user = select().kind("User")
- .name("amanda");
- var policybinding = select().kind("PolicyBinding")
- .namespace("financeprj")
- .name(":default");
- assert.equal(user.length, 1, "number of users");
- assert.equal(policybinding.length, 1, "number of policybinding");
- var rolesArray = projectUtil.getAllRoles("", "");
- assert.equal(rolesArray.length, 0, "no values passed 1 ");
- rolesArray = projectUtil.getAllRoles();
- assert.equal(rolesArray.length, 0, "no values passed 2");
- rolesArray = projectUtil.getAllRoles(user.one(), "financeprj");
- assert.equal(rolesArray.length, 3, "values passed");
-
- var regRolesArray = projectUtil.getRegistryRoles(user.one(), "financeprj");
- assert.equal(regRolesArray[0], "Admin", "getRegistryRoles displayRole values");
- regRolesArray = projectUtil.getRegistryRoles("", "");
- assert.equal(regRolesArray.length, 0, "no values passed 3 ");
- regRolesArray = projectUtil.getRegistryRoles();
- assert.equal(regRolesArray.length, 0, "no values passed 4");
-
- assert.equal(projectUtil.isRegistryRole(user.one(), "Admin", "financeprj"), true, "check if Admin registry role");
- assert.equal(projectUtil.isRegistryRole("system:unauthenticated", "Pull", "financeprj"), true, "check if Pull registry role");
- assert.equal(projectUtil.isRoles(user.one(), "financeprj"), true, "check if any role exist");
- done();
- }]);
- });
-
- angular.module('exceptionOverride', []).factory('$exceptionHandler', function() {
- return function(exception, cause) {
- exception.message += ' (caused by "' + cause + '")';
- throw exception;
- };
- });
-
- module.run([
- '$injector',
- function($injector) {
- inject = function inject(func) {
- return $injector.invoke(func);
- };
- QUnit.start();
- }
- ]);
-
- angular.bootstrap(document, ['registry.projects.tests']);
-}
-
-/* Invoke the test suite with this data */
-suite([
- {
- "kind": "User",
- "apiVersion": "v1",
- "metadata": {
- "name": "amanda",
- "selfLink": "/oapi/v1/users/amanda",
- "uid": "8d10b355-b9d4-11e5-b7ad-5254009e00f1",
- "resourceVersion": "1114",
- "creationTimestamp": "2016-01-13T09:03:45Z"
- },
- "identities": [
- "anypassword:abc123"
- ],
- "groups": [
- "finance"
- ]
- },
- {
- "kind": "User",
- "apiVersion": "v1",
- "metadata": {
- "name": "jay",
- "selfLink": "/oapi/v1/users/jay",
- "uid": "8d10b355-b9d4-11e5-b7ad-5254009e00f1",
- "resourceVersion": "1114",
- "creationTimestamp": "2016-01-13T09:03:45Z"
- },
- "identities": [
- "anypassword:abc123"
- ],
- "groups": [
- "finance", "admin", "hr", "dev"
- ]
- },
- {
- "kind": "Group",
- "apiVersion": "v1",
- "metadata": {
- "name": "finance",
- "selfLink": "/oapi/v1/groups/finance",
- "uid": "bff4578c-b9d4-11e5-b7ad-5254009e00f1",
- "resourceVersion": "1124",
- "creationTimestamp": "2016-01-13T09:05:10Z"
- },
- "users": [
- "tom",
- "jay",
- "amanda",
- "myadmin"
- ]
- },
- {
- "kind": "PolicyBinding",
- "apiVersion": "v1",
- "metadata": {
- "name": ":default",
- "namespace": "financeprj",
- "selfLink": "/oapi/v1/namespaces/financeprj/policybindings/:default",
- "uid": "d5a78dfc-e9e4-11e5-a1bd-3c970eb867f7",
- "resourceVersion": "53908",
- "creationTimestamp": "2016-03-14T13:01:15Z"
- },
- "lastModified": "2016-03-24T07:19:42Z",
- "policyRef": {
- "name": "default"
- },
- "roleBindings": [
- {
- "name": "admin",
- "roleBinding": {
- "metadata": {
- "name": "admin",
- "namespace": "financeprj",
- "uid": "f33cbdd7-ea0e-11e5-ba57-3c970eb867f7",
- "resourceVersion": "24003",
- "creationTimestamp": "2016-03-14T18:02:43Z"
- },
- "userNames": null,
- "groupNames": null,
- "subjects": [
-
- ],
- "roleRef": {
- "name": "admin"
- }
- }
- },
- {
- "name": "edit",
- "roleBinding": {
- "metadata": {
- "name": "edit",
- "namespace": "financeprj",
- "selfLink": "/oapi/v1/namespaces/financeprj/rolebindings/edit",
- "uid": "d5a340e0-e9e4-11e5-a1bd-3c970eb867f7",
- "resourceVersion": "24002",
- "creationTimestamp": "2016-03-14T13:01:15Z"
- },
- "userNames": [
- "amanda"
- ],
- "groupNames": null,
- "subjects": [
- {
- "kind": "User",
- "name": "amanda"
- }
- ],
- "roleRef": {
- "name": "edit"
- }
- }
- },
- {
- "name": "registry-admin",
- "roleBinding": {
- "metadata": {
- "name": "registry-admin",
- "namespace": "financeprj",
- "uid": "c0746786-f0fd-11e5-b5cb-3c970eb867f7",
- "resourceVersion": "24005",
- "creationTimestamp": "2016-03-23T13:47:15Z"
- },
- "userNames": [
- "amanda"
- ],
- "groupNames": null,
- "subjects": [
- {
- "kind": "User",
- "name": "amanda"
- }
- ],
- "roleRef": {
- "name": "registry-admin"
- }
- }
- },
- {
- "name": "registry-editor",
- "roleBinding": {
- "metadata": {
- "name": "registry-editor",
- "namespace": "financeprj",
- "selfLink": "/oapi/v1/namespaces/financeprj/rolebindings/registry-editor",
- "uid": "c613716d-f0fd-11e5-b5cb-3c970eb867f7",
- "resourceVersion": "24339",
- "creationTimestamp": "2016-03-23T13:47:24Z"
- },
- "userNames": [
- "sunny",
- "sam",
- "janet"
- ],
- "groupNames": null,
- "subjects": [
- {
- "kind": "User",
- "name": "sunny"
- },
- {
- "kind": "User",
- "name": "sam"
- },
- {
- "kind": "User",
- "name": "janet"
- }
- ],
- "roleRef": {
- "name": "registry-editor"
- }
- }
- },
- {
- "name": "registry-viewer",
- "roleBinding": {
- "metadata": {
- "name": "registry-viewer",
- "namespace": "financeprj",
- "uid": "de6e0980-f0fd-11e5-b5cb-3c970eb867f7",
- "resourceVersion": "24264",
- "creationTimestamp": "2016-03-23T13:48:05Z"
- },
- "userNames": [
- "janet",
- "sunny"
- ],
- "groupNames": null,
- "subjects": [
- {
- "kind": "User",
- "name": "janet"
- },
- {
- "kind": "User",
- "name": "sunny"
- },
- {
- "kind": "SystemGroup",
- "name": "system:unauthenticated"
- }
- ],
- "roleRef": {
- "name": "registry-viewer"
- }
- }
- },
- {
- "name": "view",
- "roleBinding": {
- "metadata": {
- "name": "view",
- "namespace": "financeprj",
- "uid": "07e34b4c-ea0f-11e5-ba57-3c970eb867f7",
- "resourceVersion": "23860",
- "creationTimestamp": "2016-03-14T18:03:18Z"
- },
- "userNames": null,
- "groupNames": null,
- "subjects": [
-
- ],
- "roleRef": {
- "name": "view"
- }
- }
- }
- ]
- },
- {
- "kind": "RoleBinding",
- "apiVersion": "v1",
- "metadata": {
- "name": "registry-admin",
- "namespace": "financeprj",
- "selfLink": "/oapi/v1/namespaces/financeprj/rolebindings/registry-admin",
- "uid": "c0746786-f0fd-11e5-b5cb-3c970eb867f7",
- "resourceVersion": "24005",
- "creationTimestamp": "2016-03-23T13:47:15Z"
- },
- "userNames": [
- "amanda"
- ],
- "groupNames": null,
- "subjects": [
- {
- "kind": "User",
- "name": "amanda"
- }
- ],
- "roleRef": {
- "name": "registry-admin"
- }
- },
- {
- "kind": "RoleBinding",
- "apiVersion": "v1",
- "metadata": {
- "name": "admin",
- "namespace": "financeprj",
- "selfLink": "/oapi/v1/namespaces/financeprj/rolebindings/admin",
- "uid": "c0746786-f0fd-11e5-b5cb-3c970eb867f7",
- "resourceVersion": "24005",
- "creationTimestamp": "2016-03-23T13:47:15Z"
- },
- "userNames": [
- "amanda"
- ],
- "groupNames": null,
- "subjects": [
- {
- "kind": "User",
- "name": "amanda"
- }
- ],
- "roleRef": {
- "name": "admin"
- }
- }
-]);
diff --git a/pkg/kubernetes/scripts/test-tags.js b/pkg/kubernetes/scripts/test-tags.js
deleted file mode 100644
index 3b1dc938f..000000000
--- a/pkg/kubernetes/scripts/test-tags.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-import QUnit from "qunit-tests";
-var angular = require("angular");
-
-require("./tags");
-
-var specData;
-
-function suite() {
- /* Filled in with a function */
- var inject;
-
- var module = angular.module("registry.tags.tests", [
- "registry.tags"
- ]);
-
- QUnit.test("parseSpec", function (assert) {
- var done = assert.async();
- assert.expect(1);
-
- inject(["imageTagData", function(data) {
- var names = data.parseSpec(specData);
- assert.deepEqual(names, [ "1", "1.23", "1.24.0", "1.24.2", "latest" ], "parsed names correctly");
- done();
- }]);
- });
-
- QUnit.test("buildSpec with spec", function (assert) {
- var done = assert.async();
- assert.expect(1);
-
- inject(["imageTagData", function(data) {
- var spec = angular.extend({ }, specData);
- spec = data.buildSpec(["2.5", "latest", "second"], spec, true, 'docker.io/busybox');
- assert.deepEqual(spec, {
- "dockerImageRepository": "busybox",
- "tags": [
- { "name": "2.5", "importPolicy": { "insecure": true },
- "from": { "kind": "DockerImage", "name": "docker.io/busybox:2.5" } },
- { "annotations": null, "from": { "kind": "DockerImage", "name": "docker.io/busybox:latest" },
- "generation": 2, "importPolicy": { "insecure": true }, "name": "latest" },
- { "name": "second", "importPolicy": { "insecure": true },
- "from": { "kind": "DockerImage", "name": "docker.io/busybox:second" } }
- ]
- }, "build spec correctly");
- done();
- }]);
- });
-
- angular.module('exceptionOverride', []).factory('$exceptionHandler', function() {
- return function(exception, cause) {
- exception.message += ' (caused by "' + cause + '")';
- throw exception;
- };
- });
-
- module.run([
- '$injector',
- function($injector) {
- inject = function inject(func) {
- return $injector.invoke(func);
- };
- QUnit.start();
- }
- ]);
-
- angular.bootstrap(document, ['registry.tags.tests']);
-}
-
-specData = {
- "dockerImageRepository": "busybox",
- "tags": [
- {
- "name": "1",
- "annotations": null,
- "from": {
- "kind": "DockerImage",
- "name": "docker.io/busybox:1"
- },
- "generation": 2,
- "importPolicy": {}
- },
- {
- "name": "1.23",
- "annotations": null,
- "from": {
- "kind": "DockerImage",
- "name": "docker.io/busybox:1.23"
- },
- "generation": 2,
- "importPolicy": {}
- },
- {
- "name": "1.24.0",
- "annotations": null,
- "from": {
- "kind": "DockerImage",
- "name": "docker.io/busybox:1.24.0"
- },
- "generation": 2,
- "importPolicy": {}
- },
- {
- "name": "1.24.2",
- "annotations": null,
- "from": {
- "kind": "DockerImage",
- "name": "docker.io/busybox:1.24.2"
- },
- "generation": 2,
- "importPolicy": {}
- },
- {
- "name": "latest",
- "annotations": null,
- "from": {
- "kind": "DockerImage",
- "name": "docker.io/busybox:latest"
- },
- "generation": 2,
- "importPolicy": {
- "insecure": false
- }
- }
- ]
-};
-
-suite();
diff --git a/pkg/kubernetes/scripts/test-utils.js b/pkg/kubernetes/scripts/test-utils.js
deleted file mode 100644
index d3fe83c05..000000000
--- a/pkg/kubernetes/scripts/test-utils.js
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-import QUnit from "qunit-tests";
-var angular = require("angular");
-
-require("./utils");
-
-function suite() {
- /* Filled in with a function */
- var inject;
-
- var module = angular.module("kubeUtils.tests", [
- "kubeUtils",
- ]);
-
- QUnit.test("map Named Array", function (assert) {
- var done = assert.async();
- assert.expect(4);
-
- inject(["KubeMapNamedArray", function lala(mapNamedArray) {
- var target = {
- "one": {
- "name": "one",
- "other": "other1",
- "value": 1
- },
- "two": {
- "name": "two",
- "other": "other2",
- "value": 2
- }
- };
- var target2 = {
- "other1": {
- "name": "one",
- "other": "other1",
- "value": 1
- },
- "other2": {
- "name": "two",
- "other": "other2",
- "value": 2
- }
- };
-
- var source = [{
- "name": "one",
- "other": "other1",
- "value": 1
- }, {
- "name": "two",
- "other": "other2",
- "value": 2
- }];
-
- assert.deepEqual(mapNamedArray(), {});
- assert.deepEqual(mapNamedArray([]), {});
- assert.deepEqual(mapNamedArray(source), target);
- assert.deepEqual(mapNamedArray(source, "other"), target2);
- done();
- }]);
- });
-
- QUnit.test("Kube string to bytes", function (assert) {
- var done = assert.async();
- assert.expect(20);
-
- inject(["KubeStringToBytes", function(stringToBytes) {
- assert.deepEqual(stringToBytes(), undefined);
- assert.deepEqual(stringToBytes("bad"), undefined);
- assert.deepEqual(stringToBytes("10"), undefined);
- assert.deepEqual(stringToBytes("aGi"), undefined);
- assert.deepEqual(stringToBytes("Gi"), undefined);
- assert.deepEqual(stringToBytes("Gi10"), undefined);
- assert.deepEqual(stringToBytes("Gil"), undefined);
- assert.deepEqual(stringToBytes("10E"), 10000000000000000000);
- assert.deepEqual(stringToBytes("10P"), 10000000000000000);
- assert.deepEqual(stringToBytes("10T"), 10000000000000);
- assert.deepEqual(stringToBytes("10G"), 10000000000);
- assert.deepEqual(stringToBytes("10M"), 10000000);
- assert.deepEqual(stringToBytes("10K"), 10000);
- assert.deepEqual(stringToBytes("10m"), 0.01);
- assert.deepEqual(stringToBytes("10Ei"), 11529215046068469760);
- assert.deepEqual(stringToBytes("10Pi"), 11258999068426240);
- assert.deepEqual(stringToBytes("10Ti"), 10995116277760);
- assert.deepEqual(stringToBytes("10Gi"), 10737418240);
- assert.deepEqual(stringToBytes("10Mi"), 10485760);
- assert.deepEqual(stringToBytes("10Ki"), 10240);
- done();
- }]);
- });
-
- angular.module('exceptionOverride', []).factory('$exceptionHandler', function() {
- return function(exception, cause) {
- exception.message += ' (caused by "' + cause + '")';
- throw exception;
- };
- });
-
- module.run([
- '$injector',
- function($injector) {
- inject = function inject(func) {
- return $injector.invoke(func);
- };
- QUnit.start();
- }
- ]);
-
- angular.bootstrap(document, ['kubeUtils.tests']);
-}
-
-suite();
diff --git a/pkg/kubernetes/scripts/test-volumes.js b/pkg/kubernetes/scripts/test-volumes.js
deleted file mode 100644
index f60cb9c93..000000000
--- a/pkg/kubernetes/scripts/test-volumes.js
+++ /dev/null
@@ -1,841 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-import QUnit from "qunit-tests";
-var angular = require("angular");
-
-require("./volumes");
-require("./kube-client-cockpit");
-
-function suite(fixtures) {
- /* Filled in with a function */
- var inject;
-
- var module = angular.module("kubernetes.volumes.tests", [
- "kubeClient",
- 'kubeClient.cockpit',
- "kubernetes.volumes",
- "kubeUtils",
- ])
-
- .config([
- 'KubeTranslateProvider',
- 'KubeFormatProvider',
- function(KubeTranslateProvider, KubeFormatProvider) {
- KubeTranslateProvider.KubeTranslateFactory = "CockpitTranslate";
- KubeFormatProvider.KubeFormatFactory = "CockpitFormat";
- }
- ]);
-
- function injectLoadFixtures(fixtures) {
- inject([
- "kubeLoader",
- function(loader, data) {
- loader.reset(true);
- if (fixtures)
- loader.handle(fixtures);
- }
- ]);
- }
-
- QUnit.test("pods for Claim", function (assert) {
- var done = assert.async();
- assert.expect(4);
-
- injectLoadFixtures(fixtures);
-
- inject(["volumeData", 'kubeSelect', function(volumeData, select) {
- var claim = select().kind("PersistentVolumeClaim")
- .name("bound-claim")
- .one();
- var pods = volumeData.podsForClaim(claim);
- assert.equal(pods.length, 1, "number of pods");
- assert.equal(pods.one().metadata.name, "mock-pod", "correct pod");
-
- pods = volumeData.podsForClaim();
- assert.deepEqual(pods.length, 0, "null claim pods");
-
- pods = volumeData.podsForClaim({});
- assert.deepEqual(pods.length, 0, "empty claim pods");
-
- done();
- }]);
- });
-
- QUnit.test("volumes for Pod", function (assert) {
- var done = assert.async();
- assert.expect(4);
-
- injectLoadFixtures(fixtures);
-
- inject(["volumeData", 'kubeSelect', function(volumeData, select) {
- var pod = select().kind("Pod")
- .one();
- var volumes = volumeData.volumesForPod(pod);
- assert.deepEqual(volumes, {
- "default-token-luvqo": {
- "name": "default-token-luvqo",
- "secret": {
- "secretName": "default-token-luvqo"
- },
- "mounts": {
- "mock-volume-container": {
- "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
- "name": "default-token-luvqo",
- "readOnly": true
- },
- "mock-volume-container1": {
- "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
- "name": "default-token-luvqo",
- "readOnly": true
- }
- }
- },
- "host-tmp": {
- "mounts": {
- "mock-volume-container": {
- "mountPath": "/other",
- "name": "host-tmp"
- },
- "mock-volume-container1": {
- "mountPath": "/tmp",
- "name": "host-tmp"
- }
- },
- "name": "host-tmp",
- "persistentVolumeClaim": {
- "claimName": "bound-claim"
- }
- },
- "missing-claim": {
- "mounts": {
- "mock-volume-container": {
- "mountPath": "/tmp",
- "name": "missing-claim"
- }
- },
- "name": "missing-claim",
- "persistentVolumeClaim": {
- "claimName": "missing-claim"
- }
- },
- "missing-claim2": {
- "name": "missing-claim2",
- "persistentVolumeClaim": {
- "claimName": "missing-claim2"
- }
- }
- });
- assert.equal(volumes, volumeData.volumesForPod(pod), "same object");
-
- assert.deepEqual(volumeData.volumesForPod(), {}, "No null volumes");
- assert.deepEqual(volumeData.volumesForPod({}), {}, "No empty volumes");
-
- done();
- }]);
- });
-
- QUnit.test("claim From Volume Source", function (assert) {
- var done = assert.async();
- assert.expect(4);
-
- injectLoadFixtures(fixtures);
-
- inject(["volumeData", 'kubeSelect', function(volumeData, select) {
- var pod = select().kind("Pod")
- .one();
- var volumes = volumeData.volumesForPod(pod);
- var source = volumes["host-tmp"]["persistentVolumeClaim"];
- var claim = volumeData.claimFromVolumeSource(source, "default");
- assert.equal(claim.metadata.name, "bound-claim", "correct claim");
- assert.equal(claim.kind, "PersistentVolumeClaim", "correct type");
-
- assert.deepEqual(volumeData.claimFromVolumeSource(), null, "No null volumes");
- assert.deepEqual(volumeData.claimFromVolumeSource({}), null, "No empty volumes");
-
- done();
- }]);
- });
-
- QUnit.test("claim For Volume", function (assert) {
- var done = assert.async();
- assert.expect(5);
-
- injectLoadFixtures(fixtures);
-
- inject(["volumeData", 'kubeSelect', function(volumeData, select) {
- var bound = select().kind("PersistentVolume")
- .name("bound")
- .one();
- var claim = volumeData.claimForVolume(bound);
-
- assert.equal(claim.metadata.name, "bound-claim", "correct claim");
- assert.equal(claim.kind, "PersistentVolumeClaim", "correct claim");
-
- var unbound = select().kind("PersistentVolume")
- .name("unbound")
- .one();
- assert.equal(volumeData.claimForVolume(unbound), null, "no claim");
-
- assert.equal(volumeData.claimForVolume(), null, "null volume");
- assert.equal(volumeData.claimForVolume(), null, "empty volume");
- done();
- }]);
- });
-
- QUnit.test("claim phases", function (assert) {
- var done = assert.async();
- assert.expect(2);
-
- injectLoadFixtures(fixtures);
-
- inject(["volumeData", 'kubeSelect', function(volumeData, select) {
- var claim = select().kind("PersistentVolumeClaim")
- .statusPhase("Bound")
- .one();
- assert.equal(claim.metadata.name, "bound-claim", "select bound claims");
-
- var pending = select().kind("PersistentVolumeClaim")
- .statusPhase("Pending")
- .one();
- assert.equal(pending.metadata.name, "unbound-claim", "select unbound claims");
- done();
- }]);
- });
-
- QUnit.test("volume Types", function (assert) {
- var done = assert.async();
- assert.expect(4);
-
- injectLoadFixtures(fixtures);
-
- inject(["volumeData", 'kubeSelect', function(volumeData, select) {
- var pv = select().kind("PersistentVolume")
- .name("bound")
- .one();
- var volumes = volumeData.volumesForPod(select().kind("Pod")
- .one());
- assert.equal(volumeData.getVolumeType(pv.spec), "nfs", "correct type");
- assert.equal(volumeData.getVolumeType(volumes["default-token-luvqo"]), "secret", "secret volume");
- assert.equal(volumeData.getVolumeType(), undefined, "null volume");
- assert.equal(volumeData.getVolumeType({}), undefined, "empty volume");
- done();
- }]);
- });
-
- QUnit.test("volume Labels", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(fixtures);
-
- inject(["volumeData", 'kubeSelect', function(volumeData, select) {
- var pv = select().kind("PersistentVolume")
- .name("bound")
- .one();
- assert.equal(volumeData.getVolumeLabel(), "Unknown", "null volume");
- assert.equal(volumeData.getVolumeLabel({}), "Unknown", "empty volume");
- assert.equal(volumeData.getVolumeLabel(pv.spec), "NFS Mount", "volume label");
- done();
- }]);
- });
-
- QUnit.test("default volume build", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(fixtures);
-
- inject(["defaultVolumeFields", "kubeSelect", function(volumeFields, select) {
- var blank_fields = {
- "accessModes": {
- "ReadOnlyMany": "Read only from multiple nodes",
- "ReadWriteMany": "Read and write from multiple nodes",
- "ReadWriteOnce": "Read and write from a single node"
- },
- "capacity": "",
- "policy": "Retain",
- "reclaimPolicies": {
- "Delete": "Delete",
- "Recycle": "Recycle",
- "Retain": "Retain"
- }
- };
-
- assert.deepEqual(blank_fields, volumeFields.build(), "default fields");
- assert.deepEqual(blank_fields, volumeFields.build({}), "empty fields");
- assert.deepEqual({
- "accessModes": {
- "ReadOnlyMany": "Read only from multiple nodes",
- "ReadWriteMany": "Read and write from multiple nodes",
- "ReadWriteOnce": "Read and write from a single node"
- },
- "capacity": "2Gi",
- "policy": "Retain",
- "ReadWriteMany": true,
- "reclaimPolicies": {
- "Delete": "Delete",
- "Recycle": "Recycle",
- "Retain": "Retain"
- }
- }, volumeFields.build(select().name("available")
- .one()), "default fields");
- done();
- }]);
- });
-
- QUnit.test("default volume validate", function (assert) {
- var done = assert.async();
- assert.expect(15);
-
- injectLoadFixtures(fixtures);
-
- inject(["defaultVolumeFields", "kubeSelect", function(volumeFields, select) {
- var result = volumeFields.validate(null, {});
- assert.equal(result.data, null, "blank fields blank data");
- assert.equal(result.errors.length, 4);
- assert.equal(result.errors[0].target, "#last-access", "blank fields access error");
- assert.equal(result.errors[1].target, "#modify-name", "blank fields name error");
- assert.equal(result.errors[2].target, "#modify-capacity", "blank fields capacity error");
- assert.equal(result.errors[3].target, "#last-policy", "blank fields policy error");
-
- var invalid = {
- "reclaimPolicies": { "policy1": "policy2" },
- "accessModes": { "mode1": "mode1" },
- "mode2": true,
- "policy" : "policy2",
- "name": "a name",
- "capacity": "invalid"
- };
- result = volumeFields.validate(null, invalid);
- assert.equal(result.data, null, "invalid fields invalid data");
- assert.equal(result.errors.length, 4);
- assert.equal(result.errors[0].target, "#last-access", "invalid fields access error");
- assert.equal(result.errors[1].target, "#modify-name", "invalid fields name error");
- assert.equal(result.errors[2].target, "#modify-capacity", "invalid fields capacity error");
- assert.equal(result.errors[3].target, "#last-policy", "invalid fields policy error");
-
- var valid = {
- "reclaimPolicies": { "policy1": "policy2" },
- "accessModes": { "mode1": "mode1" },
- "mode1": true,
- "policy" : "policy1",
- "name": " name ",
- "capacity": " 2Gi "
- };
- var spec = {
- "accessModes": [
- "mode1"
- ],
- "capacity": {
- "storage": "2Gi"
- },
- "persistentVolumeReclaimPolicy": "policy1"
- };
- result = volumeFields.validate(null, valid);
- assert.deepEqual(result.data, {
- "kind": "PersistentVolume",
- "metadata": {
- "name": "name"
- },
- "spec": spec
- }, "no item full object");
- assert.equal(result.errors.length, 0);
-
- result = volumeFields.validate({}, valid);
- assert.deepEqual(result.data, { "spec": spec }, "with item only spec");
-
- done();
- }]);
- });
-
- QUnit.test("gluster volume build", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(fixtures);
-
- inject(["glusterfsVolumeFields", "kubeSelect", function(gfs, select) {
- var endpoints = select().kind("Endpoints");
- var blank_fields = {
- "glusterfsPath": undefined,
- "endpoint": undefined,
- "endpointOptions": endpoints,
- "readOnly": undefined,
- "reclaimPolicies": {
- "Retain": "Retain"
- }
- };
-
- assert.deepEqual(blank_fields, gfs.build(), "default gluster fields");
- assert.deepEqual(blank_fields, gfs.build({}), "empty gluster fields");
- assert.deepEqual({
- "glusterfsPath": "kube_vo",
- "endpointOptions": endpoints,
- "readOnly": undefined,
- "reclaimPolicies": {
- "Retain": "Retain"
- },
- "endpoint": "my-gluster-endpoint",
- }, gfs.build(select().name("gfs-volume")
- .one()), "gluster fields");
-
- done();
- }]);
- });
-
- QUnit.test("gfs volume validate", function (assert) {
- var done = assert.async();
- assert.expect(9);
-
- injectLoadFixtures(fixtures);
-
- inject(["glusterfsVolumeFields", function(nfsVolumeFields) {
- var result = nfsVolumeFields.validate(null, {});
- assert.equal(result.data, null, "blank fields blank data");
- assert.equal(result.errors.length, 2);
- assert.equal(result.errors[0].target, "#modify-endpoint", "blank fields endpoint error");
- assert.equal(result.errors[1].target, "#modify-glusterfs-path", "blank fields path error");
-
- var invalid = {
- "endpoint": "bad",
- "glusterfsPath": "name"
- };
- result = nfsVolumeFields.validate(null, invalid);
- assert.equal(result.data, null, "invalid fields invalid data");
- assert.equal(result.errors.length, 1);
- assert.equal(result.errors[0].target, "#modify-endpoint", "invalid endpoint error");
-
- var valid = {
- "endpoint": "my-gluster-endpoint",
- "glusterfsPath": "name",
- };
- var source = {
- "endpoints": "my-gluster-endpoint",
- "path": "name",
- "readOnly": false
- };
- result = nfsVolumeFields.validate(null, valid);
- assert.deepEqual(result.data, source, "valid source result");
- assert.equal(result.errors.length, 0, "no errors when valid");
- done();
- }]);
- });
-
- QUnit.test("nfs volume build", function (assert) {
- var done = assert.async();
- assert.expect(3);
-
- injectLoadFixtures(fixtures);
-
- inject(["nfsVolumeFields", "kubeSelect", function(nfsVolumeFields, select) {
- var blank_fields = {
- "path": undefined,
- "readOnly": undefined,
- "reclaimPolicies": {
- "Recycle": "Recycle",
- "Retain": "Retain"
- },
- "server": undefined
- };
-
- assert.deepEqual(blank_fields, nfsVolumeFields.build(), "default nfs fields");
- assert.deepEqual(blank_fields, nfsVolumeFields.build({}), "empty nfs fields");
- assert.deepEqual({
- "path": "/tmp",
- "readOnly": true,
- "reclaimPolicies": {
- "Recycle": "Recycle",
- "Retain": "Retain"
- },
- "server": "host-or.ip:port",
- }, nfsVolumeFields.build(select().name("bound")
- .one()), "nfs fields");
- done();
- }]);
- });
-
- QUnit.test("nfs volume validate", function (assert) {
- var done = assert.async();
- assert.expect(10);
-
- injectLoadFixtures(fixtures);
-
- inject(["nfsVolumeFields", function(nfsVolumeFields) {
- var result = nfsVolumeFields.validate(null, {});
- assert.equal(result.data, null, "blank fields blank data");
- assert.equal(result.errors.length, 2);
- assert.equal(result.errors[0].target, "#nfs-modify-server", "blank fields server error");
- assert.equal(result.errors[1].target, "#modify-path", "blank fields path error");
-
- var invalid = {
- "server": "server/bad",
- "path": "bad",
- };
- result = nfsVolumeFields.validate(null, invalid);
- assert.equal(result.data, null, "invalid fields invalid data");
- assert.equal(result.errors.length, 2);
- assert.equal(result.errors[0].target, "#nfs-modify-server", "invalid fields server error");
- assert.equal(result.errors[1].target, "#modify-path", "invalid fields path error");
-
- var valid = {
- "server": "host.or-ip:port",
- "path": "/tmp",
- };
- var source = {
- "server": "host.or-ip:port",
- "path": "/tmp",
- "readOnly": false
- };
- result = nfsVolumeFields.validate(null, valid);
- assert.deepEqual(result.data, source, "valid source result");
- assert.equal(result.errors.length, 0, "no errors when valid");
- done();
- }]);
- });
-
- angular.module('exceptionOverride', []).factory('$exceptionHandler', function() {
- return function(exception, cause) {
- exception.message += ' (caused by "' + cause + '")';
- throw exception;
- };
- });
-
- module.run([
- '$injector',
- function($injector) {
- inject = function inject(func) {
- return $injector.invoke(func);
- };
- QUnit.start();
- }
- ]);
-
- angular.bootstrap(document, ['kubernetes.volumes.tests']);
-}
-
-/* Invoke the test suite with this data */
-suite([
- {
- "kind": "PersistentVolume",
- "apiVersion": "v1",
- "metadata": {
- "name": "iscsi-vol",
- "selfLink": "/api/v1/persistentvolumes/iscsi-vol",
- "uid": "3b2e0dc2-f6a4-11e5-9e36-5254009e00f2",
- "resourceVersion": "1325",
- "creationTimestamp": "2016-03-30T18:21:33Z"
- },
- "spec": {
- "capacity": {
- "storage": "2Gi"
- },
- "iscsi":{
- "targetPortal": "host-or.ip:port",
- "iqn": "iqn.1994-05.t.com.redhat:83ba4072bb9c",
- "lun": 10,
- "iscsiInterface": "custom-iface",
- "fsType":"ext3",
- "readOnly": true,
- },
- "accessModes":["ReadWriteOnce"],
- "persistentVolumeReclaimPolicy": "Retain"
- },
- "status": {
- "phase": "Available"
- }
- },
- {
- "kind": "PersistentVolume",
- "apiVersion": "v1",
- "metadata": {
- "name": "available",
- "selfLink": "/api/v1/persistentvolumes/available",
- "uid": "3b2e0dc2-f6a4-11e5-9e36-5254009e00f1",
- "resourceVersion": "1325",
- "creationTimestamp": "2016-03-30T18:21:33Z"
- },
- "spec": {
- "capacity": {
- "storage": "2Gi"
- },
- "hostPath": {
- "path": "/tmp"
- },
- "accessModes": [
- "ReadWriteMany"
- ],
- "persistentVolumeReclaimPolicy": "Retain"
- },
- "status": {
- "phase": "Available"
- }
- },
- {
- "kind": "PersistentVolume",
- "apiVersion": "v1",
- "metadata": {
- "name": "bound",
- "selfLink": "/api/v1/persistentvolumes/bound",
- "uid": "ae3133fc-f6a4-11e5-9e36-5254009e00f1",
- "resourceVersion": "1388",
- "creationTimestamp": "2016-03-30T18:24:46Z"
- },
- "spec": {
- "capacity": {
- "storage": "5Gi"
- },
- "nfs": {
- "path": "/tmp",
- "server": "host-or.ip:port",
- "readOnly": true
- },
- "accessModes": [
- "ReadWriteMany"
- ],
- "claimRef": {
- "kind": "PersistentVolumeClaim",
- "namespace": "default",
- "name": "bound-claim",
- "uid": "43dfbea5-f6a4-11e5-9e36-5254009e00f1",
- "apiVersion": "v1",
- "resourceVersion": "1331"
- },
- "persistentVolumeReclaimPolicy": "Retain"
- },
- "status": {
- "phase": "Bound"
- }
- },
- {
- "kind": "PersistentVolume",
- "apiVersion": "v1",
- "metadata": {
- "name": "gfs-volume",
- "selfLink": "/api/v1/persistentvolumes/gfs-volume",
- "uid": "ae3133fc-f6a4-11e5-9e36-5254009e00cc",
- "resourceVersion": "1388",
- "creationTimestamp": "2016-03-30T18:24:46Z"
- },
- "spec": {
- "capacity": {
- "storage": "5Gi"
- },
- "glusterfs": {
- "path": "kube_vo",
- "endpoints": "my-gluster-endpoint"
- },
- "accessModes": [
- "ReadWriteMany"
- ],
- "persistentVolumeReclaimPolicy": "Retain"
- },
- "status": {
- "phase": "Pending"
- }
- },
- {
- "kind": "PersistentVolumeClaim",
- "apiVersion": "v1",
- "metadata": {
- "name": "unbound-claim",
- "namespace": "default",
- "selfLink": "/api/v1/namespaces/default/persistentvolumeclaims/unbound-claim",
- "uid": "3d474220-f6b3-11e5-ab0c-3b97187a9955",
- "resourceVersion": "1331",
- "creationTimestamp": "2016-03-30T18:21:47Z"
- },
- "spec": {
- "accessModes": [
- "ReadWriteMany"
- ],
- "resources": {
- "requests": {
- "storage": "5Gi"
- }
- }
- },
- "status": {
- "phase": "Pending"
- }
- },
- {
- "kind": "PersistentVolumeClaim",
- "apiVersion": "v1",
- "metadata": {
- "name": "bound-claim",
- "namespace": "default",
- "selfLink": "/api/v1/namespaces/default/persistentvolumeclaims/bound-claim",
- "uid": "43dfbea5-f6a4-11e5-9e36-5254009e00f1",
- "resourceVersion": "1387",
- "creationTimestamp": "2016-03-30T18:21:47Z"
- },
- "spec": {
- "accessModes": [
- "ReadWriteMany"
- ],
- "resources": {
- "requests": {
- "storage": "5Gi"
- }
- },
- "volumeName": "available"
- },
- "status": {
- "phase": "Bound",
- "accessModes": [
- "ReadWriteMany"
- ],
- "capacity": {
- "storage": "5Gi"
- }
- }
- },
- {
- "kind": "Pod",
- "apiVersion": "v1",
- "metadata": {
- "name": "mock-pod",
- "namespace": "default",
- "selfLink": "/api/v1/namespaces/default/pods/mock-pod",
- "uid": "43d38e8e-f6a4-11e5-9e36-5254009e00f1",
- "resourceVersion": "1328",
- "creationTimestamp": "2016-03-30T18:21:47Z"
- },
- "spec": {
- "volumes": [
- {
- "name": "missing-claim",
- "persistentVolumeClaim": {
- "claimName": "missing-claim"
- }
- },
- {
- "name": "host-tmp",
- "persistentVolumeClaim": {
- "claimName": "bound-claim"
- }
- },
- {
- "name": "missing-claim2",
- "persistentVolumeClaim": {
- "claimName": "missing-claim2"
- }
- },
- {
- "name": "default-token-luvqo",
- "secret": {
- "secretName": "default-token-luvqo"
- }
- }
- ],
- "containers": [
- {
- "name": "mock-volume-container1",
- "image": "busybox:buildroot-2014.02",
- "command": [
- "/bin/sh",
- "-c",
- "for x in $(seq 1 1000); do echo 'HelloMessage.' \u003e\u00262; sleep 1; done"
- ],
- "ports": [
- {
- "containerPort": 9949,
- "protocol": "TCP"
- }
- ],
- "resources": {},
- "volumeMounts": [
- {
- "name": "host-tmp",
- "mountPath": "/tmp"
- },
- {
- "name": "default-token-luvqo",
- "readOnly": true,
- "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
- }
- ]
- },
- {
- "name": "mock-volume-container",
- "image": "busybox:buildroot-2014.02",
- "command": [
- "/bin/sh",
- "-c",
- "for x in $(seq 1 1000); do echo 'HelloMessage.' \u003e\u00262; sleep 1; done"
- ],
- "ports": [
- {
- "containerPort": 9949,
- "protocol": "TCP"
- }
- ],
- "resources": {},
- "volumeMounts": [
- {
- "name": "host-tmp",
- "mountPath": "/other"
- },
- {
- "name": "missing-claim",
- "mountPath": "/tmp"
- },
- {
- "name": "default-token-luvqo",
- "readOnly": true,
- "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
- }
- ]
- }
- ]
- },
- "status": {
- "phase": "Pending"
- }
- },
- {
- "kind": "Endpoints",
- "apiVersion": "v1",
- "metadata": {
- "name": "my-gluster-endpoint",
- "namespace": "default",
- "selfLink": "/api/v1/namespaces/default/endpoints/my-gluster-endpoint",
- "uid": "498cac38-ffc0-11e5-8098-5254009e00dd",
- "resourceVersion": "1078",
- "creationTimestamp": "2016-04-11T08:35:03Z"
- },
- "subsets": [
- {
- "addresses": [
- {
- "ip": "172.17.0.2"
- }
- ],
- "ports": [
- {
- "port": 1,
- "protocol": "TCP"
- }
- ]
- }
- ]
- }
-
-]);
diff --git a/pkg/kubernetes/scripts/topology.js b/pkg/kubernetes/scripts/topology.js
deleted file mode 100644
index eace11a98..000000000
--- a/pkg/kubernetes/scripts/topology.js
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
- require('angular-route');
- require('kubernetes-topology-graph/dist/topology-graph.js');
-
- require('./kube-client');
- require('./details');
-
- require('../views/topology-page.html');
-
- var icons = {
- Pod: '#vertex-Pod',
- ReplicationController: '#vertex-ReplicationController',
- Node: '#vertex-Node',
- Service: '#vertex-Service',
- DeploymentConfig: "#vertex-DeploymentConfig",
- Route: "#vertex-Route"
- };
-
- angular.module('kubernetes.topology', [
- 'ngRoute',
- 'kubernetesUI',
- 'kubeClient',
- 'kubernetes.details'
- ])
-
- .config(['$routeProvider',
- function($routeProvider) {
- $routeProvider.when('/topology/:namespace?', {
- templateUrl: 'views/topology-page.html',
- controller: 'TopologyCtrl'
- });
- }
- ])
-
- .controller('TopologyCtrl', [
- '$scope',
- '$window',
- 'kubeLoader',
- 'kubeSelect',
- 'KubeDiscoverSettings',
- 'itemActions',
- function($scope, $window, loader, select, discoverSettings, actions) {
- $scope.items = { };
- $scope.relations = [ ];
- $scope.selected = null;
-
- var ready = false;
-
- function link_for_item(kind, namespace, name) {
- var rel = select().kind(kind)
- .name(name)
- .namespace(namespace)
- .one();
- if (rel)
- return rel.metadata.selfLink;
- }
-
- function rels_for_item(item) {
- var rels = { };
- var endpoints, subsets;
- var link;
-
- /* Lookup which node this pod is scheduled on */
- if (item.kind === "Node") {
- rels = select().kind("Pod")
- .host(item.metadata.name);
-
- /* Kubernetes tells us about endpoints, which are service to pod mappings */
- } else if (item.kind === "Service") {
- endpoints = select().kind("Endpoints")
- .namespace(item.metadata.namespace)
- .name(item.metadata.name)
- .one() || { };
- subsets = endpoints.subsets || [ ];
- subsets.forEach(function(subset) {
- var addresses = subset.addresses || [ ];
- addresses.forEach(function(address) {
- if (address.targetRef && address.targetRef.kind == "Pod")
- link = link_for_item("Pod", address.targetRef.namespace,
- address.targetRef.name);
- if (link)
- rels[link] = {};
- });
- });
-
- /* For ReplicationControllers we just do the selection ourselves */
- } else if (item.kind === "ReplicationController") {
- rels = select().kind("Pod")
- .namespace(item.metadata.namespace);
- if (item.spec.selector)
- rels = rels.label(item.spec.selector);
- } else if (item.kind === "DeploymentConfig") {
- rels = select().kind("ReplicationController")
- .namespace(item.metadata.namespace)
- .label({ "openshift.io/deployment-config.name" : item.metadata.name });
- /* For Routes just build it out */
- } else if (item.kind === "Route" && item.spec.to) {
- link = link_for_item(item.spec.to.kind, item.metadata.namespace,
- item.spec.to.name);
- if (link)
- rels[link] = {};
- }
- return rels;
- }
-
- loader.watch("Node", $scope);
- loader.watch("Pod", $scope);
- loader.watch("ReplicationController", $scope);
- loader.watch("Service", $scope);
- loader.watch("Endpoints", $scope);
-
- discoverSettings().then(function(settings) {
- if (settings.flavor === "openshift") {
- loader.watch("DeploymentConfig", $scope);
- loader.watch("Route", $scope);
- }
- });
-
- loader.listen(function(changed, removed) {
- var selected_meta;
- var relations = [];
- var item;
- var key;
-
- $scope.items = select();
- if ($scope.selected) {
- selected_meta = $scope.selected.metadata || {};
- item = select().kind($scope.selected.kind)
- .name(selected_meta.name);
- if (selected_meta.namespace)
- item = item.namespace(selected_meta.namespace);
- $scope.selected = item.one();
- }
-
- for (key in $scope.items) {
- var pkey;
- var rels = rels_for_item($scope.items[key]);
- for (pkey in rels)
- relations.push({ source: key, target: pkey });
- }
-
- $scope.relations = relations;
- }, $scope);
-
- $scope.$on("select", function(ev, item) {
- $scope.$applyAsync(function () {
- $scope.selected = item;
- });
- });
-
- /* Make a copy since we modify */
- $scope.kinds = angular.copy(icons);
-
- /* All the actions available on the $scope */
- angular.extend($scope, actions);
-
- function resized() {
- $scope.height = { height: (window.innerHeight - 60) + "px" };
- if (ready)
- $scope.$digest();
- }
-
- angular.element($window).bind('resize', resized);
- resized();
-
- ready = true;
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/utils.js b/pkg/kubernetes/scripts/utils.js
deleted file mode 100644
index 21a86dcd3..000000000
--- a/pkg/kubernetes/scripts/utils.js
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
-
- angular.module("kubeUtils", [])
-
- .factory("KubeMapNamedArray", [
- function () {
- return function mapNamedArray(array, attr) {
- if (!attr)
- attr = "name";
-
- var result = { };
- var i, len;
- if (array) {
- for (i = 0, len = array.length; i < len; i++)
- result[array[i][attr]] = array[i];
- }
- return result;
- };
- }
- ])
-
- .factory("KubeStringToBytes", [
- function() {
- return function (byte_string) {
- var valid_suffixes = {
- "E": 1000000000000000000,
- "P": 1000000000000000,
- "T": 1000000000000,
- "G": 1000000000,
- "M": 1000000,
- "K": 1000,
- "m": 0.001,
- "Ei": 1152921504606846976,
- "Pi": 1125899906842624,
- "Ti": 1099511627776,
- "Gi": 1073741824,
- "Mi": 1048576,
- "Ki": 1024,
- };
-
- if (!byte_string)
- return;
-
- byte_string = byte_string.trim();
- for (var key in valid_suffixes) {
- if (byte_string.length > key.length &&
- byte_string.slice(-key.length) === key) {
- var number = Number(byte_string.slice(0, -key.length));
- if (!isNaN(number))
- return number * valid_suffixes[key];
- }
- }
- };
- }
- ])
-
- .provider('KubeFormat', [
- function() {
- var self = this;
-
- /* Until we come up with a good default implementation, must be provided */
- self.KubeFormatFactory = "MissingFormat";
-
- function load(injector, name) {
- if (angular.isString(name))
- return injector.get(name, "KubeFormat");
- else
- return injector.invoke(name);
- }
-
- self.$get = [
- "$injector",
- function($injector) {
- return load($injector, self.KubeFormatFactory);
- }
- ];
- }
- ])
-
- .factory("MissingFormat", [
- function() {
- return function MissingFormatCapacity(value) {
- throw Error("no KubeFormatFactory set");
- };
- }
- ])
-
- .provider('KubeTranslate', [
- function() {
- var self = this;
-
- /* Until we come up with a good default implementation, must be provided */
- self.KubeTranslateFactory = "KubeTranslate";
-
- function load(injector, name) {
- if (angular.isString(name))
- return injector.get(name, "MissingKubeTranslate");
- else
- return injector.invoke(name);
- }
-
- self.$get = [
- "$injector",
- function($injector) {
- return load($injector, self.KubeTranslateFactory);
- }
- ];
- }
- ])
-
- .factory("MissingKubeTranslate", [
- function() {
- function error_func() {
- throw Error("no KubeTranslateFactory set");
- }
-
- return {
- gettext: error_func,
- ngettext: error_func
- };
- }
- ])
-
- .provider('KubeBrowserStorage', [
- function() {
- var self = this;
-
- /* Until we come up with a good default implementation, must be provided */
- self.KubeBrowserStorageFactory = "DefaultKubeBrowserStorage";
-
- function load(injector, name) {
- if (angular.isString(name))
- return injector.get(name, "DefaultKubeBrowserStorage");
- else
- return injector.invoke(name);
- }
-
- self.$get = [
- "$injector",
- function($injector) {
- return load($injector, self.KubeBrowserStorageFactory);
- }
- ];
- }
- ])
-
- .factory("DefaultKubeBrowserStorage", [
- "$window",
- function($window) {
- return {
- localStorage: $window.localStorage,
- sessionStorage: $window.sessionStorage,
- };
- }
- ])
-
- .filter('formatCapacityName', function() {
- return function(key) {
- var data;
- if (key == "cpu") {
- data = "CPUs";
- } else {
- key = key.replace(/-/g, " ");
- data = key.charAt(0).toUpperCase() + key.substr(1);
- }
- return data;
- };
- })
-
- .filter('formatCapacityValue', [
- "KubeFormat",
- "KubeStringToBytes",
- function (format, stringToBytes) {
- return function(value, key) {
- if (key == "memory") {
- var raw = stringToBytes(value);
- if (raw)
- value = format.formatBytes(raw);
- }
- return value;
- };
- }
- ]);
-}());
diff --git a/pkg/kubernetes/scripts/volumes.js b/pkg/kubernetes/scripts/volumes.js
deleted file mode 100644
index 09cc6409b..000000000
--- a/pkg/kubernetes/scripts/volumes.js
+++ /dev/null
@@ -1,1042 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-(function() {
- var angular = require('angular');
- require('angular-route');
- require('angular-dialog.js');
-
- require('./date');
- require('./listing');
- require('./kube-client');
- require('./utils');
-
- require('../views/volumes-page.html');
- require('../views/pv-page.html');
- require('../views/pv-body.html');
- require('../views/pvc-body.html');
- require('../views/pv-claim.html');
- require('../views/volume-body.html');
- require('../views/pvc-delete.html');
- require('../views/pv-delete.html');
- require('../views/pv-modify.html');
-
- var VOLUME_FACTORY_SUFFIX = "VolumeFields";
-
- angular.module('kubernetes.volumes', [
- 'ngRoute',
- 'kubeClient',
- 'kubernetes.date',
- 'kubernetes.listing',
- 'ui.cockpit',
- ])
-
- .config([
- '$routeProvider',
- function($routeProvider) {
- $routeProvider
- .when('/volumes', {
- templateUrl: 'views/volumes-page.html',
- controller: 'VolumeCtrl'
- })
-
- .when('/volumes/:target', {
- controller: 'VolumeCtrl',
- templateUrl: 'views/pv-page.html'
- });
- }
- ])
-
- /*
- * The controller for the volumes view.
- */
- .controller('VolumeCtrl', [
- '$scope',
- 'kubeLoader',
- 'kubeSelect',
- 'ListingState',
- 'filterService',
- '$routeParams',
- '$location',
- 'volumeActions',
- '$timeout',
- function($scope, loader, select, ListingState, filterService,
- $routeParams, $location, actions, $timeout) {
- var target = $routeParams["target"] || "";
- $scope.target = target;
- $scope.pvFailure = null;
-
- loader.listen(function() {
- $scope.pending = select().kind("PersistentVolumeClaim")
- .statusPhase("Pending");
- $scope.pvs = select().kind("PersistentVolume");
- if (target)
- $scope.item = select().kind("PersistentVolume")
- .name(target)
- .one();
- }, $scope);
-
- loader.watch("PersistentVolume", $scope)
- .catch(function (ex) {
- $scope.pvFailure = ex.message;
- });
-
- loader.watch("PersistentVolumeClaim", $scope);
- loader.watch("Endpoints", $scope);
- loader.watch("Pod", $scope);
-
- $scope.listing = new ListingState($scope);
-
- /* All the actions available on the $scope */
- angular.extend($scope, actions);
-
- /* Redirect after a delete */
- $scope.deletePV = function(item) {
- var promise = actions.deletePV(item);
-
- /* If the promise is successful, redirect to another page */
- promise.then(function() {
- if ($scope.target)
- $location.path('/volumes/');
- });
-
- return promise;
- };
-
- $scope.$on("activate", function(ev, id) {
- ev.preventDefault();
- $location.path('/volumes/' + id);
- });
- }
- ])
-
- .directive('pvBody',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/pv-body.html'
- };
- }
- )
-
- .directive('pvcBody',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/pvc-body.html',
- scope: {
- item: '=item',
- settings: '=settings'
- },
- };
- }
- )
-
- .directive('pvClaim', [
- 'volumeData',
- 'kubeLoader',
- function(volumeData, loader) {
- return {
- restrict: 'A',
- templateUrl: 'views/pv-claim.html',
- link: function(scope, element, attrs) {
- loader.listen(function() {
- scope.pvc = volumeData.claimForVolume(scope.item);
- scope.pods = volumeData.podsForClaim(scope.pvc);
- }, scope);
-
- loader.watch("PersistentVolume", scope);
- loader.watch("PersistentVolumeClaim", scope);
- loader.watch("Pod", scope);
- },
- };
- }
- ])
-
- .directive('volumeBody',
- function() {
- return {
- restrict: 'A',
- templateUrl: 'views/volume-body.html',
- scope: {
- volume: '=volume'
- },
- };
- }
- )
-
- .factory("volumeData", [
- 'kubeSelect',
- "KubeTranslate",
- "KubeMapNamedArray",
- function (select, translate, mapNamedArray) {
- const _ = translate.gettext;
-
- var KNOWN_VOLUME_TYPES = {
- "gcePersistentDisk" : _("GCE Persistent Disk"),
- "awsElasticBlockStore" : _("AWS Elastic Block Store"),
- "gitRepo" : _("Git Repository"),
- "secret" : _("Secret"),
- "emptyDir" : _("Empty Directory"),
- "hostPath" : _("Host Path"),
- "glusterfs" : _("Gluster FS"),
- "nfs" : _("NFS Mount"),
- "rbd" : _("Rados Block Device"),
- "iscsi" : _("ISCSI"),
- "cinder" : _("Cinder"),
- "cephfs" : _("Ceph Filesystem Mount"),
- "fc" : _("Fibre Channel"),
- "flocker" : _("Flocker"),
- "flexVolume" : _("Flex"),
- "azureFile" : _("Azure")
- };
-
- var ACCESS_MODES = {
- "ReadWriteOnce" : _("Read and write from a single node"),
- "ReadOnlyMany" : _("Read only from multiple nodes"),
- "ReadWriteMany" : _("Read and write from multiple nodes"),
- };
-
- var RECLAIM_POLICIES = {
- "Retain" : _("Retain"),
- "Delete" : _("Delete"),
- "Recycle" : _("Recycle")
- };
-
- select.register({
- name: "volumeName",
- digest: function(arg) {
- if (typeof arg === "string")
- return arg;
-
- var spec = arg.spec || {};
- return spec.volumeName;
- }
- });
-
- select.register({
- name: "claim",
- digests: function(arg) {
- if (typeof arg === "string")
- return ["claimName=" + arg];
-
- var i;
- var ret = [];
- var spec = arg.spec || {};
- var vols = spec.volumes || [];
- for (i in vols) {
- var claim = vols[i].persistentVolumeClaim || {};
- if (claim.claimName)
- ret.push("claimName=" + claim.claimName);
- }
- return ret;
- }
- });
-
- function getVolumeType(volume) {
- var keys = Object.keys(KNOWN_VOLUME_TYPES);
- var i;
- volume = volume || {};
- for (i = 0; i < keys.length; i++) {
- var key = keys[i];
- if (volume[key])
- return key;
- }
- }
-
- function getVolumeLabel(volume) {
- var type = getVolumeType(volume);
- if (type)
- return KNOWN_VOLUME_TYPES[type];
- return _("Unknown");
- }
-
- function claimForVolume(volume) {
- var uid = "";
- if (volume && volume.spec.claimRef)
- uid = volume.spec.claimRef.uid || "";
-
- return select().kind("PersistentVolumeClaim")
- .uid(uid)
- .one();
- }
-
- function claimFromVolumeSource(source, namespace) {
- source = source || {};
- return select().kind("PersistentVolumeClaim")
- .namespace(namespace || "")
- .name(source.claimName || "")
- .one();
- }
-
- function podsForClaim(claim) {
- var meta;
- claim = claim || {};
- meta = claim.metadata || {};
- return select().kind("Pod")
- .namespace(meta.namespace || "")
- .claim(meta.name || "");
- }
-
- function volumesForPod(item) {
- var volumes;
- var i, j, container, volumeMounts, name;
- if (item && !item.volumes) {
- if (item.spec)
- volumes = mapNamedArray(item.spec.volumes);
- else
- volumes = { };
-
- if (item.spec && item.spec.containers) {
- for (i = 0; i < item.spec.containers.length; i++) {
- container = item.spec.containers[i];
- volumeMounts = container.volumeMounts || [];
- for (j = 0; j < volumeMounts.length; j++) {
- name = volumeMounts[j].name;
- if (!volumes[name])
- volumes[name] = {};
-
- if (!volumes[name]['mounts'])
- volumes[name]['mounts'] = {};
-
- volumes[name]['mounts'][container.name] = volumeMounts[j];
- }
- }
- }
-
- item.volumes = volumes;
- }
- return item ? item.volumes : { };
- }
-
- return {
- podsForClaim: podsForClaim,
- volumesForPod: volumesForPod,
- claimFromVolumeSource: claimFromVolumeSource,
- claimForVolume: claimForVolume,
- getVolumeType: getVolumeType,
- getVolumeLabel: getVolumeLabel,
- reclaimPolicies: RECLAIM_POLICIES,
- accessModes: ACCESS_MODES,
- };
- }
- ])
-
- .factory('volumeActions', [
- '$modal',
- '$injector',
- 'volumeData',
- function($modal, $injector, volumeData) {
- function canEdit(item) {
- var spec = item ? item.spec : {};
- var type = volumeData.getVolumeType(spec);
- if (type)
- return $injector.has(type + VOLUME_FACTORY_SUFFIX);
- return true;
- }
-
- function deleteItem(item, resolve, template, ev) {
- if (ev)
- ev.stopPropagation();
-
- return $modal.open({
- animation: false,
- controller: 'VolumeDeleteCtrl',
- templateUrl: template,
- resolve: resolve,
- }).result;
- }
-
- function deletePVC(item, ev) {
- var resolve = {
- dialogData: function() {
- return { item: item,
- pvc: item,
- pods: volumeData.podsForClaim(item) };
- }
- };
- return deleteItem(item, resolve, 'views/pvc-delete.html', ev);
- }
-
- function deletePV(item, ev) {
- var resolve = {
- dialogData: function() {
- return { item: item };
- }
- };
- return deleteItem(item, resolve, 'views/pv-delete.html', ev);
- }
-
- function createPV(item) {
- return $modal.open({
- animation: false,
- controller: 'PVModifyCtrl',
- templateUrl: 'views/pv-modify.html',
- resolve: {
- dialogData: function() {
- return { pvc : item };
- }
- },
- }).result;
- }
-
- function modifyPV(item) {
- return $modal.open({
- animation: false,
- controller: 'PVModifyCtrl',
- templateUrl: 'views/pv-modify.html',
- resolve: {
- dialogData: function() {
- return { item: item };
- }
- },
- }).result;
- }
-
- return {
- modifyPV: modifyPV,
- createPV: createPV,
- deletePV: deletePV,
- deletePVC: deletePVC,
- canEdit: canEdit,
- };
- }
- ])
-
- .factory("defaultVolumeFields", [
- "volumeData",
- "KubeStringToBytes",
- "KubeTranslate",
- "KUBE_NAME_RE",
- function (volumeData, stringToBytes, translate, NAME_RE) {
- const _ = translate.gettext;
-
- function build (item, type) {
- if (!item)
- item = {};
-
- var spec = item.spec || {};
- var requests, storage;
-
- if (item.kind == "PersistentVolumeClaim") {
- requests = spec.resources ? spec.resources.requests : {};
- storage = requests ? requests.storage : "";
- } else {
- storage = spec.capacity ? spec.capacity.storage : "";
- }
-
- var fields = {
- "capacity" : storage || "",
- "policy" : spec.persistentVolumeReclaimPolicy || "Retain",
- "accessModes": volumeData.accessModes,
- "reclaimPolicies": volumeData.reclaimPolicies,
- };
-
- var i;
- for (i in spec.accessModes || []) {
- fields[spec.accessModes[i]] = true;
- }
-
- return fields;
- }
-
- function validate (item, fields) {
- var ex, spec, name, capacity, policy, i, validModes;
- var accessModes = [];
- var ret = {
- errors: [],
- data: null,
- };
-
- validModes = Object.keys(fields.accessModes || {});
- for (i = 0; i < validModes.length; i++) {
- var mode = validModes[i];
- if (fields[mode])
- accessModes.push(mode);
- }
-
- if (accessModes.length < 1) {
- ex = new Error(_("Please select a valid access mode"));
- ex.target = "#last-access";
- ret.errors.push(ex);
- ex = null;
- }
-
- name = fields.name ? fields.name.trim() : fields.name;
- if (!item && (!name || !NAME_RE.test(name))) {
- ex = new Error(_("Please provide a valid name"));
- ex.target = "#modify-name";
- ret.errors.push(ex);
- ex = null;
- }
-
- capacity = fields.capacity ? fields.capacity.trim() : fields.capacity;
- if (!item && (!capacity || !stringToBytes(capacity))) {
- ex = new Error(_("Please provide a valid storage capacity."));
- ex.target = "#modify-capacity";
- ret.errors.push(ex);
- ex = null;
- }
-
- policy = fields.policy ? fields.policy.trim() : fields.policy;
- if (!fields.reclaimPolicies || !fields.reclaimPolicies[policy]) {
- ex = new Error(_("Please select a valid policy option."));
- ex.target = "#last-policy";
- ret.errors.push(ex);
- ex = null;
- }
-
- if (ret.errors.length < 1) {
- spec = {
- "accessModes" : accessModes,
- "capacity" : { "storage" : capacity },
- "persistentVolumeReclaimPolicy" : policy,
- };
-
- if (item) {
- ret.data = {
- spec: spec
- };
- } else {
- ret.data = {
- kind: "PersistentVolume",
- metadata: {
- name: fields.name.trim()
- },
- spec: spec
- };
- }
- }
-
- return ret;
- }
-
- return {
- build: build,
- validate: validate,
- };
- }
- ])
-
- .factory("glusterfs" + VOLUME_FACTORY_SUFFIX, [
- "volumeData",
- "KubeTranslate",
- "kubeSelect",
- function (volumeData, translate, select) {
- const _ = translate.gettext;
-
- function build(item) {
- if (!item)
- item = {};
-
- var spec = item.spec || {};
- var glusterfs = spec.glusterfs || {};
-
- return {
- endpoint: glusterfs.endpoints,
- endpointOptions: select().kind("Endpoints"),
- glusterfsPath: glusterfs.path,
- readOnly: glusterfs.readOnly,
- reclaimPolicies: {
- "Retain" : volumeData.reclaimPolicies["Retain"]
- },
- };
- }
-
- function validate (item, fields) {
- var ex, endpoint, path;
- var ret = {
- errors: [],
- data: null,
- };
-
- endpoint = fields.endpoint ? fields.endpoint.trim() : fields.endpoint;
- if (!select().kind("Endpoints")
- .name(endpoint)
- .one()) {
- ex = new Error(_("Please select a valid endpoint"));
- ex.target = "#modify-endpoint";
- ret.errors.push(ex);
- ex = null;
- }
-
- // The API calls glusterfs volume name, path.
- path = fields.glusterfsPath ? fields.glusterfsPath.trim() : fields.glusterfsPath;
- if (!path) {
- ex = new Error(_("Please provide a GlusterFS volume name"));
- ex.target = "#modify-glusterfs-path";
- ret.errors.push(ex);
- ex = null;
- }
-
- if (ret.errors.length < 1) {
- ret.data = {
- endpoints: endpoint,
- path: path,
- readOnly: !!fields.readOnly
- };
- }
-
- return ret;
- }
-
- return {
- build: build,
- validate: validate,
- };
- }
- ])
-
- .factory("nfs" + VOLUME_FACTORY_SUFFIX, [
- "volumeData",
- "KubeTranslate",
- function (volumeData, translate) {
- const _ = translate.gettext;
-
- function build(item) {
- if (!item)
- item = {};
-
- var spec = item.spec || {};
- var nfs = spec.nfs || {};
- return {
- server: nfs.server,
- path: nfs.path,
- readOnly: nfs.readOnly,
- reclaimPolicies: {
- "Recycle" : volumeData.reclaimPolicies["Recycle"],
- "Retain" : volumeData.reclaimPolicies["Retain"],
- },
- };
- }
-
- function validate (item, fields) {
- var regex = /^[a-z0-9.:-]+$/i;
-
- var ex, server, path;
- var ret = {
- errors: [],
- data: null,
- };
-
- server = fields.server ? fields.server.trim() : fields.server;
- if (!server || !regex.test(server)) {
- ex = new Error(_("Please provide a valid NFS server"));
- ex.target = "#nfs-modify-server";
- ret.errors.push(ex);
- ex = null;
- }
-
- path = fields.path ? fields.path.trim() : fields.path;
- if (!path || path.search("/") !== 0) {
- ex = new Error(_("Please provide a valid path"));
- ex.target = "#modify-path";
- ret.errors.push(ex);
- ex = null;
- }
-
- if (ret.errors.length < 1) {
- ret.data = {
- server: server,
- path: path,
- readOnly: !!fields.readOnly
- };
- }
-
- return ret;
- }
-
- return {
- build: build,
- validate: validate,
- };
- }
- ])
-
- .factory("hostPath" + VOLUME_FACTORY_SUFFIX, [
- "volumeData",
- "KubeTranslate",
- function (volumeData, translate) {
- const _ = translate.gettext;
-
- function build(item) {
- if (!item)
- item = {};
-
- var spec = item.spec || {};
- var hp = spec.hostPath || {};
- return {
- path: hp.path,
- readOnly: hp.readOnly,
- reclaimPolicies: {
- "Recycle" : volumeData.reclaimPolicies["Recycle"],
- "Retain" : volumeData.reclaimPolicies["Retain"],
- },
- };
- }
-
- function validate (item, fields) {
- var ex, path;
- var ret = {
- errors: [],
- data: null,
- };
-
- path = fields.path ? fields.path.trim() : fields.path;
- if (!path || path.search("/") !== 0) {
- ex = new Error(_("Please provide a valid path"));
- ex.target = "#modify-path";
- ret.errors.push(ex);
- ex = null;
- }
-
- if (ret.errors.length < 1) {
- ret.data = {
- path: path,
- };
- }
-
- return ret;
- }
-
- return {
- build: build,
- validate: validate,
- };
- }
- ])
-
- .controller("VolumeDeleteCtrl", [
- "$scope",
- "$modalInstance",
- "dialogData",
- "volumeData",
- "kubeMethods",
- "kubeLoader",
- function($scope, $instance, dialogData, volumeData, methods, loader) {
- angular.extend($scope, dialogData);
-
- loader.listen(function() {
- if ($scope.pvc)
- $scope.pods = volumeData.podsForClaim($scope.pvc);
- }, $scope);
-
- $scope.performDelete = function performDelete() {
- return methods.delete($scope.item);
- };
- }
- ])
-
- .factory("iscsi" + VOLUME_FACTORY_SUFFIX, [
- "volumeData",
- "KubeTranslate",
- function (volumeData, translate) {
- const _ = translate.gettext;
-
- function build(item) {
- if (!item)
- item = {};
-
- var spec = item.spec || {};
- var source = spec.iscsi || {};
- return {
- target: source.targetPortal,
- fstype: source.fsType || "ext4",
- iqn: source.iqn,
- lun: source.lun || 0,
- iface: source.iscsiInterface,
- readOnly: source.readOnly,
- ReadWriteOnce: true,
- accessModes: {
- "ReadWriteOnce": volumeData.accessModes["ReadWriteOnce"],
- },
- reclaimPolicies: {
- "Retain": volumeData.reclaimPolicies["Retain"],
- },
- };
- }
-
- function validate (item, fields) {
- var ex, lun, target, iqn, fs, iface;
- var regex = /^[a-z0-9.:-]+$/i;
-
- var ret = {
- errors: [],
- data: null,
- };
-
- target = fields.target ? fields.target.trim() : fields.target;
- if (!target || !regex.test(target)) {
- ex = new Error(_("Please provide a valid target"));
- ex.target = "#modify-iscsi-target";
- ret.errors.push(ex);
- ex = null;
- }
-
- iqn = fields.iqn ? fields.iqn.trim() : fields.iqn;
- if (!iqn || !regex.test(iqn)) {
- ex = new Error(_("Please provide a valid qualified name"));
- ex.target = "#modify-iscsi-iqn";
- ret.errors.push(ex);
- ex = null;
- }
-
- lun = parseInt(fields.lun ? fields.lun.trim() : fields.lun, 10);
- if (isNaN(lun)) {
- ex = new Error(_("Please provide a valid logical unit number"));
- ex.target = "#modify-iscsi-lun";
- ret.errors.push(ex);
- ex = null;
- }
-
- fs = fields.fstype ? fields.fstype.trim() : "ext4";
- if (!regex.test(fs)) {
- ex = new Error(_("Please provide a valid filesystem type"));
- ex.target = "#modify-fstype";
- ret.errors.push(ex);
- ex = null;
- }
-
- iface = fields.iface ? fields.iface.trim() : undefined;
- if (iface && !regex.test(iface)) {
- ex = new Error(_("Please provide a valid interface"));
- ex.target = "#modify-iscsi-iface";
- ret.errors.push(ex);
- ex = null;
- }
-
- if (ret.errors.length < 1) {
- ret.data = {
- iqn: iqn,
- lun: lun,
- fsType: fs,
- targetPortal: target,
- readOnly: !!fields.readOnly
- };
- if (iface)
- ret.data["iscsiInterface"] = iface;
- }
-
- return ret;
- }
-
- return {
- build: build,
- validate: validate,
- };
- }
- ])
-
- .controller("PVModifyCtrl", [
- "$q",
- "$scope",
- "$injector",
- "$modalInstance",
- "dialogData",
- "volumeData",
- "defaultVolumeFields",
- "kubeMethods",
- "KubeTranslate",
- function($q, $scope, $injector, $instance, dialogData, volumeData,
- defaultVolumeFields, methods, translate) {
- const _ = translate.gettext;
- var volumeFields, valName;
-
- angular.extend($scope, dialogData);
-
- $scope.types = [
- {
- name: _("NFS"),
- type: "nfs",
- },
- {
- name: _("Host Path"),
- type: "hostPath",
- },
- {
- name: _("ISCSI"),
- type: "iscsi",
- },
- {
- name: _("GlusterFS"),
- type: "glusterfs",
- },
- ];
-
- function selectType(type) {
- $scope.current_type = type;
- valName = $scope.current_type + VOLUME_FACTORY_SUFFIX;
- $scope.fields = defaultVolumeFields.build($scope.item || $scope.pvc);
- if ($injector.has(valName)) {
- volumeFields = $injector.get(valName, "PVModifyCtrl");
- angular.extend($scope.fields, volumeFields.build($scope.item || $scope.pvc));
- } else {
- $scope.$applyAsync(function () {
- $scope.$dismiss();
- });
- }
- }
-
- if ($scope.item) {
- $scope.current_type = volumeData.getVolumeType($scope.item.spec);
- selectType(volumeData.getVolumeType($scope.item.spec));
- } else {
- $scope.selected = $scope.types[0];
- selectType($scope.selected.type);
- }
-
- function validate() {
- var defer = $q.defer();
- var resp, main_resp;
- var errors = [];
-
- if (!$scope.item) {
- valName = $scope.current_type + VOLUME_FACTORY_SUFFIX;
- if ($injector.has(valName))
- volumeFields = $injector.get(valName, "PVModifyCtrl");
- else
- errors.push(new Error(_("Sorry, I don't know how to modify this volume")));
- }
-
- if (volumeFields) {
- resp = volumeFields.validate($scope.item, $scope.fields);
- errors = resp.errors;
- }
-
- main_resp = defaultVolumeFields.validate($scope.item, $scope.fields);
- errors = errors.concat(main_resp.errors);
-
- if (errors.length > 0) {
- defer.reject(errors);
- } else {
- main_resp.data.spec[$scope.current_type] = resp ? resp.data : null;
- defer.resolve(main_resp.data);
- }
-
- return defer.promise;
- }
-
- function updatePVC() {
- /*
- * HACK: https://github.com/kubernetes/kubernetes/issues/21498
- *
- * Until the API gets a way to manually
- * trigger the process that matches a volume with a claim
- * we change something else on the claim to try to kick things
- * off sooner. Otherwise in the worse case
- * the user will need to wait for around 10 mins.
- */
- if ($scope.pvc) {
- return methods.patch($scope.pvc, {
- "metadata" : {
- "annotations" : {
- "claimTrigger": "on"
- }
- }
- })
- .then(function () {
- methods.patch($scope.pvc, {
- "metadata" : {
- "annotations" : {
- "claimTrigger": null
- }
- }
- });
- });
- }
- }
-
- $scope.select = function(type) {
- $scope.selected = type;
- selectType(type.type);
- };
-
- $scope.setField = function(name, value) {
- $scope.fields[name] = value;
- };
-
- $scope.hasField = function(name) {
- return $scope.fields.hasOwnProperty(name);
- };
-
- $scope.performModify = function performModify() {
- return validate().then(function(data) {
- var res;
- if (!$scope.item)
- res = methods.create(data, null);
- else
- res = methods.patch($scope.item, data);
- return res.then(updatePVC);
- });
- };
- }
- ])
-
- .filter("formatReadOnly", [
- "KubeTranslate",
- function(translate) {
- return function(readOnly) {
- if (readOnly)
- return translate.gettext("Yes");
- else
- return translate.gettext("No");
- };
- }
- ])
-
- .filter("formatPartitionNumber", [
- function() {
- return function(partition) {
- if (!partition)
- return 0;
- else
- return partition;
- };
- }
- ])
-
- .filter("formatVolumeType", [
- 'volumeData',
- function(volumeData) {
- return function(volume) {
- return volumeData.getVolumeLabel(volume || {});
- };
- }
- ])
-
- .filter("reclaimLabel", [
- 'volumeData',
- function(volumeData) {
- return function(policy) {
- var label = volumeData.reclaimPolicies[policy || ""];
- return label || policy;
- };
- }
- ])
-
- .filter("accessModeLabel", [
- 'volumeData',
- function(volumeData) {
- return function(mode) {
- var label = volumeData.accessModes[mode || ""];
- return label || mode;
- };
- }
- ]);
-}());
diff --git a/pkg/kubernetes/standalone/src/cockpit-kube-auth/helpers/client.go b/pkg/kubernetes/standalone/src/cockpit-kube-auth/helpers/client.go
deleted file mode 100644
index 9f80b5d5b..000000000
--- a/pkg/kubernetes/standalone/src/cockpit-kube-auth/helpers/client.go
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-package helpers
-
-import (
- "bytes"
- "crypto/tls"
- "crypto/x509"
- "encoding/base64"
- "encoding/json"
- "errors"
- "fmt"
- "io/ioutil"
- "log"
- "net/http"
- "os"
- "strconv"
- "strings"
-)
-
-const CA_PATH = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
-
-type AuthError struct {
- msg string
-}
-
-func (v *AuthError) Error() string {
- return v.msg
-}
-
-func newAuthError(msg string) error {
- return &AuthError{msg}
-}
-
-// helpers
-func namedArrayObject(key string, name string, m map[string]interface{}) []map[string]interface{} {
- nm := make(map[string]interface{})
- nm[key] = m
- nm["name"] = name
- s := make([]map[string]interface{}, 1)
- s[0] = nm
- return s
-}
-
-// Struct for decoding json
-type userInfo struct {
- FullName string `json:"fullName"`
- MetaData struct {
- Name string `json:"name"`
- } `json:"metadata"`
-}
-
-type apiVersions struct {
- Versions []string `json:"versions"`
-}
-
-// Simple client
-type Client struct {
- host string
- version string
-
- caData string
- insecure bool
- requireOpenshift bool
- isOpenshift bool
-
- userAPI string
- client *http.Client
- creds *Credentials
-}
-
-func doRequest(client *http.Client, method string, path string, auth string, body []byte) (*http.Response, error) {
- var req *http.Request
- var err error
- if body != nil {
- req, err = http.NewRequest(method, path, bytes.NewReader(body))
- } else {
- req, err = http.NewRequest(method, path, nil)
- }
-
- if err != nil {
- return nil, err
- }
-
- if auth != "" {
- req.Header.Add("Authorization", auth)
- }
- return client.Do(req)
-}
-
-func (self *Client) fetchVersion(authHeader string) error {
- path := fmt.Sprintf("%s/api", self.host)
- resp, err := doRequest(self.client, "GET", path, authHeader, nil)
-
- // Treat connection errors as internal errors and invalid
- // responses as auth errors
- if err != nil {
- return errors.New(fmt.Sprintf("Couldn't connect to the api: %s", err))
- }
-
- defer resp.Body.Close()
-
- if resp.StatusCode != 200 {
- return newAuthError(fmt.Sprintf("Couldn't get api version: %s", resp.Status))
- }
-
- data := apiVersions{}
- deErr := json.NewDecoder(resp.Body).Decode(&data)
- if deErr != nil {
- return newAuthError(fmt.Sprintf("Couldn't get api version: %s", deErr))
- }
-
- if len(data.Versions) < 1 {
- return newAuthError(fmt.Sprintf("Couldn't get api version: invalid data"))
- }
-
- self.version = data.Versions[0]
- return nil
-}
-
-func (self *Client) apiStatus(resource string, auth string) (int, error) {
- path := fmt.Sprintf("%s/api/%s/%s", self.host, self.version, resource)
- resp, rErr := doRequest(self.client, "GET", path, auth, nil)
- if rErr != nil {
- return 0, errors.New(fmt.Sprintf("Couldn't connect to api: %s", rErr))
- }
-
- defer resp.Body.Close()
- return resp.StatusCode, nil
-}
-
-func (self *Client) confirmBearerAuth(creds *Credentials) error {
- // There are no bugs we have to work around here
- // so just make sure we get a 200 or 403 to
- // a namespace call
-
- status, e := self.apiStatus("namespaces", creds.GetHeader())
- if e == nil && status != 403 && status != 200 {
- newAuthError(fmt.Sprintf("Couldn't verify bearer token with api: %s", status))
- }
-
- return e
-}
-
-func (self *Client) confirmBasicAuth(creds *Credentials) error {
- // Issue a request to the the /api API endpoint without any
- // auth data.
- // If we get 401 in response then we know our creds were good and we can log the user in.
- // If we get a 200 or a 403 then we don't know if are creds were correct and we need to
- // make more calls to figure it out.
- // Any other code is treated as an error.
- var e error
- var status int
- status, e = self.apiStatus("", "")
- success := status == 401
-
- if status == 200 || status == 403 {
- // Either /api is open or the current user, possibly (system:anonymous)
- // doesn't have permissions on it
- // Send a request to the /api/$version/namespaces endpoint with a
- // Authorization header that is guarenteed to be invalid.
- // This should return a 200 if the whole api is open or a 401 if the
- // api is protected.
- status, e = self.apiStatus("namespaces", "Basic Og==")
- if e != nil {
- return e
- }
-
- // Some versions of kubernetes return 403 instead of 401
- // when presented with bad basic auth data. In those cases
- // we need to refuse authentication, as we have no way
- // know if the credentials we have are in fact valid.
- // https://github.com/kubernetes/kubernetes/pull/41775
- if status == 403 {
- e = errors.New("This version of kubernetes is not supported. Turn off anonymous auth or upgrade.")
- } else if status == 200 {
- success = true
- } else if status == 401 {
- if creds.GetHeader() != "" {
- success = true
- } else {
- status = 403
- }
- }
- }
-
- if !success && e == nil {
- e = newAuthError(fmt.Sprintf("Couldn't verify authentication with api: %s", status))
- }
-
- return e
-}
-
-func (self *Client) confirmCreds(creds *Credentials) error {
- // Do this explictly so that we know we have a valid response
- // Kubernetes doesn't provide any way for a caller
- // to find out who it is, so we need to confirm the creds
- // we got some other way.
- err := self.fetchVersion(creds.GetHeader())
- if err != nil {
- return err
- }
-
- // If we are here we got a version for the api from the /api endpoint,
- // using the credentials the user gave us.
- // This happens when either
- // a) /api is protected and the credentials are correct
- // or
- // b) /api is open in which case we have no idea if our creds were correct
- // Confirming them is different for Basic or Bearer auth
- var e error
- if creds.UserName != "" {
- e = self.confirmBasicAuth(creds)
- } else {
- creds.UserName = "Unknown"
- e = self.confirmBearerAuth(creds)
- }
-
- creds.DisplayName = creds.UserName
- return e
-}
-
-func (self *Client) fetchUserData(creds *Credentials) error {
- resp, err := self.DoRequest("GET", self.userAPI, "users/~", creds, nil)
- if err != nil {
- return err
- }
-
- defer resp.Body.Close()
-
- // 404 or 403 are both responses we can
- // get when the oapi/users endpoint doesn't exists
- notFound := resp.StatusCode == 404 || resp.StatusCode == 403
- if notFound && self.requireOpenshift {
- return errors.New("Couldn't connect: Incompatible API")
-
- // This might be kubernetes, it doesn't have a way to
- // get user data, if we have a username try to
- // see if we can connect to it anyways
- } else if notFound {
- return self.confirmCreds(creds)
- } else if resp.StatusCode != 200 {
- return newAuthError(fmt.Sprintf("Couldn't get user data: %s", resp.Status))
- }
-
- self.isOpenshift = true
- data := userInfo{}
- deErr := json.NewDecoder(resp.Body).Decode(&data)
- if deErr != nil {
- return newAuthError(fmt.Sprintf("Couldn't get user json data: %s", deErr))
- }
-
- creds.UserName = data.MetaData.Name
- if creds.UserName != "" {
- creds.DisplayName = data.FullName
- if creds.DisplayName == "" {
- creds.DisplayName = creds.UserName
- }
- } else {
- return newAuthError(fmt.Sprintf("Openshift user data wasn't valid: %v", data))
- }
- return nil
-}
-
-func (self *Client) DoRequest(method string, api string, resource string,
- creds *Credentials, body []byte) (*http.Response, error) {
- if self.host == "" {
- return nil, errors.New("No kubernetes available")
- }
-
- authHeader := ""
- if creds != nil {
- authHeader = creds.GetHeader()
- }
-
- if self.version == "" {
- err := self.fetchVersion(authHeader)
- if err != nil {
- return nil, err
- }
- }
-
- path := fmt.Sprintf("%s/%s/%s/%s", self.host, api, self.version, resource)
- resp, rErr := doRequest(self.client, method, path, authHeader, body)
- if rErr != nil {
- return nil, errors.New(fmt.Sprintf("Couldn't connect: %s", rErr))
- }
- return resp, nil
-}
-
-func (self *Client) Login(authLine string) (map[string]interface{}, error) {
- parts := strings.SplitN(authLine, " ", 2)
- if len(parts) == 0 {
- return nil, newAuthError("Invalid Authorization line")
- }
- authData := ""
- authType := parts[0]
- if len(parts) == 2 {
- authData = parts[1]
- }
-
- creds, err := NewCredentials(authType, authData)
- if err == nil {
- err = self.fetchUserData(creds)
- }
-
- if err != nil {
- if creds != nil && creds.authType == "negotiate" {
- return nil, newAuthError(fmt.Sprintf("Negotiate failed: %s", err))
- }
- return nil, err
- }
-
- // Login successfull, save creds
- self.creds = creds
- user_data := creds.GetApiUserMap()
- cluster := make(map[string]interface{})
- cluster["server"] = self.host
- if self.caData != "" {
- cluster["certificate-authority-data"] = self.caData
- }
-
- cluster["insecure-skip-tls-verify"] = self.insecure
- clusters := namedArrayObject("cluster", "container-cluster", cluster)
-
- context := make(map[string]interface{})
- context["cluster"] = "container-cluster"
- context["user"] = user_data["name"]
- contexts := namedArrayObject("context", "container-context", context)
-
- users := make([]map[string]interface{}, 1)
- users[0] = user_data
-
- login_data := make(map[string]interface{})
- login_data["apiVersion"] = self.version
- login_data["displayName"] = creds.DisplayName
- login_data["current-context"] = "container-context"
- login_data["clusters"] = clusters
- login_data["contexts"] = contexts
- login_data["users"] = users
-
- return login_data, nil
-}
-
-func (self *Client) CleanUp() error {
- if self.creds != nil && self.isOpenshift {
- token := self.creds.GetToken()
- if token != "" {
- path := fmt.Sprintf("oauthaccesstokens/%s", token)
- resp, err := self.DoRequest("DELETE", self.userAPI, path, self.creds, nil)
- if err != nil {
- return err
- }
-
- if resp.StatusCode != 200 {
- log.Println(fmt.Sprintf("Invalid token cleanup response: %d", resp.StatusCode))
- }
-
- defer resp.Body.Close()
- }
- }
- return nil
-}
-
-func NewClient() *Client {
- var caData []byte = nil
- var pool *x509.CertPool
-
- ac := new(Client)
- ac.insecure = false
- ac.host = os.Getenv("KUBERNETES_SERVICE_HOST")
- if ac.host != "" {
- // assume we are always on https
- ac.host = fmt.Sprintf("https://%s", ac.host)
- port := os.Getenv("KUBERNETES_SERVICE_PORT")
- if port != "" {
- ac.host = fmt.Sprintf("%s:%s", ac.host, port)
- }
- }
-
- ac.userAPI = os.Getenv("KUBERNETES_USER_API")
- if ac.userAPI == "" {
- ac.userAPI = "oapi"
- }
-
- ac.requireOpenshift, _ = strconv.ParseBool(os.Getenv("REGISTRY_ONLY"))
-
- ac.insecure, _ = strconv.ParseBool(os.Getenv("KUBERNETES_INSECURE"))
- if !ac.insecure {
- data := os.Getenv("KUBERNETES_CA_DATA")
- if data != "" {
- caData = []byte(data)
- }
-
- if caData == nil {
- var err error
- caData, err = ioutil.ReadFile(CA_PATH)
- if err != nil {
- log.Println(fmt.Sprintf("Couldn't load CA data: %s", err))
- }
- }
-
- if caData != nil {
- pool = x509.NewCertPool()
- pool.AppendCertsFromPEM(caData)
- ac.caData = base64.StdEncoding.EncodeToString(caData)
- }
- }
-
- tr := &http.Transport{
- TLSClientConfig: &tls.Config{RootCAs: pool, InsecureSkipVerify: ac.insecure},
- }
- ac.client = &http.Client{Transport: tr}
-
- return ac
-}
diff --git a/pkg/kubernetes/standalone/src/cockpit-kube-auth/helpers/creds.go b/pkg/kubernetes/standalone/src/cockpit-kube-auth/helpers/creds.go
deleted file mode 100644
index 5a5497580..000000000
--- a/pkg/kubernetes/standalone/src/cockpit-kube-auth/helpers/creds.go
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-package helpers
-
-import (
- "encoding/base64"
- "errors"
- "fmt"
- "io/ioutil"
- "strings"
-)
-
-type Credentials struct {
- UserName string
- DisplayName string
-
- password string
- bearerToken string
-
- authHeader string
- authType string
-}
-
-func (self *Credentials) GetHeader() string {
- return self.authHeader
-}
-
-func (self *Credentials) GetToken() string {
- return self.bearerToken
-}
-
-func (self *Credentials) GetApiUserMap() map[string]interface{} {
- m := make(map[string]interface{})
- name := self.UserName
- if name == "" {
- name = "cockpit-container-user"
- }
-
- user := make(map[string]string)
- if self.password != "" {
- user["password"] = self.password
- user["username"] = self.UserName
- } else {
- user["token"] = self.bearerToken
- }
-
- m["name"] = self.UserName
- m["user"] = user
-
- return m
-}
-
-func NewCredentials(authType string, authData string) (*Credentials, error) {
- cred := new(Credentials)
- cred.authType = strings.ToLower(authType)
- if cred.authType == "basic" {
- raw, err := base64.StdEncoding.DecodeString(authData)
- if err != nil {
- return nil, errors.New(fmt.Sprintf("Couldn't decode basic header: %s", err))
- }
- parts := strings.SplitN(string(raw), ":", 2)
- cred.UserName = parts[0]
- if len(parts) > 1 {
- cred.password = parts[1]
- }
- cred.authHeader = fmt.Sprintf("Basic %s", authData)
- } else if cred.authType == "bearer" {
- cred.bearerToken = authData
- cred.authHeader = fmt.Sprintf("Bearer %s", cred.bearerToken)
-
- } else if cred.authType == "negotiate" {
- cred.UserName = "Unauthenticated"
- } else {
- return nil, errors.New(fmt.Sprintf("Unsuported authentication type %s", authType))
- }
- return cred, nil
-}
-
-func NewCredentialsForSystem() (*Credentials, error) {
- token, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/token")
- if err != nil {
- return nil, err
- }
- return NewCredentials("bearer", string(token))
-}
diff --git a/pkg/kubernetes/standalone/src/cockpit-kube-auth/main.go b/pkg/kubernetes/standalone/src/cockpit-kube-auth/main.go
deleted file mode 100644
index a2a214eec..000000000
--- a/pkg/kubernetes/standalone/src/cockpit-kube-auth/main.go
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-package main
-
-import (
- "cockpit-kube-auth/helpers"
- "encoding/json"
- "errors"
- "fmt"
- "log"
- "os"
- "strconv"
- "syscall"
- "time"
-)
-
-type ChallengeResponse struct {
- Cookie string `json:"cookie"`
- Response string `json:"response"`
- Command string `json:"command"`
-}
-
-func readSize(fd int) (int, error) {
- single := make([]byte, 1)
- sep := byte('\n')
- var size int64 = 0
- seen := 0
-
- for true {
- _, err := syscall.Read(fd, single)
- if err != nil {
- return -1, err
- }
-
- if single[0] == sep {
- break
- }
-
- i, e := strconv.ParseInt(string(single), 10, 64)
- if e != nil {
- return -1, errors.New("Invalid frame: invalid size")
- }
-
- size = size * 10
- size = size + i
- seen++
-
- if seen > 7 {
- return -1, errors.New("Invalid frame: size too long")
- }
- }
-
- return int(size), nil
-}
-
-func readFrame(fd int) ([]byte, error) {
- size, sizeErr := readSize(fd)
- if sizeErr != nil {
- return nil, sizeErr
- }
- data := make([]byte, 0)
-
- for size > 0 {
- buffer := make([]byte, size)
- i, err := syscall.Read(fd, buffer)
-
- if err != nil {
- return nil, err
- }
-
- if i == 0 {
- break
- }
-
- size = size - i
- data = append(data, buffer[:i]...)
- }
-
- if size > 0 {
- return nil, errors.New(fmt.Sprintf("Invalid frame: Missing %d bytes", size))
- }
-
- return data, nil
-}
-
-func getCockpitControlMsg(iface interface{}) error {
- buf, err := readFrame(syscall.Stdin)
- if err == nil {
- err = json.Unmarshal(buf, iface)
- }
- return err
-}
-
-func sendCockpitControlMsg(data interface{}) error {
- response, respErr := json.Marshal(data)
- if respErr != nil {
- return respErr
- }
-
- _, err := syscall.Write(syscall.Stdout, []byte(fmt.Sprintf("%d\n\n", len(response)+1)))
- if err == nil {
- _, err = syscall.Write(syscall.Stdout, response)
- }
-
- return err
-}
-
-func sendAuthorization(login_data map[string]interface{}) error {
- data := make(map[string]interface{})
- data["command"] = "authorize"
- data["challenge"] = "x-login-data"
- data["cookie"] = "kube-auth-unused"
- data["login-data"] = login_data
- return sendCockpitControlMsg(data)
-}
-
-func sendInitProblem(err error) error {
- log.Println(err)
- errorType := "internal-error"
- if _, ok := err.(*helpers.AuthError); ok {
- errorType = "authentication-failed"
- }
-
- data := make(map[string]interface{})
- data["command"] = "init"
- data["problem"] = errorType
- data["message"] = fmt.Sprintf("%s", err)
- return sendCockpitControlMsg(data)
-}
-
-func challengeForAuthData() ([]byte, error) {
- t := time.Now()
- data := make(map[string]interface{})
- data["command"] = "authorize"
- data["challenge"] = "*"
- data["cookie"] = fmt.Sprintf("cookie%d%d", os.Getpid(), t.Unix())
-
- err := sendCockpitControlMsg(data)
- if err != nil {
- return nil, nil
- }
-
- r := ChallengeResponse{}
- fetchErr := getCockpitControlMsg(&r)
- if fetchErr != nil {
- return nil, fetchErr
- }
-
- if r.Command != "authorize" {
- return nil, errors.New(fmt.Sprintf("Got invalid command %s", r.Command))
- }
-
- return []byte(r.Response), nil
-}
-
-func runStub() int {
- var wstatus syscall.WaitStatus
- sysProcAttr := &syscall.SysProcAttr{
- Pdeathsig: syscall.SIGTERM,
- }
-
- procAttr := &syscall.ProcAttr{
- Env: os.Environ(),
- Files: []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd()},
- Sys: sysProcAttr,
- }
-
- pid, fork_err := syscall.ForkExec("/usr/libexec/cockpit-stub", nil, procAttr)
- if fork_err != nil {
- log.Fatal("Error forking process:", fork_err)
- }
-
- _, wait_err := syscall.Wait4(pid, &wstatus, 0, nil)
- for wait_err == syscall.EINTR {
- _, wait_err = syscall.Wait4(pid, &wstatus, 0, nil)
- }
- if wait_err != nil {
- log.Fatal("Error waiting on bridge pid:", wait_err)
- }
-
- return wstatus.ExitStatus()
-}
-
-func main() {
- authData, err := challengeForAuthData()
- if err != nil {
- log.Fatal("Error reading authentication data ", err)
- }
-
- client := helpers.NewClient()
- response, loginErr := client.Login(string(authData))
- if loginErr != nil {
- err = sendInitProblem(loginErr)
- } else {
- err = sendAuthorization(response)
- }
-
- if err != nil {
- log.Fatal("Error sending auth result", err)
- }
-
- if err == nil && loginErr == nil {
- if os.Getenv("XDG_RUNTIME_DIR") == "" {
- os.Setenv("XDG_RUNTIME_DIR", "/tmp")
- }
-
- status := runStub()
- err = client.CleanUp()
- if err != nil {
- log.Fatal("Error deleting token", err)
- }
-
- os.Exit(status)
- }
-}
diff --git a/pkg/kubernetes/standalone/src/cockpit-kube-launch/main.go b/pkg/kubernetes/standalone/src/cockpit-kube-launch/main.go
deleted file mode 100644
index 067886ad7..000000000
--- a/pkg/kubernetes/standalone/src/cockpit-kube-launch/main.go
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-package main
-
-import (
- "cockpit-kube-auth/helpers"
- "flag"
- "fmt"
- "log"
- "os"
- "os/exec"
- "path"
- "strconv"
- "syscall"
- "text/template"
-)
-
-var OAUTH_CLIENT_ID = "cockpit-kube-client"
-var CONFIG_FILE = "/etc/cockpit/cockpit.conf"
-var CONFIG_TEMPLATE = "cockpit.conf.tmpl"
-
-var confDir = flag.String("config-dir", "/container", "Directory with cockpit-kube-launch config files")
-
-func writeConfigFile(confData map[string]interface{}) {
- tmpl, tErr := template.New("cockpit.conf.tmpl").ParseFiles(path.Join(*confDir, CONFIG_TEMPLATE))
- if tErr != nil {
- log.Fatalf("Invalid cockpit.conf template: %s", tErr)
- }
-
- f, fErr := os.Create(CONFIG_FILE)
- if fErr != nil {
- log.Fatalf("Could't open file config file: %s", fErr)
- }
-
- wErr := tmpl.Execute(f, confData)
- if wErr != nil {
- log.Fatalf("Could't write config file: %s", wErr)
- }
-}
-
-func linkFiles(src string, target string) {
- // Not using symlink because os.Symlink doesn't let you force.
- out, err := exec.Command("ln", "-sf", src, target).CombinedOutput()
- if err != nil {
- log.Fatalf("Could't link %s to %s: %v: %s", src, target, err, out)
- }
-}
-
-func setupCertificates() {
- // Ensure path exits
- dErr := os.MkdirAll("/etc/cockpit/ws-certs.d", os.ModeDir|0775)
- if dErr != nil {
- log.Fatalf("Couldn't create certificate directory %s", dErr)
- }
-
- // Finding these certificate files or setting ownership on
- // the certificate may fail so execute combine and ensure
- // and the check results without
- exec.Command("/usr/sbin/remotectl", "certificate",
- "/var/run/secrets/ws-certs.d/tls.crt",
- "/var/run/secrets/ws-certs.d/tls.key").CombinedOutput()
- exec.Command("/usr/sbin/remotectl", "certificate", "--ensure").CombinedOutput()
- out, rErr := exec.Command("/usr/sbin/remotectl", "certificate").CombinedOutput()
- if rErr != nil {
- log.Fatalf("Failed to generate certificates %s %s", rErr, out)
- }
-}
-
-func haveOpenShiftEndpoint() (bool, error) {
- var isOpenShift bool = false
-
- creds, err := helpers.NewCredentialsForSystem()
- if err != nil {
- return isOpenShift, err
- }
-
- client := helpers.NewClient()
- resp, e := client.DoRequest("GET", "oapi", "", creds, nil)
- if e != nil {
- return isOpenShift, e
- }
-
- defer resp.Body.Close()
- if resp.StatusCode == 200 {
- isOpenShift = true
- }
-
- return isOpenShift, nil
-}
-
-func main() {
- flag.Parse()
-
- var isOpenShift bool = false
- args := []string{
- "/usr/libexec/cockpit-ws",
- }
-
- insecure, _ := strconv.ParseBool(os.Getenv("COCKPIT_KUBE_INSECURE"))
- if insecure {
- args = append(args, "--no-tls")
- }
-
- setupCertificates()
-
- name := "kubernetes"
- isRegistry, _ := strconv.ParseBool(os.Getenv("REGISTRY_ONLY"))
-
- oauth_url := os.Getenv("OPENSHIFT_OAUTH_PROVIDER_URL")
- if oauth_url != "" {
- isOpenShift = true
- client_id := os.Getenv("OPENSHIFT_OAUTH_CLIENT_ID")
- if client_id == "" {
- client_id = OAUTH_CLIENT_ID
- }
- oauth_url = fmt.Sprintf("%s/oauth/authorize?client_id=%s&response_type=token",
- oauth_url, client_id)
- } else {
- oauth_url = os.Getenv("OAUTH_PROVIDER_URL")
- var osErr error = nil
- isOpenShift, osErr = haveOpenShiftEndpoint()
- if osErr != nil {
- log.Printf("Error checking for openshift endpoint %s", osErr)
- }
- }
-
- if isRegistry {
- name = "registry"
- } else if isOpenShift {
- name = "openshift"
- }
-
- confData := make(map[string]interface{})
- confData["login_command"] = "/usr/libexec/cockpit-kube-auth"
- confData["oauth_url"] = oauth_url
- confData["is_openshift"] = isOpenShift
- confData["is_registry"] = isRegistry
- confData["origins"] = os.Getenv("COCKPIT_KUBE_URL");
- writeConfigFile(confData)
-
- override := path.Join(*confDir, fmt.Sprintf("%s-override.json", name))
- brand := path.Join(*confDir, fmt.Sprintf("%s-brand", name))
- linkFiles(override, "/usr/share/cockpit/shell/override.json")
- linkFiles(brand, "/container/os-release")
-
- if isRegistry {
- registry_override := path.Join(*confDir, "registry-dashboard-override.json")
- linkFiles(registry_override, "/usr/share/cockpit/kubernetes/override.json")
- linkFiles("/usr/share/cockpit/kubernetes/registry.html.gz",
- "/usr/share/cockpit/kubernetes/index.html.gz")
- } else {
- linkFiles("/usr/share/cockpit/kubernetes/original-index.gz",
- "/usr/share/cockpit/kubernetes/index.html.gz")
- }
-
- syscall.Exec(args[0], args, os.Environ())
-}
diff --git a/pkg/kubernetes/styles/app.less b/pkg/kubernetes/styles/app.less
deleted file mode 100644
index 65e67abdf..000000000
--- a/pkg/kubernetes/styles/app.less
+++ /dev/null
@@ -1,216 +0,0 @@
-#graphs {
- display: block;
-}
-
-#graphs svg {
- font-size: 10px;
-}
-
-#graphs ul {
- padding-top: 15px;
- margin-right: 10px;
-}
-
-.axis path, .axis line {
- fill: none;
- stroke: #000;
- shape-rendering: crispEdges;
-}
-
-.axis .domain,
-.axis .tick line {
- stroke: lightgrey;
- opacity: 0.5;
-}
-
-.tick text {
- fill: #545454;
- font-size: 12px;
-}
-
-path.line {
- stroke: steelblue;
- fill: none;
- stroke-width: 2;
-}
-
-path.line.highlight {
- stroke-width: 4;
-}
-
-/* Page global stuff */
-
-.container-fluid {
- margin-top: 0px;
- padding-left: 0px;
-}
-
-.container-more {
- margin-top: 10px;
-}
-
-/* Dashboard */
-
-#content {
- margin-left: 110px;
- margin-right: 0px;
- min-height: 100%;
-}
-
-#content > .row {
- margin-right: 0px;
-}
-
-#content > *:last-child {
- padding-bottom: 20px;
-}
-
-/* When panel is editable, then buttons are visible */
-.dashboard-list td button {
- display: none;
-}
-
-.dashboard-list.editable td button {
- display: block;
-}
-
-.dashboard-list.editable td.status > span {
- display: none;
-}
-
-.dashboard-list.editable tr:hover td {
- background-color: #FFF;
- cursor: auto;
-}
-
-.dashboard-list td.status {
- padding: 4px 10px 4px !important;
- text-align: right;
- white-space: nowrap;
- vertical-align: middle;
- width: 1%;
- min-width: 50px;
-}
-
-.dashboard-list span.pficon,
-.dashboard-list span.fa {
- font-size: 18px;
- color: black;
- display: inline-block;
-}
-
-.dashboard-list span.spinner {
- display: inline-block;
-}
-
-.dashboard-list span.fa-failed {
- color: #af151a;
-}
-
-
-/* App deploy dialog */
-
-#deploy-app-deploying > span {
- margin-left: 7px;
-}
-
-#deploy-app-manifest-file {
- opacity: 0.0001;
- height: 1px;
-}
-
-#deploy-app-manifest-file-button {
- width: 100%;
- padding-right: 25px;
-}
-
-.deploy-app-type-text {
- font-style: normal;
- text-align: left;
-}
-
-.manifest_file {
- font-style: normal;
- text-align: left;
- font-size: 11px;
-}
-
-.manifest_file_default {
- text-align: left;
- font-style: italic;
- font-size: 11px;
-}
-
-.combobox_option {
- width: 100%;
-}
-
-.deploy-dialog-aids {
- margin-bottom: 0px;
-}
-
-/* Replicas dialog */
-
-input.adjust-replica {
- width: 70px;
-}
-
-#adjust-dialog .modal-dialog {
- width: 400px;
-}
-
-#deploy-app-type-field > .bootstrap-select {
- margin-bottom: 3px;
-}
-
-.app-name {
- color: #333333;
- margin-top: 10px;
- text-align: left;
-}
-
-/* Used to hide angular elements until they are ready */
-[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
- display: none !important;
-}
-
-input.adjust-replica {
- width: 200px;
-}
-
-.console-ct pre {
- background-color: #fcfcfc;
- border: 1px solid #cccccc;
-}
-
-pre.dialog {
- height: 200px;
- width: 500px;
- border: 1px solid #cccccc;
-}
-
-.action-menu {
- display: block;
- float: right;
-}
-
-/* Input combo replacement */
-
-.input-combo .input-group-btn {
- position: static;
-}
-
-.input-combo .dropdown-menu {
- left: 0;
- right: 0;
-}
-
-/* overide since registry-image-widget sets
- the last column to be aligned right
- but we don't want that when we are
- using colspan
- */
-table.listing-ct > thead td[colspan]:last-child,
-table.listing-ct > thead th[colspan]:last-child {
- text-align: left;
-}
diff --git a/pkg/kubernetes/styles/containers.less b/pkg/kubernetes/styles/containers.less
deleted file mode 100644
index 8ea87c742..000000000
--- a/pkg/kubernetes/styles/containers.less
+++ /dev/null
@@ -1,19 +0,0 @@
-
-.containers-listing {
- width: 100%;
-}
-
-.containers-listing i.fa-cube,
-.content-filter i.fa-cube {
- position: relative;
- font-size: 22px;
-}
-
-.containers-listing .console-ct {
- min-height: 310px;
-}
-
-kubernetes-container-terminal .terminal-actions {
- position: relative;
- z-index: auto;
-}
diff --git a/pkg/kubernetes/styles/dashboard.less b/pkg/kubernetes/styles/dashboard.less
deleted file mode 100644
index dbfd95f68..000000000
--- a/pkg/kubernetes/styles/dashboard.less
+++ /dev/null
@@ -1,108 +0,0 @@
-.container-cards-pf {
- display: flex;
- margin-top: 10px;
-}
-
-.card-pf {
- flex-grow: 1;
- margin: 10px;
- display: flex;
- flex-direction: column;
- flex-basis: 25%;
-}
-
-.card-pf-aggregate-status .card-pf-body {
- margin-bottom: 0px;
-}
-
-.card-pf-wide {
- flex-basis: ~"calc(75% + 20px)";
-}
-
-.card-pf-double {
- flex-basis: ~"calc(66% - 76px)";
-}
-
-.dashboard-cards {
- width: 100%;
- max-width: 1024px;
- padding-right: 7px;
-}
-
-.card-pf-aggregate-status-notification .spinner {
- display: inline-block;
- margin-right: 7px;
-}
-
-.card-pf-aggregate-status-text {
- font-size: 13px;
- vertical-align: 3px;
-}
-
-.card-pf-heading {
- margin-bottom: 0px;
-
- button {
- margin: 15px 0px;
- }
-
- i {
- font-size: 24px;
- line-height: 16px;
- vertical-align: top;
- padding-right: 5px;
- }
-}
-
-.card-pf-footer {
- min-height: 5em;
-}
-
-.card-pf-body {
- margin-top: 10px;
- margin-bottom: auto;
-}
-
-.card-pf-body.blank-slate-pf {
- background: transparent;
- padding-top: 20px;
-}
-
-.card-pf-body table.listing-ct {
- margin-top: 0px;
- width: 100%;
-}
-
-.card-pf-body table.listing-ct thead th {
- border-top: none;
-}
-
-.card-pf-body table.listing-ct tbody:last-child {
- border-bottom: none;
-}
-
-.card-pf-body table.listing-ct tbody:last-child tr:last-child {
- border-bottom: none;
-}
-
-.pvc-notice {
- border-top: 1px solid #d1d1d1;
- padding-top: 5px;
-}
-
-.pvc-notice .pficon {
- font-size: 18px;
- margin-right: 5px;
- color: #72767b;
-}
-
-code {
- display: block;
- white-space: pre;
- font-size: 13px;
- margin-bottom: 1em;
-}
-
-.form-table-ct label span[translate] {
- vertical-align: top;
-}
diff --git a/pkg/kubernetes/styles/details.less b/pkg/kubernetes/styles/details.less
deleted file mode 100644
index 6b7fe1af9..000000000
--- a/pkg/kubernetes/styles/details.less
+++ /dev/null
@@ -1,75 +0,0 @@
-.details-listing {
- min-width: 70% !important;
-}
-
-.details-listing i.pficon-service {
- font-size: 30px;
- line-height: 20px;
- position: relative;
- padding-right: 5px;
- left: -5px;
-}
-
-.details-listing i.pficon-route {
- position: relative;
- font-size: 25px;
- line-height: 20px;
- left: -2px;
- padding-right: 8px;
-}
-
-.details-listing i.fa-server {
- position: relative;
- top: 3px;
-}
-
-.content-filter i.pficon-service {
- margin-right: 5px;
-}
-
-.details-listing i.pficon-replicator {
- position: relative;
- font-size: 28px;
- top: -6px;
-}
-
-.content-filter i.pficon-replicator {
- margin-right: 5px;
-}
-
-.content-filter i.pficon-container-node {
- top: 3px;
- margin-right: 5px;
-}
-
-.details-listing i.fa-cubes {
-
-}
-
-.details-listing i.fa-gear {
- position: relative;
- font-size: 25px;
- top: -3px;
-}
-
-.details-listing dl dd dl.inline-dl {
- padding-left: 15px;
-}
-
-.details-listing dl dd dl.inline-dl dt {
- text-align: left;
-}
-
-.listing-ct-inline .console-ct > pre {
- text-align: left;
- margin: 0;
-}
-
-.type-filter .btn,
-.type-filter .dropdown-menu {
- font-size: 13px;
-}
-
-.type-filter .btn-group.open .dropdown-toggle {
- box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.125) inset;
-}
diff --git a/pkg/kubernetes/styles/dropdown.less b/pkg/kubernetes/styles/dropdown.less
deleted file mode 100644
index b99416ad1..000000000
--- a/pkg/kubernetes/styles/dropdown.less
+++ /dev/null
@@ -1,12 +0,0 @@
-.dropdown-menu {
- li a:before {
- font-family: FontAwesome;
- content: "\f00c";
- margin-right: 5px;
- visibility: hidden;
- }
-
- li.checked a:before {
- visibility: visible;
- }
-}
diff --git a/pkg/kubernetes/styles/filter.less b/pkg/kubernetes/styles/filter.less
deleted file mode 100644
index 23d8a8568..000000000
--- a/pkg/kubernetes/styles/filter.less
+++ /dev/null
@@ -1,89 +0,0 @@
-@filter-height: 50px;
-
-.content-filter {
- background-color: @sidebar-pf-bg;
- padding: 10px 16px 10px 20px;
- border-bottom: 1px @sidebar-pf-border-color solid;
- position: fixed;
- top: 0px;
- right: 0px;
- z-index: 1;
- height: @filter-height;
-
- h3 {
- display: inline;
- font-size: 18px;
- line-height: 28px;
- }
-
- h3 i {
- font-size: 24px;
- position: relative;
- padding-right: 3px;
- }
-
- i.pficon-image {
- top: 3px;
- }
-
- i.fa {
- margin-top: 2px;
- font-size: 18px;
- line-height: 28px;
- }
-
- i.fa-folder {
- font-size: 22px;
- }
-
- a {
- padding-left: 30px;
- }
-}
-
-@media (min-width: 700px) {
- .content-filter {
- a.hidden-xs {
- display: inline !important;
- }
- }
-}
-
-.content-filter + div {
- padding-top: @filter-height;
-}
-
-.namespace-filter .btn,
-.namespace-filter .dropdown-menu {
- font-size: 13px;
-}
-
-.namespace-filter .btn-group.open .dropdown-toggle {
- box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.125) inset;
-}
-
-.namespace-filter .namespace-meta {
- color: @metadata-color;
-}
-
-.filter-menu {
- display: block;
-
- .caret {
- height: 10px;
- }
-}
-
-.filter-menu > .btn + .dropdown-toggle {
- padding: 3px 1px;
- min-width: 0;
- border-left: none;
- height: 26px;
-}
-
-.filter-menu > .btn:first-child {
- border-right: none;
- height: 26px;
- font-size: 15px;
-}
-
diff --git a/pkg/kubernetes/styles/images.less b/pkg/kubernetes/styles/images.less
deleted file mode 100644
index 176f7b6e1..000000000
--- a/pkg/kubernetes/styles/images.less
+++ /dev/null
@@ -1,66 +0,0 @@
-@import (less) "../../../node_modules/registry-image-widgets/dist/image-widgets.css";
-
-@tag-border: @link-color;
-
-table.images-listing {
- max-width: 2000px;
- min-width: 85%;
-
- tbody:hover {
- background-color: #edf8ff;
- }
-
- thead {
- th {
- border-top: none;
- }
- }
-
- tr.listing-ct-item {
-
- td.tag-label {
- vertical-align: top;
- background: linear-gradient(90deg, transparent 10px, @tag-border 10px, @tag-border 12px, transparent 12px);
- }
-
- td.listing-ct-toggle:hover + td.tag-label {
- background-color: #ededed
- }
-
- border-top: none;
- border-bottom: none;
- }
-
- tbody.first {
- tr.tag-item td {
- padding-top: 20px;
- }
- }
-
- tbody.last {
- tr.listing-ct-item.tag-item td.tag-label {
- background-size: 100% 20px;
- background-repeat: no-repeat;
- }
- }
-
- tr.imagestream-item {
- border-top: 1px solid @gray-lighter;
-
- th, td {
- border-bottom: 2px solid @tag-border;
- font-size: 14px;
- padding-bottom: 5px;
- }
- }
-
- tr.listing-ct-item tt {
- color: @metadata-color;
- }
-}
-
-registry-imagestream-listing {
- table.listing-ct {
- margin-top: -15px;
- }
-}
diff --git a/pkg/kubernetes/styles/main.less b/pkg/kubernetes/styles/main.less
deleted file mode 100644
index 8c5685eba..000000000
--- a/pkg/kubernetes/styles/main.less
+++ /dev/null
@@ -1,28 +0,0 @@
-@import "variables.less";
-@import (less) "../../../node_modules/angular/angular-csp.css";
-
-@import (less) "../../lib/page.css";
-@import "../../lib/listing.less";
-@import (less) "../../lib/console.css";
-@import (less) "../../lib/table.css";
-
-/* Depends on number of items in the sidebar */
-@sidebar-height-lg: 630px;
-
-@import "app.less";
-@import (less) "../../../node_modules/kubernetes-container-terminal/dist/container-terminal.css";
-@import "containers.less";
-@import "details.less";
-@import (less) "../../../node_modules/kubernetes-topology-graph/dist/topology-graph.css";
-@import "topology.less";
-@import "revealable.less";
-@import "dashboard.less";
-
-@import "sidebar.less";
-@import "filter.less";
-@import "dropdown.less";
-@import "tags.less";
-@import "images.less";
-@import "projects.less";
-@import "volumes.less";
-@import "nodes.less";
diff --git a/pkg/kubernetes/styles/nodes.less b/pkg/kubernetes/styles/nodes.less
deleted file mode 100644
index 34dbfbb02..000000000
--- a/pkg/kubernetes/styles/nodes.less
+++ /dev/null
@@ -1,112 +0,0 @@
-.node-status {
- padding-right: 3px;
-}
-
-.node-alert {
- margin-top: 20px;
-}
-
-div.nodes-delete ul {
- padding-top: 10px;
-}
-
-div.nodes-delete ul li {
- padding-bottom: 10px;
-}
-
-.nodes-heatmap-card {
- flex-basis: 66%;
-
- .card-pf-title {
- margin-top: 10px;
- }
-
- .node-heatmap {
- height: 90px;
- }
-
- ul.chart-legend {
- margin-top: 30px;
- }
-
- li.chart-legend-item {
- float: left;
- display: inline;
- }
-
- li.chart-legend-item:first-of-type span.legend-pf-color-box{
- margin-left: 0px;
- }
-
- li.chart-legend-item span.legend-pf-color-box {
- margin-left: 5px;
- }
-
- rect {
- cursor: pointer;
- }
-}
-
-.nodes-os-card {
- flex-basis: 33%;
-
- #os-counts-graph {
- height: 150px;
- }
-
- h2 {
- text-align: center;
- margin-bottom: 0;
- }
-
- @media (min-width: 992px) {
- div.row {
- display: flex;
- align-items: center;
- }
- }
-}
-
-.chart-title {
- text-anchor: middle;
- dominant-baseline: middle;
-}
-
-.chart-focused {
- opacity: 1;
- cursor: pointer;
-}
-
-.chart-unfocused {
- opacity: 0.3;
-}
-
-ul.chart-legend {
- list-style-type: none;
- margin-top: 5px;
- padding: 0;
- overflow: auto;
-}
-
-li.chart-legend-item {
- cursor: pointer;
-}
-
-li.chart-legend-item span.legend-pf-color-box {
- width: 11px;
- height: 11px;
- margin-right: 5px;
- display: inline-block;
-}
-
-li.chart-legend-item span.legend-pf-text {
- font-size: 11px;
- font-weight: 400;
- line-height: 11px;
- margin-right: 5px;
-}
-
-.nodes-container-cards svg {
- min-width: 90px;
- min-height: 90px;
-}
diff --git a/pkg/kubernetes/styles/projects.less b/pkg/kubernetes/styles/projects.less
deleted file mode 100644
index dbc828f3c..000000000
--- a/pkg/kubernetes/styles/projects.less
+++ /dev/null
@@ -1,141 +0,0 @@
-
-@tag-border: @link-color;
-
-table.project-body {
- margin-top: 0px;
-
- thead.th {
- border-top:0px;
- font-size: 12px;
- }
-
- tr {
- display: table-row;
- vertical-align: inherit;
- border-color: inherit;
- }
-
- tr.listing-ct-item {
- border-top: 1px solid color("#eee");
- border-bottom: 1px solid color("#eee");
- cursor: pointer;
- }
-}
-
-.close-icon {
- color: #000000;
-}
-.user-membership-body {
- overflow-y: auto;
- overflow-x: hidden;
- max-height: 200px;
- border-top: 1px solid #eee;
- border-bottom: 1px solid #eee;
- padding-top: 10px;
- padding-bottom: 10px;
-
- h4 {
- color: #888;
- margin-top: 0px;
- margin-bottom: 5px;
- font-size: 14px;
- }
-
- span {
- display: block;
- margin-left: 20px;
- }
-}
-
-.user-body {
- border: 0px;
-
- table.listing-ct thead th {
- border-bottom: 0px;
- border-bottom: 1px solid color("#eee");
- }
-}
-
-table.listing-ct > thead td {
- padding-top: 0px;
-}
-
-.listing-ct-head .pficon-project {
- margin-bottom: 10px;
-}
-
-span.project-description {
- font-size: 13px;
- font-weight: normal;
-}
-
-p.project-description {
- margin-top: 1em;
-}
-
-a.input-icon {
- position: absolute;
- right: 18px;
-}
-
-.project-panel {
- padding-right: 25px;
- padding-top: 5px;
-}
-
-.project-panel-actions {
- padding-right: 5px;
- padding-top: 5px;
-}
-
-table.projects-listing {
- max-width: 2000px;
- min-width: 85%;
-
- thead {
- th {
- border-top: 0px;
- }
- }
-
- tr {
- display: table-row;
- vertical-align: inherit;
- border-color: inherit;
- }
-
- .details-listing {
- min-width: 70% !important;
- }
-
- tr.listing-ct-item {
- border-top: 1px solid color("#eee");
- border-bottom: 1px solid color("#eee");
- cursor: pointer;
- }
-
- tr.inner-project-listing {
- display: table-row;
- }
-
- tbody.first {
- tr.tag-item td {
- padding-top: 20px;
- }
- }
-
- tbody.last {
- tr.listing-ct-item.tag-item td:first-child {
- background-size: 100% 20px;
- background-repeat: no-repeat;
- }
- }
-
- tr.tag-item td {
- padding-bottom: 0px;
- }
-
- tr.listing-ct-item tt {
- color: @metadata-color;
- }
-}
diff --git a/pkg/kubernetes/styles/registry.less b/pkg/kubernetes/styles/registry.less
deleted file mode 100644
index 006eb28af..000000000
--- a/pkg/kubernetes/styles/registry.less
+++ /dev/null
@@ -1,248 +0,0 @@
-@import "variables.less";
-@import (less) "../../../node_modules/angular/angular-csp.css";
-
-@import (less) "../../lib/page.css";
-@import "../../lib/listing.less";
-@import (less) "../../lib/console.css";
-@import (less) "../../lib/table.css";
-
-@icon-sidebar-width: 100px;
-
-@import "filter.less";
-@import "dropdown.less";
-@import "dashboard.less";
-
-@import "images.less";
-@import "projects.less";
-@import "tags.less";
-
-#content {
- margin-right: 0px;
- min-height: 100%;
- padding-bottom: 20px;
-}
-
-.listing-ct-body dl {
- margin-bottom: 13px;
-}
-
-/* Registry dashboard */
-
-.card-pf-utilization .card-pf-title {
- line-height: 1.1;
-}
-
-.dashboard-storage {
- img {
- display: block;
- margin: 20px auto 0px auto;
- }
-}
-
-.dashboard-images {
- .card-pf-heading {
- position: relative;
-
- .card-pf-title {
- max-width: 80%;
- }
- }
-
- .card-pf-body {
- min-height: 220px;
- padding-bottom: 0px;
-
- div {
- padding: 7px 10px 10px 10px;
- cursor: pointer;
- }
-
- div:hover {
- background-color: @table-bg-hover;
- }
-
- ul {
- background: linear-gradient(90deg, transparent 20px, @tag-border 20px, @tag-border 22px, transparent 22px);
- background-size: 100% 20px;
- background-repeat: no-repeat;
- padding: 3px 0px 0px 20px;
- margin-bottom: 0px;
- line-height: 30px;
-
- li {
- background: linear-gradient(180deg, transparent 8px, @tag-border 8px, @tag-border 10px, transparent 10px);
- background-repeat: no-repeat;
- padding-left: 7px;
- display: inline;
- list-style: none;
- }
-
- li:first-child {
- padding-left: 15px;
- }
-
- li.image-tag-truncated {
- padding-left: 15px;
- opacity: 0.5;
- }
- }
- }
-
- .namespace-filter {
- margin-top: -3px;
- }
-
- .namespace-filter button {
- margin-bottom: 0px;
- }
-
- .all-images {
- display: block;
- float: right;
- margin-bottom: 10px;
- }
-
- .registry-imagestream-lock {
- display: block;
- float: right;
- margin: 9px;
- }
-
- .table > tbody > tr > td {
- border-top: none;
- font-weight: bold;
- padding: 0px;
- }
-
- .table a {
- display: block;
- color: inherit;
- padding: 8px 15px;
- }
-
- dt {
- font-size: 13px;
- }
-
- dt a {
- text-decoration: none;
- color: inherit;
- }
-
- dd {
- float: right;
- margin-left: 20px;
- }
-
-}
-
-.dashboard-commands {
- p {
- font-size: 13px;
- font-weight: bold;
- }
-}
-
-.blank-slate-pf {
- border: none;
-}
-
-#content {
- margin-left: unit(@icon-sidebar-width, px);
-}
-
-.content-filter {
- left: unit(@icon-sidebar-width - 10, px);
-}
-
-.content-filter + div {
- padding-left: 10px;
- padding-right: 17px;
-}
-
-/* A different sidebar */
-.icon-sidebar {
- width: unit(@icon-sidebar-width, px);
-
- ul {
- margin: 0;
- padding: 0;
- list-style: none;
- width: unit(@icon-sidebar-width - 10, px);
- height: 100%;
- position: fixed;
- background-color: @nav-pf-vertical-secondary-bg-color;
- top: 0px;
- z-index: 1;
-
- li {
- border-bottom: 1px solid @nav-pf-vertical-border-color;
- display: block;
- font-size: 13px;
-
- a {
- border-bottom: 0;
- color: @nav-pf-vertical-secondary-color;
- background-color: @nav-pf-vertical-secondary-bg-color;
- padding: 15px 11px 15px 9px;
- text-align: center;
- display: block;
- text-decoration: none;
- position: relative;
-
- i {
- display: inline;
- font-size: 20px;
- line-height: 20px;
- color: @nav-pf-vertical-icon-color;
- }
-
- i.pficon-image {
- font-size: 24px;
- line-height: 20px;
- }
- }
-
- a:hover {
- color: @nav-pf-vertical-secondary-active-color;
- background-color: @nav-pf-vertical-secondary-active-bg-color;
-
- i {
- color: @nav-pf-vertical-active-icon-color;
- }
- }
- }
-
- li.active {
- a {
- color: @nav-pf-vertical-secondary-active-color;
- background-color: @nav-pf-vertical-secondary-active-bg-color;
-
- i {
- color: @link-color;
- }
- }
-
- a:after {
- content: '';
- width: 4px;
- height: 100%;
- left: 0;
- top: 0;
- display: block;
- position: absolute;
- background-color: @link-color;
- }
- }
- }
-}
-
-/* overide since registry-image-widget sets
- the last column to be aligned right
- but we don't want that when we are
- using colspan
- */
-table.listing-ct > thead td[colspan]:last-child,
-table.listing-ct > thead th[colspan]:last-child {
- text-align: left;
-}
diff --git a/pkg/kubernetes/styles/revealable.less b/pkg/kubernetes/styles/revealable.less
deleted file mode 100644
index 8fd00f351..000000000
--- a/pkg/kubernetes/styles/revealable.less
+++ /dev/null
@@ -1,46 +0,0 @@
-.revealable {
- white-space: nowrap !important;
- text-overflow: ellipsis;
- overflow: hidden !important;
-}
-
-.revealable.clickable {
- cursor: pointer;
-}
-
-.revealed {
- white-space: normal !important;
- overflow: visible !important;
- cursor: pointer;
- overflow-wrap: break-word;
-}
-
-.masked {
- color: transparent;
- position: relative;
- text-ellipsis: none !important;
- cursor: pointer;
- max-width: 1;
- display: inline-block;
-}
-
-.masked:after {
- content: "●●●●";
- position: absolute;
- left: 0px;
- font-weight: bold;
- letter-spacing: 2px;
- padding-left: 2px;
- color: black;
- cursor: pointer;
- line-height: 1.5;
- opacity: 0.5;
-}
-
-.revealed .masked:after {
- display: none;
-}
-
-.revealed .masked {
- color: black;
-}
diff --git a/pkg/kubernetes/styles/sidebar.less b/pkg/kubernetes/styles/sidebar.less
deleted file mode 100644
index ed11e0dcc..000000000
--- a/pkg/kubernetes/styles/sidebar.less
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Full large size sidebar.
- */
-
-
-.nav-sidebar {
- background: #393f44;
- width: unit(@sidebar-width-xl, px);
- height: 100%;
- position: fixed;
- top: 0px;
- z-index: 1;
- overflow-x: hidden;
- overflow-y: auto;
-
- border-right: 1px solid #292e34;
- border-bottom: none;
- border-top: none;
- border-left: none;
- bottom: 0;
-
- a {
- width: unit(@sidebar-width-xl, px) !important;
- }
- .list-group-item-value {
- max-width: unit(@sidebar-width-xl - 60, px) !important;
- padding-right: 10px !important;
- }
-}
-
-.nav-item-pf-header {
- color: #fff;
- font-size: 16px;
- margin: 18px 20px 10px 20px;
-}
-
-.nav-sidebar .list-group {
- border: none;
-}
-
-.nav-sidebar .list-group-item {
- background: inherit;
- border: none;
-}
-
-.nav-sidebar .list-group-item.active {
- background-color: #4d5258;
-}
-.nav-sidebar > .list-group > .list-group-item.active > a {
- background-color: inherit;
-}
-
-.nav-sidebar .list-group-item a {
- display: block;
- color: #d1d1d1;
-}
-
-#content {
- margin-left: unit(@sidebar-width-xl + 20, px);
-}
-
-.content-filter {
- left: unit(@sidebar-width-xl, px);
-}
-
-/*
- * Very small. Only icons
- */
-@media (max-width: @screen-sm-min) {
- .nav-sidebar {
- .nav-item-pf-header {
- display: none;
- }
-
- width: unit(@sidebar-width-sm, px);
- .list-group-item-value {
- display: none !important;
- }
- a {
- padding: 8px !important;
- height: 40px !important;
- width: unit(@sidebar-width-sm, px) !important;
- }
- }
-
- #content {
- margin-left: unit(@sidebar-width-sm + 20, px);
- }
-
- .content-filter {
- left: unit(@sidebar-width-sm, px);
- }
-}
-
-/*
- * Short window. Text next to icons.
- */
-@media (min-width: @screen-sm-min) and (max-width: @screen-lg-min), (min-width: @screen-sm-min) and (max-height: @sidebar-height-lg) {
- .nav-sidebar {
- width: unit(@sidebar-width-md, px);
- a {
- padding: 7px 8px 5px 8px !important;
- height: 40px !important;
- width: unit(@sidebar-width-md, px) !important;
- i {
- float: none !important;
- margin-right: 0px !important;
- }
- span {
- display: inline !important;
- font-size: 12px;
- margin-left: 4px;
- margin-top: 2px;
- }
- }
- }
-
- #content {
- margin-left: unit(@sidebar-width-md + 20, px);
- }
-
- .content-filter {
- left: unit(@sidebar-width-md, px);
- }
-
-}
diff --git a/pkg/kubernetes/styles/tags.less b/pkg/kubernetes/styles/tags.less
deleted file mode 100644
index d47f42b66..000000000
--- a/pkg/kubernetes/styles/tags.less
+++ /dev/null
@@ -1,54 +0,0 @@
-
-.image-tag {
- border: 2px solid @tag-border;
- border-radius: 7px;
- padding: 3px 5px;
- white-space: nowrap;
- background-color: @listing-ct-hover;
-}
-
-a.image-tag {
- color: inherit;
-}
-
-.image-tag-editor {
- -moz-appearance: textfield;
- -webkit-appearance: textfield;
- background-color: white;
- background-color: -moz-field;
- border: 1px solid darkgray;
- box-shadow: 1px 1px 1px 0 lightgray inset;
- font: -moz-field;
- font: -webkit-small-control;
- padding: 4px;
- font-size: 13px;
- max-width: 500px;
-}
-
-.image-tag-editor:focus {
- border-color: #66afe9;
- outline: 0;
- -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
- box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
-}
-
-.image-tag-editor .image-tag {
- padding: 1px 5px;
- margin: 2px 1px 2px 1px;
- cursor: default;
- display: inline-block;
-}
-
-.image-tag a {
- color: #999;
- position: relative;
- padding-left: 4px;
- font-size: 12px;
- top: 1px;
-}
-
-.image-tag a:hover {
- color: black;
- text-decoration: none;
-}
-
diff --git a/pkg/kubernetes/styles/topology.less b/pkg/kubernetes/styles/topology.less
deleted file mode 100644
index c57ec30f4..000000000
--- a/pkg/kubernetes/styles/topology.less
+++ /dev/null
@@ -1,60 +0,0 @@
-kubernetes-topology-graph {
- margin-right: 25%;
- margin-top: 55px;
- padding-bottom: 0px !important;
- overflow: hidden;
-}
-
-.kube-pane {
- float: right;
- width: 25%;
-
- .sidebar-pf-right {
- right: 0px;
- }
-}
-
-.kube-pane .sidebar-pf {
- position: fixed;
- width: 25%;
- height: 100%;
- padding: 10px;
- overflow: hidden;
-}
-
-.kube-pane .dl-horizontal {
-}
-
-.kube-pane .dl-horizontal dt {
- text-align: left;
- width: 90px;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.kube-pane .dl-horizontal dd {
- margin-left: 100px;
- margin-right: 30px;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.kube-pane .sidebar-help p {
- margin-right: 30px;
- margin-bottom: 30px;
-}
-
-.kube-pane .sidebar-help h3 {
- padding-top: 7px;
- padding-bottom: 10px;
-}
-
-kubernetes-topology-icon {
- display: block;
- float: left;
- padding: 0 10px 5px 0;
-}
-
-.topology-actions {
- float: right;
-}
diff --git a/pkg/kubernetes/styles/variables.less b/pkg/kubernetes/styles/variables.less
deleted file mode 100644
index f8d9bf9ce..000000000
--- a/pkg/kubernetes/styles/variables.less
+++ /dev/null
@@ -1,7 +0,0 @@
-@import "../../lib/variables.less";
-
-@sidebar-width-sm: 40;
-@sidebar-width-md: 145;
-@sidebar-width-xl: 185;
-
-@command-bg-color: #eee;
diff --git a/pkg/kubernetes/styles/volumes.less b/pkg/kubernetes/styles/volumes.less
deleted file mode 100644
index de23402ae..000000000
--- a/pkg/kubernetes/styles/volumes.less
+++ /dev/null
@@ -1,19 +0,0 @@
-label.inline {
- margin-right: 16px;
-}
-
-div.modal-body ul.dialog-list-ct {
- padding-top: 10px;
-}
-
-div.modal-body ul.dialog-list-ct li {
- padding-bottom: 10px;
-}
-
-.pvc-listing button.btn-danger {
- visibility: hidden;
-}
-
-.pvc-listing tr.listing-ct-item:hover button.btn-danger {
- visibility: visible;
-}
diff --git a/pkg/kubernetes/views/add-group-dialog.html b/pkg/kubernetes/views/add-group-dialog.html
deleted file mode 100644
index 48a759481..000000000
--- a/pkg/kubernetes/views/add-group-dialog.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/add-member-role-dialog.html b/pkg/kubernetes/views/add-member-role-dialog.html
deleted file mode 100644
index a59aff2e4..000000000
--- a/pkg/kubernetes/views/add-member-role-dialog.html
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/add-role-dialog.html b/pkg/kubernetes/views/add-role-dialog.html
deleted file mode 100644
index 05bc3f97c..000000000
--- a/pkg/kubernetes/views/add-role-dialog.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- Do you want to add the role '{{ fields.displayRole }}'?
-
-
diff --git a/pkg/kubernetes/views/add-user-dialog.html b/pkg/kubernetes/views/add-user-dialog.html
deleted file mode 100644
index 166840fec..000000000
--- a/pkg/kubernetes/views/add-user-dialog.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/auth-dialog.html b/pkg/kubernetes/views/auth-dialog.html
deleted file mode 100644
index 27f32c736..000000000
--- a/pkg/kubernetes/views/auth-dialog.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
diff --git a/pkg/kubernetes/views/auth-form.html b/pkg/kubernetes/views/auth-form.html
deleted file mode 100644
index 0a53d0b0f..000000000
--- a/pkg/kubernetes/views/auth-form.html
+++ /dev/null
@@ -1,132 +0,0 @@
-
-
-
diff --git a/pkg/kubernetes/views/auth-rejected-cert.html b/pkg/kubernetes/views/auth-rejected-cert.html
deleted file mode 100644
index cb5e1cf83..000000000
--- a/pkg/kubernetes/views/auth-rejected-cert.html
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
The server uses a certificate signed by an unknown authority.
-
You can bypass the certificate check, but any data you send to the server could be intercepted by others.
-
-
-
-
-
diff --git a/pkg/kubernetes/views/container-body.html b/pkg/kubernetes/views/container-body.html
deleted file mode 100644
index 0bdc8292c..000000000
--- a/pkg/kubernetes/views/container-body.html
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
- Container
- {{container.spec.name}}
- Image
- {{container.spec.image}}
- Image ID
- {{container.status.imageID | kubeIdentifier }}
- Container ID
- {{container.status.containerID | kubeIdentifier }}
- Ports
-
- {{port.containerPort}}/{{port.protocol}}
-
- State
- {{state}}
- Since
- {{args.startedAt}}
- Restart Count
- {{container.status.restartCount}}
-
-
-
-
- Environment
- {{env.name}}={{env.value}}
-
-
-
-
diff --git a/pkg/kubernetes/views/container-page-inline.html b/pkg/kubernetes/views/container-page-inline.html
deleted file mode 100644
index bc83700c7..000000000
--- a/pkg/kubernetes/views/container-page-inline.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
Container
-
-
-
-
-
-
Logs
-
-
-
-
-
-
Shell
-
-
-
-
-
-
-
-
The container '{{ target }}' does not exist.
-
diff --git a/pkg/kubernetes/views/container-page.html b/pkg/kubernetes/views/container-page.html
deleted file mode 100644
index b663911c5..000000000
--- a/pkg/kubernetes/views/container-page.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
{{ container.spec.name }}
-
{{ target }}
-
Show all Containers
-
-
-
diff --git a/pkg/kubernetes/views/container-panel.html b/pkg/kubernetes/views/container-panel.html
deleted file mode 100644
index 84e15d2b9..000000000
--- a/pkg/kubernetes/views/container-panel.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/pkg/kubernetes/views/containers-listing.html b/pkg/kubernetes/views/containers-listing.html
deleted file mode 100644
index acc098be0..000000000
--- a/pkg/kubernetes/views/containers-listing.html
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
- Containers
-
-
-
-
-
- Name
- Pod
- Project
- Namespace
- Node
- Status
-
-
-
-
-
-
-
-
-
-
-
- {{container.spec.name}}
- {{item.metadata.name}}
- {{item.metadata.namespace}}
- {{item.spec.nodeName}}
- {{name}}
-
-
-
-
-
-
-
-
diff --git a/pkg/kubernetes/views/containers-page.html b/pkg/kubernetes/views/containers-page.html
deleted file mode 100644
index 1aaf9f74a..000000000
--- a/pkg/kubernetes/views/containers-page.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
diff --git a/pkg/kubernetes/views/dashboard-page.html b/pkg/kubernetes/views/dashboard-page.html
deleted file mode 100644
index baf4d0bfd..000000000
--- a/pkg/kubernetes/views/dashboard-page.html
+++ /dev/null
@@ -1,215 +0,0 @@
-
-
-
-
-
-
-
-
-
{{pods.length}} Pods
-
-
-
- {{status.pods.Pending.length}}
-
-
- {{status.pods.Failed.length}}
-
-
- {{status.pods.Unknown.length}}
-
-
-
-
- All running
-
-
- No pods deployed
-
-
-
-
-
-
-
-
{{nodes.length}} Nodes
-
-
-
- {{status.nodes.Pending.length}}
-
-
- {{status.nodes.Terminated.length}}
-
-
- {{status.nodes.NotReady.length}}
-
-
- {{status.nodes.OutOfDisk.length}}
-
-
-
- All healthy
-
-
-
- No nodes in cluster
-
-
-
-
-
-
-
-
-
-
-
-
- Deploy
-
-
Services
-
-
-
-
-
-
-
-
Could not list services
-
{{failure.message}}
-
-
-
-
-
-
No services present
-
You can deploy an application to your cluster.
-
-
-
-
- Name
- Address
- Containers
- Project
- Namespace
-
-
-
-
-
- {{service.metadata.name}}
-
- {{serviceContainers(service)}}
- {{service.metadata.namespace}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name
- Containers
-
-
-
-
-
- {{node.metadata.name}}
- {{nodeContainers(node)}}
-
-
-
-
-
-
-
-
-
diff --git a/pkg/kubernetes/views/default-panel.html b/pkg/kubernetes/views/default-panel.html
deleted file mode 100644
index 78d46d142..000000000
--- a/pkg/kubernetes/views/default-panel.html
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
diff --git a/pkg/kubernetes/views/deploy.html b/pkg/kubernetes/views/deploy.html
deleted file mode 100644
index a2bb2746a..000000000
--- a/pkg/kubernetes/views/deploy.html
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/deploymentconfig-body.html b/pkg/kubernetes/views/deploymentconfig-body.html
deleted file mode 100644
index 4c27f7735..000000000
--- a/pkg/kubernetes/views/deploymentconfig-body.html
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
-
- Project
- Namespace
- {{ item.metadata.namespace }}
- Created
- {{ item.metadata.creationTimestamp | dateRelative }}
- Replicas
- {{ item.spec.replicas }}
-
- Strategy
- {{item.spec.strategy.type}}
-
- Latest Version
- {{ item.status.latestVersion }}
- Not deployed
-
-
-
-
- Deployment Causes
- {{ item.status.details.message }}
-
- {{ cause.type }}
-
- - {{ cause.imageTrigger.from.name }}
-
-
-
-
- Triggers
-
- {{ trigger.type }}
-
- - {{ trigger.imageChangeParams.from.name }}
-
-
-
-
- Labels
- none
- {{key}}={{value}}
-
-
-
diff --git a/pkg/kubernetes/views/deploymentconfig-page.html b/pkg/kubernetes/views/deploymentconfig-page.html
deleted file mode 100644
index cfe76a45b..000000000
--- a/pkg/kubernetes/views/deploymentconfig-page.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
{{ item.metadata.name }}
-
{{ target }}
-
Show all Deployment Configs
-
-
-
-
Deployment Config
-
-
-
Template
-
-
-
-
-
-
-
-
-
-
The deployment config '{{ target }}' does not exist.
-
diff --git a/pkg/kubernetes/views/deploymentconfig-panel.html b/pkg/kubernetes/views/deploymentconfig-panel.html
deleted file mode 100644
index 95de37291..000000000
--- a/pkg/kubernetes/views/deploymentconfig-panel.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/pkg/kubernetes/views/details-page.html b/pkg/kubernetes/views/details-page.html
deleted file mode 100644
index 08a6b15b3..000000000
--- a/pkg/kubernetes/views/details-page.html
+++ /dev/null
@@ -1,196 +0,0 @@
-
-
-
-
-
- All Types
- Type: {{ name }}
-
-
-
-
-
-
-
-
-
-
-
-
- Services
-
-
-
-
- Name
- Project
- Namespace
- Addresses
- State
-
-
-
-
-
-
-
- {{item.metadata.name}}
- {{item.metadata.namespace}}
-
-
- Ready
- Not Ready
-
-
-
-
-
-
-
-
-
-
-
- Routes
-
-
-
-
- Name
- Project
- Namespace
- Host
-
-
-
-
-
-
-
-
- {{item.metadata.name}}
- {{item.metadata.namespace}}
- {{item.spec.host}}
-
-
-
-
-
-
-
-
-
-
- Deployment Configs
-
-
-
-
- Name
- Project
- Namespace
-
- Latest Version
-
-
-
-
-
-
-
- {{item.metadata.name}}
- {{item.metadata.namespace}}
-
- {{ item.status.latestVersion }}
- Not deployed
-
-
-
-
-
-
-
-
-
- Replication Controllers
-
-
-
-
- Name
- Project
- Namespace
-
- Replicas
-
-
-
-
-
-
-
- {{item.metadata.name}}
- {{item.metadata.namespace}}
-
- {{ item.spec.replicas }}
- {{ item.status.replicas }} of {{ item.spec.replicas }}
-
-
-
-
-
-
-
-
-
- Pods
-
-
-
-
- Name
- Project
- Namespace
- Address
- State
-
-
-
-
-
-
-
- {{item.metadata.name}}
- {{item.metadata.namespace}}
- {{item.status.podIP}}
- {{ podStatus(item) }}
-
-
-
-
-
-
-
diff --git a/pkg/kubernetes/views/file-button.html b/pkg/kubernetes/views/file-button.html
deleted file mode 100644
index f3f97e7c0..000000000
--- a/pkg/kubernetes/views/file-button.html
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- Select Manifest File...
- {{ fields.filename }}
-
diff --git a/pkg/kubernetes/views/filter-bar.html b/pkg/kubernetes/views/filter-bar.html
deleted file mode 100644
index 7b2fb049f..000000000
--- a/pkg/kubernetes/views/filter-bar.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/filter-project.html b/pkg/kubernetes/views/filter-project.html
deleted file mode 100644
index 00657de43..000000000
--- a/pkg/kubernetes/views/filter-project.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- All Projects
- Project:
- {{filter.namespace()}}
-
-
-
-
-
diff --git a/pkg/kubernetes/views/group-delete.html b/pkg/kubernetes/views/group-delete.html
deleted file mode 100644
index 3b942db4a..000000000
--- a/pkg/kubernetes/views/group-delete.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
The '{{ fields.group.metadata.name }}' group will be deleted from projects:
-
-
-
Projects
- {{ member.metadata.name }}
-
-
-
-
-
The group '{{ fields.group.metadata.name }}' will be removed.
-
-
-
-
diff --git a/pkg/kubernetes/views/group-page.html b/pkg/kubernetes/views/group-page.html
deleted file mode 100644
index f252d1719..000000000
--- a/pkg/kubernetes/views/group-page.html
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
- {{ group().metadata.name }}
-
-
-
- {{ groupName }}
-
-
Show all Projects
-
-
-
-
The group '{{ groupName }}' does not exist.
-
diff --git a/pkg/kubernetes/views/group-panel.html b/pkg/kubernetes/views/group-panel.html
deleted file mode 100644
index 85a88f97d..000000000
--- a/pkg/kubernetes/views/group-panel.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
{{ group().metadata.name }}
-
-
diff --git a/pkg/kubernetes/views/image-delete.html b/pkg/kubernetes/views/image-delete.html
deleted file mode 100644
index dbc448dd4..000000000
--- a/pkg/kubernetes/views/image-delete.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- Do you want to remove the image tagged as '{{stream.metadata.namespace}}/{{stream.metadata.name}}:{{tag.tag}}'?
-
-
diff --git a/pkg/kubernetes/views/image-page.html b/pkg/kubernetes/views/image-page.html
deleted file mode 100644
index d0f4ebc65..000000000
--- a/pkg/kubernetes/views/image-page.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-
- {{ stream.metadata.namespace }}/{{ stream.metadata.name}}:{{ tag.tag }}
-
-
Show all images
-
-
-
-
Image
-
-
-
-
-
-
-
-
Container
-
-
-
-
-
-
Metadata
-
-
-
-
-
-
-
diff --git a/pkg/kubernetes/views/images-page.html b/pkg/kubernetes/views/images-page.html
deleted file mode 100644
index e711c0847..000000000
--- a/pkg/kubernetes/views/images-page.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
diff --git a/pkg/kubernetes/views/imagestream-delete.html b/pkg/kubernetes/views/imagestream-delete.html
deleted file mode 100644
index cb37b2068..000000000
--- a/pkg/kubernetes/views/imagestream-delete.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- Do you want to delete the '{{stream.metadata.namespace}}/{{stream.metadata.name}}' image stream?
-
-
diff --git a/pkg/kubernetes/views/imagestream-modify.html b/pkg/kubernetes/views/imagestream-modify.html
deleted file mode 100644
index 2eac2c1e6..000000000
--- a/pkg/kubernetes/views/imagestream-modify.html
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/imagestream-page.html b/pkg/kubernetes/views/imagestream-page.html
deleted file mode 100644
index 2d1a9f63f..000000000
--- a/pkg/kubernetes/views/imagestream-page.html
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
- {{ stream.metadata.namespace }}/{{ stream.metadata.name}}
-
-
Show all image streams
-
-
-
-
Image Stream
-
-
-
-
-
-
-
Images
-
-
-
-
Metadata
-
-
-
-
-
diff --git a/pkg/kubernetes/views/item-delete.html b/pkg/kubernetes/views/item-delete.html
deleted file mode 100644
index a7807f9f0..000000000
--- a/pkg/kubernetes/views/item-delete.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
Do you want to delete the {{ item.kind }} '{{item.metadata.name}}'?
-
Deleting a Pod will kill all associated containers. Pods may be automatically created again in some cases.
-
-
-
diff --git a/pkg/kubernetes/views/node-add.html b/pkg/kubernetes/views/node-add.html
deleted file mode 100644
index 0bcd8ea60..000000000
--- a/pkg/kubernetes/views/node-add.html
+++ /dev/null
@@ -1,52 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/node-alerts.html b/pkg/kubernetes/views/node-alerts.html
deleted file mode 100644
index f0282422f..000000000
--- a/pkg/kubernetes/views/node-alerts.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
- {{ nodeCondition(item, 'Ready').message }}
-
-
-
- The node doesn't have enough disk space .
-
-
-
- The node doesn't have enough free memory .
-
-
diff --git a/pkg/kubernetes/views/node-body.html b/pkg/kubernetes/views/node-body.html
deleted file mode 100644
index 5e86083e3..000000000
--- a/pkg/kubernetes/views/node-body.html
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
- Created
- {{ item.metadata.creationTimestamp | dateRelative }}
- Address
-
- {{item.metadata.name}}
- {{item.metadata.name}}
-
- IP
- {{ nodeIPAddress(item) }}
- Unknown
- OS
- {{item.status.nodeInfo.osImage}}
- Machine ID
- {{item.status.nodeInfo.machineID}}
- Boot ID
- {{item.status.nodeInfo.bootID}}
- Kernel Version
- {{item.status.nodeInfo.kernelVersion}}
- Container Runtime Version
- {{item.status.nodeInfo.containerRuntimeVersion}}
- Kubelet Version
- {{item.status.nodeInfo.kubeletVersion}}
- Proxy Version
- {{item.status.nodeInfo.kubeProxyVersion}}
-
-
-
-
- Labels
- {{key}}={{value}}
- none
-
-
-
-
-
- Status
-
- Ready
- Not Ready
- Unknown
-
- Reason
- {{ready.reason }}
- Message
- {{ready.reason }}
- Last Heartbeat
- {{ready.lastHeartbeatTime | dateRelative }}
- Last Status Change
- {{ready.lastTransitionTime | dateRelative }}
-
-
-
-
- Annotations
- {{key}}={{value}}
- none
-
-
diff --git a/pkg/kubernetes/views/node-capacity.html b/pkg/kubernetes/views/node-capacity.html
deleted file mode 100644
index 639dc965b..000000000
--- a/pkg/kubernetes/views/node-capacity.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
- {{ key | formatCapacityName }}
- {{ value | formatCapacityValue:key }}
-
-
-
-
- Scheduled Pods
- {{ pod.metadata.name }}
- No pods scheduled
-
-
diff --git a/pkg/kubernetes/views/node-delete.html b/pkg/kubernetes/views/node-delete.html
deleted file mode 100644
index 054deeda6..000000000
--- a/pkg/kubernetes/views/node-delete.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
Do you want to delete this Node?
-
Do you want to delete the following Nodes?
-
- {{ node.metadata.name }}
-
-
-
-
diff --git a/pkg/kubernetes/views/node-page.html b/pkg/kubernetes/views/node-page.html
deleted file mode 100644
index 95cbc4361..000000000
--- a/pkg/kubernetes/views/node-page.html
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
{{ item.metadata.name }}
-
{{ target }}
-
Show all Nodes
-
-
-
-
-
-
Node
-
-
-
Capacity
-
-
-
-
-
-
The node '{{ target }}' does not exist.
-
diff --git a/pkg/kubernetes/views/node-panel.html b/pkg/kubernetes/views/node-panel.html
deleted file mode 100644
index 51b5dcde1..000000000
--- a/pkg/kubernetes/views/node-panel.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
diff --git a/pkg/kubernetes/views/node-stats.html b/pkg/kubernetes/views/node-stats.html
deleted file mode 100644
index 4248231d3..000000000
--- a/pkg/kubernetes/views/node-stats.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/pkg/kubernetes/views/nodes-page.html b/pkg/kubernetes/views/nodes-page.html
deleted file mode 100644
index 1073f0111..000000000
--- a/pkg/kubernetes/views/nodes-page.html
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
-
-
-
diff --git a/pkg/kubernetes/views/pod-body.html b/pkg/kubernetes/views/pod-body.html
deleted file mode 100644
index ebd03a1f3..000000000
--- a/pkg/kubernetes/views/pod-body.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
- Project
- Namespace
- {{ pod.metadata.namespace }}
- Created
- {{ pod.metadata.creationTimestamp | dateRelative }}
- Restart Policy
- {{ pod.spec.restartPolicy }}
- Service Account
- {{ pod.spec.serviceAccountName }}
- DNS Policy
- {{ pod.spec.dnsPolicy }}
- Phase
- {{pod.status.phase}}
- Node
- {{pod.spec.host}}
- Pod Address
- {{pod.status.podIP}}
-
-
-
-
- Labels
- {{key}}={{value}}
-
-
-
diff --git a/pkg/kubernetes/views/pod-container.html b/pkg/kubernetes/views/pod-container.html
deleted file mode 100644
index 4e2f8848e..000000000
--- a/pkg/kubernetes/views/pod-container.html
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
{{ pod.metadata.name }} / {{ container.spec.name }}
-
{{ target }}
-
Show all Pod Containers
-
-
-
diff --git a/pkg/kubernetes/views/pod-page.html b/pkg/kubernetes/views/pod-page.html
deleted file mode 100644
index 6430e79e5..000000000
--- a/pkg/kubernetes/views/pod-page.html
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
{{ item.metadata.name }}
-
{{ target }}
-
Show all Pods
-
-
-
-
Pod
-
-
-
-
-
-
Volumes
-
-
{{ podVolume.name }}
-
-
-
- Mount Location
-
- None
-
- {{ name }}
- {{ data.mountPath }}
-
-
-
-
-
-
Containers
-
-
-
-
The pod '{{ target }}' does not exist.
-
diff --git a/pkg/kubernetes/views/pod-panel.html b/pkg/kubernetes/views/pod-panel.html
deleted file mode 100644
index 4de545a49..000000000
--- a/pkg/kubernetes/views/pod-panel.html
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
{{ container.spec.name }}
-
-
-
-
-
-
-
{{ container.spec.name }}
-
-
-
-
-
-
-
-
-
-
- Mount Location
-
- None
-
- {{ name }}
- {{ data.mountPath }}
-
-
-
-
-
-
diff --git a/pkg/kubernetes/views/project-body.html b/pkg/kubernetes/views/project-body.html
deleted file mode 100644
index f92236aae..000000000
--- a/pkg/kubernetes/views/project-body.html
+++ /dev/null
@@ -1,113 +0,0 @@
-
-
- Project access policy allows anonymous users to pull images. Grant additional push or admin access to specific members below.
-
-
-
-
- Project access policy allows any authenticated user to pull images. Grant additional push or admin access to specific members below.
-
-
-
-
- Project access policy only allows specific members to access images. Grant access to specific members below.
-
-
-
-
-
-
- Project Members
- Roles
-
-
-
-
-
-
-
-
- {{ user.metadata.name }}
-
-
-
-
-
-
-
- {{ getRegistryRoles(user, project()).join() }}
-
-
-
-
-
-
-
-
-
- Admin
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ group.metadata.name }}
-
-
-
-
-
-
-
- {{ getRegistryRoles(group, project()).join() }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Add Member
-
-
-
-
-
diff --git a/pkg/kubernetes/views/project-delete.html b/pkg/kubernetes/views/project-delete.html
deleted file mode 100644
index fab242893..000000000
--- a/pkg/kubernetes/views/project-delete.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
All objects in the Project '{{ project.metadata.name }}' will be deleted:
-
-
diff --git a/pkg/kubernetes/views/project-listing.html b/pkg/kubernetes/views/project-listing.html
deleted file mode 100644
index 64fc1ccd1..000000000
--- a/pkg/kubernetes/views/project-listing.html
+++ /dev/null
@@ -1,116 +0,0 @@
-
-
-
-
-
-
- New Project
-
- Projects
-
-
-
-
- Name
- Description
- Members
-
-
-
-
-
-
-
- {{ item.metadata.name }}
- {{ item.metadata.annotations["openshift.io/description"] }}
-
-
-
-
-
-
-
-
-
- No projects are present.
- {{failure}}
-
-
-
-
-
-
-
- New Group
-
- Groups
-
-
-
-
- Name
- Description
- Members
-
-
-
-
-
-
-
- {{ item.metadata.name }}
-
- {{ formatMembers(item.users, 'Users') }}
-
-
-
-
-
-
- No groups are present.
- {{failure}}
-
-
-
-
-
-
-
- Add User
-
- Users
-
-
-
-
- Name
- Identity
- Member of
-
-
-
-
-
-
-
- {{ item.metadata.name }}
- {{ formatMembers(item.identities, 'Identities') }}
- {{ formatMembers(getMembershipOfUser(projects(),groups(),item.metadata.name), 'Groups') }}
-
-
-
-
-
-
-
- No users are present.
- {{failure}}
-
-
-
diff --git a/pkg/kubernetes/views/project-modify.html b/pkg/kubernetes/views/project-modify.html
deleted file mode 100644
index e0fde2c89..000000000
--- a/pkg/kubernetes/views/project-modify.html
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/project-page.html b/pkg/kubernetes/views/project-page.html
deleted file mode 100644
index 9ce63f14d..000000000
--- a/pkg/kubernetes/views/project-page.html
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
- {{ project().metadata.annotations['openshift.io/display-name'] }} ({{ project().metadata.name }})
-
-
- {{ project().metadata.name }}
-
-
-
-
-
- {{ projName }}
-
-
-
Show all Projects
-
-
-
- {{ project().metadata.annotations['openshift.io/description'] }}
-
-
Membership
-
-
-
-
-
The project '{{ projName }}' does not exist.
-
diff --git a/pkg/kubernetes/views/project-panel.html b/pkg/kubernetes/views/project-panel.html
deleted file mode 100644
index 66d170c2a..000000000
--- a/pkg/kubernetes/views/project-panel.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
- {{ project().metadata.annotations['openshift.io/description'] }}
-
-
-
-
diff --git a/pkg/kubernetes/views/projects-page.html b/pkg/kubernetes/views/projects-page.html
deleted file mode 100644
index 8d0e333d5..000000000
--- a/pkg/kubernetes/views/projects-page.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/pv-body.html b/pkg/kubernetes/views/pv-body.html
deleted file mode 100644
index ff174c3bf..000000000
--- a/pkg/kubernetes/views/pv-body.html
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
- Reclaim Policy
- {{ item.spec.persistentVolumeReclaimPolicy | reclaimLabel }}
-
- Access Modes
-
- {{ mode | accessModeLabel }},
-
- Capacity
-
-
- {{ key | formatCapacityName }}
- {{ value | formatCapacityValue:key }}
-
-
-
-
-
-
- Status
- {{ item.status.phase }}
- Unknown
- Message
- {{ item.status.message }}
-
-
-
diff --git a/pkg/kubernetes/views/pv-claim.html b/pkg/kubernetes/views/pv-claim.html
deleted file mode 100644
index ca47082c6..000000000
--- a/pkg/kubernetes/views/pv-claim.html
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
- Name
- {{ pvc.metadata.name }}
- Namespace
- {{ pvc.metadata.namespace }}
-
- Access Modes
-
- {{ mode | accessModeLabel }},
-
- Requests
-
-
- {{ key | formatCapacityName }}
- {{ value | formatCapacityValue:key }}
-
-
-
-
-
- This volume has not been claimed
-
-
-
-
-
- Status
- {{ pvc.status.phase }}
- Unknown
- Message
- {{ pvc.status.message }}
-
-
-
- Pods
- {{ pod.metadata.namespace }} / {{ pod.metadata.name }}
- No Pods are using this claim
-
-
-
diff --git a/pkg/kubernetes/views/pv-delete.html b/pkg/kubernetes/views/pv-delete.html
deleted file mode 100644
index fdbcf7ff9..000000000
--- a/pkg/kubernetes/views/pv-delete.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
Do you want to delete the Persistent Volume '{{item.metadata.name}}'?
-
This volume has been claimed by {{ item.item.spec.claimRef.namespace }} / {{ item.item.spec.claimRef.name }}. Deleting it will break that claim and may cause issues with any pods depending on it.
-
-
-
diff --git a/pkg/kubernetes/views/pv-modify.html b/pkg/kubernetes/views/pv-modify.html
deleted file mode 100644
index a46250ca7..000000000
--- a/pkg/kubernetes/views/pv-modify.html
+++ /dev/null
@@ -1,209 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/pv-page.html b/pkg/kubernetes/views/pv-page.html
deleted file mode 100644
index aa07b73a4..000000000
--- a/pkg/kubernetes/views/pv-page.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
{{ item.metadata.name }}
-
{{ target }}
-
Show all Persistent Volumes
-
-
-
-
-
-
The persistent volume '{{ target }}' does not exist.
-
diff --git a/pkg/kubernetes/views/pv-panel.html b/pkg/kubernetes/views/pv-panel.html
deleted file mode 100644
index 36279a611..000000000
--- a/pkg/kubernetes/views/pv-panel.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
diff --git a/pkg/kubernetes/views/pvc-body.html b/pkg/kubernetes/views/pvc-body.html
deleted file mode 100644
index d6d0b2e82..000000000
--- a/pkg/kubernetes/views/pvc-body.html
+++ /dev/null
@@ -1,54 +0,0 @@
-
- Volume Type
- Persistent Volume
- Claim Name
- {{ item.metadata.name }}
- Volume
-
- {{ item.spec.volumeName }}
- {{ item.spec.volumeName }}
- No Volume Bound
-
-
- Status
- {{ item.status.phase }}
- Message
- {{ item.status.message }}
-
- Access Modes
-
-
- Requested
-
- {{ mode | accessModeLabel }},
-
- Actual
-
- {{ mode | accessModeLabel }},
-
-
-
-
- Capacity
-
-
- Requested
-
-
- {{ key | formatCapacityName }}
- {{ value | formatCapacityValue:key }}
-
-
-
-
-
- Actual
-
-
- {{ key | formatCapacityName }}
- {{ value | formatCapacityValue:key }}
-
-
-
-
-
diff --git a/pkg/kubernetes/views/pvc-delete.html b/pkg/kubernetes/views/pvc-delete.html
deleted file mode 100644
index 8abdbd071..000000000
--- a/pkg/kubernetes/views/pvc-delete.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
Do you want to delete the Persistent Volume Claim '{{item.metadata.name}}'?
-
This claim is in use. Deleting it may cause issues with the following pods:
-
This claim is in use. Deleting it may cause issues with the following pod:
-
- {{ pod.metadata.name }}
-
-
-
-
diff --git a/pkg/kubernetes/views/registry-dashboard-page.html b/pkg/kubernetes/views/registry-dashboard-page.html
deleted file mode 100644
index ce41bfc92..000000000
--- a/pkg/kubernetes/views/registry-dashboard-page.html
+++ /dev/null
@@ -1,162 +0,0 @@
-
-
-
-
-
Welcome to the Image Registry
-
In order to begin pushing images to the registry, you need to create a project.
-
-
-
-
-
-
-
Images by project
-
Images
-
-
-
-
-
-
-
-
Images pushed recently
-
-
-
-
-
-
-
-
-
No images pushed
-
In order to begin pushing images to the registry, use the commands below.
-
-
-
-
-
-
-
-
-
- Login commands
-
-
-
-
- Log into the registry:
-
-
-
-
-
-
- Your login credentials do not give you access to use the docker registry from the command line.
-
-
$ sudo docker login -p {{settings.registry.password}} -u unused {{settings.registry.host}}
-
- Log into OpenShift command line tools:
-
-
-
-
-
$ oc login --token {{settings.registry.password}} {{settings.registry.openshifthost}}
-
-
-
-
-
-
-
-
- Image commands
-
-
-
-
-
- Push an image:
-
-
-
-
-
$ sudo docker tag myimage {{settings.registry.host}} /project /name:tag
-$ sudo docker push {{settings.registry.host}} /project /name
-
-
- Pull an image:
-
-
-
-
-
$ sudo docker pull {{settings.registry.host}} /project /name:tag
-
-
-
diff --git a/pkg/kubernetes/views/remove-role-dialog.html b/pkg/kubernetes/views/remove-role-dialog.html
deleted file mode 100644
index d63c6bd33..000000000
--- a/pkg/kubernetes/views/remove-role-dialog.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
- Do you want to remove the role '{{ fields.displayRole }}' from member {{ fields.member.metadata.name }}?
-
-
diff --git a/pkg/kubernetes/views/replicationcontroller-body.html b/pkg/kubernetes/views/replicationcontroller-body.html
deleted file mode 100644
index 1f3474dea..000000000
--- a/pkg/kubernetes/views/replicationcontroller-body.html
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- Project
- Namespace
- {{ item.metadata.namespace }}
- Created
- {{ item.metadata.creationTimestamp | dateRelative }}
- Replicas
- {{ item.spec.replicas }}
- {{ item.status.replicas }}
- of {{ item.spec.replicas }}
-
-
-
-
- Labels
- {{key}}={{value}}
-
-
-
diff --git a/pkg/kubernetes/views/replicationcontroller-modify.html b/pkg/kubernetes/views/replicationcontroller-modify.html
deleted file mode 100644
index 4dc385e2b..000000000
--- a/pkg/kubernetes/views/replicationcontroller-modify.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/replicationcontroller-page.html b/pkg/kubernetes/views/replicationcontroller-page.html
deleted file mode 100644
index bde9750cc..000000000
--- a/pkg/kubernetes/views/replicationcontroller-page.html
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
{{ item.metadata.name }}
-
{{ target }}
-
Show all Replication Controllers
-
-
-
-
Replication Controller
-
-
-
Pods
-
-
-
Template
-
-
-
-
-
-
-
-
-
-
The replication controller '{{ target }}' does not exist.
-
diff --git a/pkg/kubernetes/views/replicationcontroller-panel.html b/pkg/kubernetes/views/replicationcontroller-panel.html
deleted file mode 100644
index 728ccdd07..000000000
--- a/pkg/kubernetes/views/replicationcontroller-panel.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/pkg/kubernetes/views/replicationcontroller-pods.html b/pkg/kubernetes/views/replicationcontroller-pods.html
deleted file mode 100644
index 6c059f94c..000000000
--- a/pkg/kubernetes/views/replicationcontroller-pods.html
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
- Pod Replicated
- {{ pod.metadata.name }}
- No pods replicated
-
-
-
-
- Pod Selector
- {{key}}={{value}}
-
-
-
diff --git a/pkg/kubernetes/views/route-body.html b/pkg/kubernetes/views/route-body.html
deleted file mode 100644
index 7bd46a980..000000000
--- a/pkg/kubernetes/views/route-body.html
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
- Project
- Namespace
- {{ item.metadata.namespace }}
- Created
- {{ item.metadata.creationTimestamp | dateRelative }}
- Host
- {{ item.spec.host }}
-
- TLS Termination
- yes
- no
-
- {{ item.spec.to.kind }}
- {{item.spec.to.name}}
-
-
-
-
- Labels
- {{key}}={{value}}
- none
-
-
- Annotations
- {{key}}={{value}}
- none
-
-
-
diff --git a/pkg/kubernetes/views/route-modify.html b/pkg/kubernetes/views/route-modify.html
deleted file mode 100644
index 70eefa7f0..000000000
--- a/pkg/kubernetes/views/route-modify.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/route-page.html b/pkg/kubernetes/views/route-page.html
deleted file mode 100644
index d83f122b7..000000000
--- a/pkg/kubernetes/views/route-page.html
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
{{ item.metadata.name }}
-
{{ target }}
-
Show all Routes
-
-
-
-
-
-
The route '{{ target }}' does not exist.
-
diff --git a/pkg/kubernetes/views/route-panel.html b/pkg/kubernetes/views/route-panel.html
deleted file mode 100644
index fbdeeb2bc..000000000
--- a/pkg/kubernetes/views/route-panel.html
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
diff --git a/pkg/kubernetes/views/service-body.html b/pkg/kubernetes/views/service-body.html
deleted file mode 100644
index 849860f9f..000000000
--- a/pkg/kubernetes/views/service-body.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
- Project
- Namespace
- {{ item.metadata.namespace }}
- Created
- {{ item.metadata.creationTimestamp | dateRelative }}
- IP
- {{ item.spec.clusterIP }}
- Type
- {{ item.spec.type }}
- Ports
-
- None
-
- {{portMapping.port}}/{{portMapping.protocol}} → {{portMapping.nodePort || portMapping.targetPort}}
-
-
- Session Affinity
- {{ item.spec.sessionAffinity }}
-
-
-
-
- Labels
- {{key}}={{value}}
-
-
-
diff --git a/pkg/kubernetes/views/service-endpoint.html b/pkg/kubernetes/views/service-endpoint.html
deleted file mode 100644
index 9cb6a5800..000000000
--- a/pkg/kubernetes/views/service-endpoint.html
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- Pod Endpoints
-
- {{ address.ip }} → {{ address.targetRef.name }}
-
-
- Pod Endpoints
- No pods selected
-
-
-
-
- Pod Selector
- {{key}}={{value}}
-
-
-
diff --git a/pkg/kubernetes/views/service-modify.html b/pkg/kubernetes/views/service-modify.html
deleted file mode 100644
index c09e3fb95..000000000
--- a/pkg/kubernetes/views/service-modify.html
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/service-page.html b/pkg/kubernetes/views/service-page.html
deleted file mode 100644
index 7656ecf99..000000000
--- a/pkg/kubernetes/views/service-page.html
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
{{ item.metadata.name }}
-
{{ target }}
-
Show all Services
-
-
-
-
Service
-
-
Endpoints
-
-
-
-
-
The service '{{ target }}' does not exist.
-
diff --git a/pkg/kubernetes/views/service-panel.html b/pkg/kubernetes/views/service-panel.html
deleted file mode 100644
index e082cb60b..000000000
--- a/pkg/kubernetes/views/service-panel.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
diff --git a/pkg/kubernetes/views/topology-page.html b/pkg/kubernetes/views/topology-page.html
deleted file mode 100644
index c674f7da2..000000000
--- a/pkg/kubernetes/views/topology-page.html
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/pkg/kubernetes/views/user-add-membership.html b/pkg/kubernetes/views/user-add-membership.html
deleted file mode 100644
index 96515bca0..000000000
--- a/pkg/kubernetes/views/user-add-membership.html
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/user-body.html b/pkg/kubernetes/views/user-body.html
deleted file mode 100644
index 518a5ae63..000000000
--- a/pkg/kubernetes/views/user-body.html
+++ /dev/null
@@ -1,72 +0,0 @@
-
-
-
- Member of
- Role
-
-
-
-
-
-
-
-
- {{ member.metadata.name }}
-
-
-
-
-
-
-
- {{ getRegistryRoles(user(), member).join() }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ member.metadata.name }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Add Membership
-
-
-
-
-
diff --git a/pkg/kubernetes/views/user-delete.html b/pkg/kubernetes/views/user-delete.html
deleted file mode 100644
index 09b4b9c7f..000000000
--- a/pkg/kubernetes/views/user-delete.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
The user '{{ fields.user.metadata.name }}' will be removed from the following:
-
-
-
Projects
- {{ member.metadata.name }}
-
-
-
Groups
- {{ member.metadata.name }}
-
-
-
-
-
The user '{{ fields.user.metadata.name }}' will be removed.
-
-
-
-
diff --git a/pkg/kubernetes/views/user-group-add.html b/pkg/kubernetes/views/user-group-add.html
deleted file mode 100644
index fa0358a52..000000000
--- a/pkg/kubernetes/views/user-group-add.html
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/user-group-remove.html b/pkg/kubernetes/views/user-group-remove.html
deleted file mode 100644
index bc3f32704..000000000
--- a/pkg/kubernetes/views/user-group-remove.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
Do you want to remove '{{ fields.user }}' from the group '{{ fields.group.metadata.name }}'
-
-
-
diff --git a/pkg/kubernetes/views/user-modify.html b/pkg/kubernetes/views/user-modify.html
deleted file mode 100644
index 51434fc43..000000000
--- a/pkg/kubernetes/views/user-modify.html
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
diff --git a/pkg/kubernetes/views/user-page.html b/pkg/kubernetes/views/user-page.html
deleted file mode 100644
index 6b231db02..000000000
--- a/pkg/kubernetes/views/user-page.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
- {{ user().metadata.name }}
-
-
-
- {{ userName }}
-
-
Show all Projects
-
-
-
User
-
- Identities
- {{ identity }}
-
-
Membership
-
-
-
-
The user '{{ userName }}' does not exist.
-
diff --git a/pkg/kubernetes/views/user-panel.html b/pkg/kubernetes/views/user-panel.html
deleted file mode 100644
index 0af554110..000000000
--- a/pkg/kubernetes/views/user-panel.html
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
-
-
-
-
{{ user().metadata.name }}
-
-
-
-
-
-
- Identities
- {{ identity }}
-
-
-
-
-
-
-
- Member of
- Role
-
-
-
-
-
- {{ member.metadata.name }}
-
-
-
-
-
- {{ getRegistryRoles(user(), member).join() }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ member.metadata.name }}
-
-
-
-
-
-
-
-
-
-
-
-
- Add Membership
-
-
-
-
-
-
diff --git a/pkg/kubernetes/views/user-remove-membership.html b/pkg/kubernetes/views/user-remove-membership.html
deleted file mode 100644
index a3845df84..000000000
--- a/pkg/kubernetes/views/user-remove-membership.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
Do you want to remove '{{ fields.memberObj.metadata.name }}' from '{{ fields.parentObj.metadata.name }}'
-
-
-
diff --git a/pkg/kubernetes/views/volume-body.html b/pkg/kubernetes/views/volume-body.html
deleted file mode 100644
index b4e5031ce..000000000
--- a/pkg/kubernetes/views/volume-body.html
+++ /dev/null
@@ -1,144 +0,0 @@
-
Volume Type
-
{{ volume | formatVolumeType }}
-
-
PD Name
-
{{ volume.gcePersistentDisk.pdName }}
-
Filesystem Type
-
{{ volume.gcePersistentDisk.fsType }}
-
Partition
-
{{ volume.gcePersistentDisk.partition | formatPartitionNumber }}
-
Read Only
-
{{ volume.gcePersistentDisk.readOnly | formatReadOnly }}
-
-
-
Volume ID
-
{{ volume.awsElasticBlockStore.volumeID }}
-
Filesystem Type
-
{{ volume.awsElasticBlockStore.fsType }}
-
Partition
-
{{ volume.awsElasticBlockStore.partition | formatPartitionNumber }}
-
Read Only
-
{{ volume.awsElasticBlockStore.readOnly | formatReadOnly }}
-
-
-
Repository URL
-
{{ volume.gitRepo.repository }}
-
Revision
-
{{ volume.gitRepo.revision }}
-
Directory
-
{{ volume.gitRepo.directory }}
-
-
Name
-
{{ volume.secret.secretName }}
-
-
Medium
-
{{ volume.emptyDir.medium }}
-
-
Path
-
{{ volume.hostPath.path }}
-
-
Endpoint Name
-
{{ volume.glusterfs.endpoints }}
-
Volume Name
-
{{ volume.glusterfs.path }}
-
Read Only
-
{{ volume.glusterfs.readOnly | formatReadOnly }}
-
-
Server
-
{{ volume.nfs.server }}
-
Path
-
{{ volume.nfs.path }}
-
Read Only
-
{{ volume.nfs.readOnly | formatReadOnly }}
-
-
Monitors
-
- {{ monitor }},
-
-
Image Name
-
{{ volume.rbd.image }}
-
Pool Name
-
{{ volume.rbd.pool }}
-
Filesystem Type
-
{{ volume.rbd.fsType }}
-
User
-
volume.rbd.user
-
admin
-
Key Ring Path
-
{{ volume.rbd.keyring }}
-
Secret Volume
-
{{ volume.rbd.secretRef.name }}
-
Read Only
-
{{ volume.rbd.readOnly | formatReadOnly }}
-
-
-
Target Portal
-
{{ volume.iscsi.targetPortal }}
-
Qualified Name
-
{{ volume.iscsi.iqn }}
-
Logical Unit Number
-
{{ volume.iscsi.lun }}
-
Interface
-
{{ volume.iscsi.iscsiInterface }}
-
Filesystem Type
-
{{ volume.iscsi.fsType }}
-
Read Only
-
{{ volume.iscsi.readOnly | formatReadOnly }}
-
-
-
Volume ID
-
{{ volume.cinder.volumeID }}
-
Filesystem Type
-
{{ volume.cinder.fsType }}
-
Read Only
-
{{ volume.cinder.readOnly | formatReadOnly }}
-
-
-
Ceph Monitors
-
- {{ monitor }},
-
-
Path
-
{{ volume.cephfs.path }}
-
User
-
volume.cephfs.user
-
admin
-
Secret File
-
{{ volume.cephfs.secretFile }}
-
Secret Volume
-
{{ volume.cephfs.secretRef.name }}
-
Read Only
-
{{ volume.cephfs.readOnly | formatReadOnly }}
-
-
-
Target World Wide Names
-
- {{ wwn }},
-
-
Logical Unit Number
-
{{ volume.fc.lun }}
-
Filesystem Type
-
{{ volume.fc.fsType }}
-
Read Only
-
{{ volume.fc.readOnly | formatReadOnly }}
-
-
Flocker Dataset Name
-
{{ volume.flocker.datasetName }}
-
-
Driver
-
{{ volume.flexVolume.driver }}
-
Options
-
{{ volume.flexVolume.options }}
-
Filesystem Type
-
{{ volume.flexVolume.fsType }}
-
Secret Volume
-
{{ volume.flexVolume.secretRef.name }}
-
Read Only
-
{{ volume.flexVolume.readOnly | formatReadOnly }}
-
-
Share Name
-
{{ volume.azureFile.shareName }}
-
Secret Name
-
{{ volume.azureFile.secretName }}
-
Read Only
-
{{ volume.azureFile.readOnly | formatReadOnly }}
diff --git a/pkg/kubernetes/views/volumes-page.html b/pkg/kubernetes/views/volumes-page.html
deleted file mode 100644
index 8edc8e172..000000000
--- a/pkg/kubernetes/views/volumes-page.html
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- Register New Volume
-
- Persistent Volumes
-
-
-
-
- Name
- Type
- Status
-
-
-
-
-
-
-
- {{ item.metadata.name }}
- {{ item.spec | formatVolumeType }}
- {{ item.status.phase}}
- Unknown
-
-
-
-
-
-
-
-
- No volumes are present.
- {{pvFailure}}
-
-
-
-
-
-
-
- Pending Volume Claims
-
-
-
- Name
- Project
- Namespace
- Size
- When
-
-
-
-
-
- {{ item.metadata.name }}
- {{ item.metadata.namespace }}
- {{ item.spec.resources.requests.storage }}
- {{ item.metadata.creationTimestamp | dateRelative }}
-
-
-
-
-
-
diff --git a/pkg/lib/angular-dialog.js b/pkg/lib/angular-dialog.js
deleted file mode 100644
index cd035ab7d..000000000
--- a/pkg/lib/angular-dialog.js
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see
.
- */
-
-(function() {
- var angular = require('angular');
- require('angular-bootstrap-npm/dist/angular-bootstrap.js');
-
- angular.module('ui.cockpit', [
- 'ui.bootstrap',
- ])
-
- /*
- * Implements a
directive that works with ui-bootstrap's
- * $modal service. Implements Cockpit dialog HIG behavior.
- *
- * This wraps and provides a default implementation
- * of result and cancel where the dialog is closed when either method
- * is called.
- */
- .directive('modalDialog', [
- "$q",
- function($q) {
- return {
- restrict: 'E',
- transclude: true,
- template: ' ',
- link: function(scope, element, attrs) {
- scope.cancel = function() {
- scope.$dismiss();
- };
-
- scope.result = function(success, result) {
- /* Close dialog on success */
- if (success)
- scope.$close(result);
- };
- },
- };
- }
- ])
-
- /*
- * Implements a directive that works with ui-bootstrap's
- * $modal service. Implements Cockpit dialog HIG behavior.
- *
- * To use this directive your parent scope must implement a result
- * and cancel method. See for the default implementation.
- *
- * This dialog treats a button with .btn-cancel class as a cancel
- * button. Clicking it will call the cancel method or (see below) cancel
- * a completion promise.
- *
- * From inside the dialog, you can invoke the following methods on
- * the scope:
- *
- * failure(ex)
- * failure([ex1, ex2])
- *
- * Displays errors either globally or on fields. The ex.message or
- * ex.toString() is displayed as the failure message. If ex.target
- * is a valid CSS selector, then the failure message will be displayed
- * under the selected field.
- *
- * failure()
- * failure(null)
- *
- * Clears all failures from display.
- *
- * complete(promise)
- * complete(data)
- *
- * Complete the dialog. If a promise is passed, then the dialog will
- * enter into a wait state until the promise completes. If promise resolves
- * then the result method with be called with the resolve value. If the promise
- * rejects, then failures will be displayed by invoking failure() above.
- *
- * While the promise is completing, all .form-control and .btn will
- * be disabled. If promise.cancel() is a method, then the .btn-cancel
- * will remain clickable, and clicking it will cancel the promise, and
- * when the promise completes, will call the cancel method.
- */
- .directive('modalGroup', [
- "$q",
- function($q) {
- return {
- restrict: 'E',
- transclude: true,
- template: ' ',
- link: function(scope, element, attrs) {
- var state = null;
-
- function detach() {
- if (state)
- state.detach();
- state = null;
- }
-
- scope.complete = function(thing) {
- var buttonSel = scope.modalGroupButtonSel || ".modal-footer";
- var errorAfter = scope.modalGroupErrorAfter || false;
-
- detach();
- if (!thing || !thing.then)
- thing = $q(thing);
- state = new DialogState(element, buttonSel, errorAfter, thing, scope);
- };
-
- scope.failure = function(/* ... */) {
- var errors;
- var n = arguments.length;
- if (n === 0) {
- errors = null;
- } else if (n === 1) {
- errors = arguments[0];
- } else {
- errors = [];
- errors.push.apply(errors, arguments);
- }
-
- if (!errors) {
- detach();
- return;
- }
-
- var defer = $q.defer();
- defer.reject(errors);
- scope.complete(defer.promise);
- };
-
- /* Dialog cancellation before promises kick in */
- function dismissDialog() {
- scope.cancel();
- }
-
- var cancel = queryFirst(element, ".btn-cancel");
- cancel.on("click", dismissDialog);
- scope.$on("$routeChangeStart", dismissDialog);
-
- scope.$on("$destroy", function() {
- cancel.off("click", dismissDialog);
- detach();
- });
- },
- };
- }
- ]);
-
- function queryAll(element, selector) {
- var list;
- var result = [];
- var j, i, jlen;
- var len = element.length;
- for (i = 0; i < len; i++) {
- list = element[i].querySelectorAll(selector);
- if (list) {
- for (j = 0, jlen = list.length; j < jlen; j++)
- result.push(list[j]);
- }
- }
- return angular.element(result);
- }
-
- function queryFirst(element, selector) {
- var result = null;
- var i;
- var len = element.length;
- for (i = 0; !result && i < len; i++)
- result = element[i].querySelector(selector);
- return angular.element(result);
- }
-
- /*
- * This state object handles one of three different states.
- * This does not exist in the case "before" these states are relevant.
- *
- * state = null: pending
- * state = true: succeeded
- * state = false: failed
- */
- function DialogState(element, btnSel, errorAfter, promise, scope) {
- var state = null;
- var result = null;
-
- /* Set to true when cancel was requested */
- var cancelled = false;
- var detached = false;
-
- /* The wait field elements */
- var disabled = [];
- var wait = angular.element("");
- wait.append(angular.element("
"));
- var notify = angular.element("
");
- wait.append(notify);
-
- this.detach = detachState;
-
- if (!promise) {
- detachState();
- return;
- }
-
- promise.then(function(data) {
- result = data;
- if (promise)
- changeState(true);
- }, function(data) {
- result = data;
- if (promise)
- changeState(false);
- }, function(data) {
- if (promise)
- notifyWait(data);
- });
-
- window.setTimeout(function() {
- if (promise && scope && state === null) {
- changeState(null);
- scope.$digest();
- }
- }, 0);
-
- function changeState(value) {
- if (detached)
- return;
- state = value;
- if (cancelled) {
- scope.cancel();
- } else if (state === null) {
- clearErrors();
- displayWait();
- } else if (state === true) {
- clearErrors();
- clearWait();
- scope.result(true, result);
- } else if (state === false) {
- clearWait();
- displayErrors(result);
- scope.result(false, result);
- } else {
- console.warn("invalid dialog state", state);
- }
- }
-
- function detachState() {
- scope = null;
- promise = null;
- clearErrors();
- clearWait();
- }
-
- function displayErrors(errors) {
- clearErrors();
-
- if (!angular.isArray(errors))
- errors = [errors];
- errors.forEach(function(error) {
- var target = null;
- /* Each error can have a target field */
- if (error.target)
- target = queryFirst(element, error.target);
- if (target && target[0])
- fieldError(target, error);
- else
- globalError(error);
- });
- }
-
- function globalError(error) {
- var alert = angular.element("");
- var message = error.message || error.toString();
- console.warn(message);
- alert.text(message);
- alert.prepend(angular.element("
"));
-
- var wrapper = queryFirst(element, btnSel);
- if (wrapper.length) {
- if (errorAfter)
- wrapper.append(alert);
- else
- wrapper.prepend(alert);
- } else {
- element.append(alert);
- }
- }
-
- function fieldError(target, error) {
- var message = angular.element("");
- message.text(error.message || error.toString());
- var wrapper = target.parent();
- wrapper.addClass("has-error");
- target.after(message);
- wrapper.on("keypress change", handleClear);
- }
-
- function handleClear(ev) {
- var target = ev.target;
- while (target !== this) {
- clearError(angular.element(target));
- target = target.parentNode;
- }
- }
-
- function clearError(target) {
- var wrapper = target.parent();
- queryAll(wrapper, ".dialog-error").remove();
- wrapper.removeClass("has-error");
- wrapper.off("keypress change", handleClear);
- }
-
- function clearErrors() {
- var messages = queryAll(element, ".dialog-error");
- angular.forEach(messages, function(message) {
- clearError(angular.element(message));
- });
- }
-
- function handleCancel(ev) {
- if (promise.cancel)
- promise.cancel();
- cancelled = true;
- ev.stopPropagation();
- ev.preventDefault();
- return false;
- }
-
- function notifyWait(data) {
- var message = data.message || data;
- if (typeof message == "string" || typeof message == "number")
- notify.text(message);
- else if (!message)
- notify.text("");
- }
-
- function clearWait() {
- var control;
- while (true) {
- control = disabled.pop();
- if (!control)
- break;
- control.removeAttr("disabled");
- }
- wait.remove();
- queryFirst(element, ".btn-cancel").off("click", handleCancel);
- }
-
- function displayWait() {
- clearWait();
-
- /* Insert the wait area */
- queryFirst(element, btnSel).prepend(wait);
-
- /* Disable everything and stash previous disabled state */
- function disable(el) {
- var control = angular.element(el);
- if (control.attr("disabled") ||
- (promise.cancel && control.hasClass("btn-cancel")))
- return;
- disabled.push(control);
- control.attr("disabled", "disabled");
- }
-
- angular.forEach(queryAll(element, ".form-control"), disable);
- angular.forEach(queryAll(element, ".form-checkbox"), disable);
- angular.forEach(queryAll(element, ".btn"), disable);
-
- queryFirst(element, ".btn-cancel").on("click", handleCancel);
- }
- }
-}());
diff --git a/pkg/playground/translate.html b/pkg/playground/translate.html
index 7c3fae2f8..8c7c4a20e 100644
--- a/pkg/playground/translate.html
+++ b/pkg/playground/translate.html
@@ -167,44 +167,6 @@
Extraction of single quoted strings.
-
-
-
-
Angular Translations
-
-
In Angular use these forms:
-
-
- <span translate>Ready</span>
- = Ready
-
-
-
- <span translate translate-context="verb">Ready</span>
- = Ready
-
-
-
- <span translate>Delete '{{ name }}'</span>
- = Delete '{{ name }}'
-
-
-
-
-
When translating Angular we not support :
-
- The translatable
attribute.
- The translate="attr"
translating of attribute values.
- The {{value|translate}}
filter, even though documented on angular-gettext.
- The <translate>
element
-
diff --git a/pkg/playground/translate.js b/pkg/playground/translate.js
index 657b8bf97..bc5d7cb98 100644
--- a/pkg/playground/translate.js
+++ b/pkg/playground/translate.js
@@ -1,8 +1,6 @@
import $ from "jquery";
import cockpit from "cockpit";
import { mustache } from "mustache";
-import angular from 'angular';
-import 'angular-gettext/dist/angular-gettext.js';
const _ = cockpit.gettext;
var C_ = cockpit.gettext;
@@ -42,13 +40,7 @@ $(function () {
$("#mustache-output").empty()
.append(output);
- var module = angular.module('playgroundTranslate', [ 'gettext' ]);
-
- module.run(["$rootScope", function($rootScope) {
- cockpit.transport.wait(function() {
- $rootScope.$digest();
- $("body").show();
- });
- }]);
- angular.bootstrap(document, ['playgroundTranslate']);
+ cockpit.transport.wait(function() {
+ $("body").show();
+ });
});
diff --git a/pkg/shell/index-stub.js b/pkg/shell/index-stub.js
deleted file mode 100644
index ab8292282..000000000
--- a/pkg/shell/index-stub.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-
-import $ from "jquery";
-import cockpit from "cockpit";
-
-import { machines } from "machines";
-import { new_machine_dialog_manager } from "machine-dialogs";
-
-import * as indexes from "./indexes";
-
-var default_title = "Cockpit";
-var manifest = cockpit.manifests["shell"] || { };
-if (manifest.title)
- default_title = manifest.title;
-
-var options = {
- brand_sel: "#index-brand",
- logout_sel: "#go-logout",
- oops_sel: "#navbar-oops",
- language_sel: "#display-language",
- about_sel: "#about-version",
- default_title: default_title,
- skip_brand_title: true
-};
-
-/* When alt is held down we display debugging menu items */
-document.addEventListener("click", function(ev) {
- var i;
- var visible = !!ev.altKey;
- var advanced = document.querySelectorAll(".navbar-advanced");
- for (i = 0; i < advanced.length; i++)
- advanced[i].style.display = visible ? "block" : "none";
-}, true);
-
-var machines_inst = machines.instance();
-var loader = machines.loader(machines_inst, true);
-var dialogs = new_machine_dialog_manager(machines_inst, {
- "no-cockpit": "not-supported",
- "not-supported": "not-supported",
- "protocol-error": "not-supported",
- "authentication-not-supported": "change-auth",
- "authentication-failed": "change-auth",
- "no-forwarding": "change-auth",
- "unknown-hostkey": "unknown-hostkey",
- "unknown-host": "unknown-host",
- "invalid-hostkey": "invalid-hostkey",
- "no-host": "change-port",
-});
-
-indexes.machines_index(options, machines_inst, loader, dialogs);
-
-var login_data = cockpit.localStorage.getItem('login-data', true);
-if (login_data) {
- var data = JSON.parse(login_data);
- $("#content-user-name").text(data["displayName"]);
-}
diff --git a/pkg/shell/stub.html b/pkg/shell/stub.html
deleted file mode 100644
index e776c0ccd..000000000
--- a/pkg/shell/stub.html
+++ /dev/null
@@ -1,192 +0,0 @@
-
-
-
- Cockpit
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Cockpit is an interactive Linux server admin interface.
-
-
- Version .
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Choose the language to be used in the application
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Reconnect
- Troubleshoot
-
-
-
-
-
-
-
-
-
-
-
diff --git a/po/po.empty.js b/po/po.empty.js
index 9b645f6f7..d284890d5 100644
--- a/po/po.empty.js
+++ b/po/po.empty.js
@@ -13,47 +13,6 @@
loaded = true;
}
- function transformAngular(data, prev) {
- var key, context, parts, value, result = { };
- for (key in data) {
- if (key === "")
- continue;
- parts = key.split("\u0004");
- value = data[key];
- if (parts[1]) {
- context = parts[0];
- key = parts[1];
- } else {
- context = "$$noContext";
- key = parts[0];
- }
- if (value[0] === null)
- value = value[1];
- else
- value = value.slice(1);
- if (!(key in result))
- result[key] = { };
- result[key][context] = value;
- }
- return angular.extend(prev, result);
- }
-
- /* Load into angular here */
- if (typeof angular === 'object') {
- try {
- module = angular.module(["gettext"]);
- } catch(ex) { console.log(ex); /* Either no angular or angular-gettext */ };
- if (module) {
- loaded = true;
- module.run(['gettextCatalog', function(gettextCatalog) {
- var lang = data[""]["language"];
- var prev = (gettextCatalog.getCurrentLanguage() == lang) ? gettextCatalog.strings : { };
- gettextCatalog.setStrings(lang, transformAngular(data, prev));
- gettextCatalog.setCurrentLanguage(lang);
- }]);
- }
- }
-
if (!loaded)
root.po = data;
diff --git a/src/base1/Makefile.am b/src/base1/Makefile.am
index 63066dbdc..337257880 100644
--- a/src/base1/Makefile.am
+++ b/src/base1/Makefile.am
@@ -120,7 +120,6 @@ base_QUNIT_TESTS = \
dist/base1/test-series.html \
dist/base1/test-cache.html \
dist/base1/test-websocket.html \
- dist/base1/test-stub.html \
dist/base1/test-browser-storage.html \
dist/base1/test-promise.html \
dist/base1/test-protocol.html \
diff --git a/src/base1/test-stub.js b/src/base1/test-stub.js
deleted file mode 100644
index 5f50622b8..000000000
--- a/src/base1/test-stub.js
+++ /dev/null
@@ -1,207 +0,0 @@
-/* global $, cockpit, QUnit, WebSocket */
-
-/* Tell cockpit to use an alternate url to connect to test-server */
-window.mock.url = cockpit.transport.uri();
-window.mock.url += "?cockpit-stub";
-
-function internal_test(assert, options) {
- let done = assert.async();
- assert.expect(2);
- var dbus = cockpit.dbus(null, options);
- dbus.call("/", "org.freedesktop.DBus.Introspectable", "Introspect")
- .done(function(resp) {
- assert.ok(String(resp[0]).indexOf(" 0, "unexpected error: " + ex.message);
- assert.ok(ex.message.indexOf("/user") > 0, "unexpected error: " + ex.message);
- })
- .always(function() {
- assert.equal(this.state(), "rejected", "finished successfuly");
- done();
- });
-});
-
-QUnit.test("not supported types", function (assert) {
- let done = assert.async();
- var failures = 7;
- var seen = 0;
- assert.expect(failures);
-
- function failed(ev, ex) {
- assert.equal(ex.problem, "not-supported", "not-supported");
- seen++;
- if (failures == seen)
- done();
- }
-
- var flist = cockpit.channel({ "payload":"fslist1", "path":"/foo" });
- $(flist).on("close", failed);
-
- var fwatch = cockpit.channel({ "payload":"fswatch1", "path":"/foo" });
- $(fwatch).on("close", failed);
-
- var file = cockpit.channel({ "payload":"fsread1", "path":"/foo" });
- $(file).on("close", failed);
-
- var freplace = cockpit.channel({ "payload":"fsreplace1", "path":"/foo" });
- $(freplace).on("close", failed);
-
- var spawn = cockpit.channel({ "payload":"stream", "spawn":["sh", "-c", "echo"] });
- $(spawn).on("close", failed);
-
- var dbus = cockpit.dbus("com.redhat.Cockpit.DBusTests.Test", { "bus": "session" });
- $(dbus).on("close", failed);
-
- var metrics = cockpit.channel({ payload: "metrics1",
- interval: 1000,
- source: "internal" });
- $(metrics).on("close", failed);
-
- window.setTimeout(function () {
- done();
- }, 5000);
-});
-
-QUnit.test("external channel websocket", function (assert) {
- let done = assert.async();
- assert.expect(3);
-
- var query = window.btoa(JSON.stringify({
- payload: "websocket-stream1",
- address: "localhost",
- port: parseInt(window.location.port, 10),
- path: "/cockpit/echosocket/",
- }));
-
- var count = 0;
- var ws = new WebSocket("ws://" + window.location.host + "/cockpit/channel/" +
- cockpit.transport.csrf_token + '?' + query);
- ws.onopen = function() {
- assert.ok(true, "websocket is open");
- ws.send("oh marmalade");
- };
- ws.onerror = function() {
- assert.ok(false, "websocket error");
- };
- ws.onmessage = function(ev) {
- if (count === 0) {
- assert.equal(ev.data, "OH MARMALADE", "got payload");
- ws.send("another test");
- count += 1;
- } else {
- assert.equal(ev.data, "ANOTHER TEST", "got payload again");
- ws.close(1000);
- }
- };
- ws.onclose = function(ev) {
- done();
- };
-});
-
-QUnit.start();
diff --git a/src/bridge/Makefile.am b/src/bridge/Makefile.am
index c13941c4b..ecc1f0e3c 100644
--- a/src/bridge/Makefile.am
+++ b/src/bridge/Makefile.am
@@ -1,55 +1,8 @@
noinst_LIBRARIES += \
- libcockpit-stub.a \
libcockpit-bridge.a \
$(NULL)
-libcockpit_stub_a_SOURCES = \
- src/bridge/cockpitconnect.c \
- src/bridge/cockpitconnect.h \
- src/bridge/cockpitdbuscache.c \
- src/bridge/cockpitdbuscache.h \
- src/bridge/cockpitdbusinternal.h \
- src/bridge/cockpitdbusinternal.c \
- src/bridge/cockpitdbusjson.c \
- src/bridge/cockpitdbusjson.h \
- src/bridge/cockpitdbusprocess.c \
- src/bridge/cockpitdbusmeta.c \
- src/bridge/cockpitdbusmeta.h \
- src/bridge/cockpitdbusrules.c \
- src/bridge/cockpitdbusrules.h \
- src/bridge/cockpitechochannel.c \
- src/bridge/cockpitechochannel.h \
- src/bridge/cockpitpipechannel.c \
- src/bridge/cockpitpipechannel.h \
- src/bridge/cockpithttpstream.c \
- src/bridge/cockpithttpstream.h \
- src/bridge/cockpitinteracttransport.c \
- src/bridge/cockpitinteracttransport.h \
- src/bridge/cockpitpackages.c \
- src/bridge/cockpitpackages.h \
- src/bridge/cockpitpacketchannel.c \
- src/bridge/cockpitpacketchannel.h \
- src/bridge/cockpitpaths.c \
- src/bridge/cockpitpaths.h \
- src/bridge/cockpitpeer.c \
- src/bridge/cockpitpeer.h \
- src/bridge/cockpitnullchannel.c \
- src/bridge/cockpitnullchannel.h \
- src/bridge/cockpitrouter.c \
- src/bridge/cockpitrouter.h \
- src/bridge/cockpitstream.c \
- src/bridge/cockpitstream.h \
- src/bridge/cockpitwebsocketstream.c \
- src/bridge/cockpitwebsocketstream.h \
- $(NULL)
-
-libcockpit_stub_a_CFLAGS = \
- -I$(srcdir)/src/bridge \
- -DG_LOG_DOMAIN=\"cockpit-bridge\" \
- $(COCKPIT_CFLAGS) \
- $(NULL)
-
libcockpit_bridge_METRICS = \
src/bridge/cockpitblocksamples.c \
src/bridge/cockpitblocksamples.h \
@@ -76,19 +29,54 @@ libcockpit_bridge_METRICS = \
libcockpit_bridge_a_SOURCES = \
src/bridge/cockpitconnect.c \
src/bridge/cockpitconnect.h \
+ src/bridge/cockpitdbuscache.c \
+ src/bridge/cockpitdbuscache.h \
+ src/bridge/cockpitdbusinternal.c \
+ src/bridge/cockpitdbusinternal.h \
+ src/bridge/cockpitdbusjson.c \
+ src/bridge/cockpitdbusjson.h \
+ src/bridge/cockpitdbusmachines.c \
+ src/bridge/cockpitdbusmeta.c \
+ src/bridge/cockpitdbusmeta.h \
+ src/bridge/cockpitdbusprocess.c \
+ src/bridge/cockpitdbusrules.c \
+ src/bridge/cockpitdbusrules.h \
src/bridge/cockpitdbussetup.c \
src/bridge/cockpitdbususer.c \
- src/bridge/cockpitdbusmachines.c \
- src/bridge/cockpitpolkitagent.c \
- src/bridge/cockpitpolkitagent.h \
+ src/bridge/cockpitechochannel.c \
+ src/bridge/cockpitechochannel.h \
+ src/bridge/cockpitfslist.c \
+ src/bridge/cockpitfslist.h \
src/bridge/cockpitfsread.c \
src/bridge/cockpitfsread.h \
src/bridge/cockpitfsreplace.c \
src/bridge/cockpitfsreplace.h \
src/bridge/cockpitfswatch.c \
src/bridge/cockpitfswatch.h \
- src/bridge/cockpitfslist.c \
- src/bridge/cockpitfslist.h \
+ src/bridge/cockpithttpstream.c \
+ src/bridge/cockpithttpstream.h \
+ src/bridge/cockpitinteracttransport.c \
+ src/bridge/cockpitinteracttransport.h \
+ src/bridge/cockpitnullchannel.c \
+ src/bridge/cockpitnullchannel.h \
+ src/bridge/cockpitpackages.c \
+ src/bridge/cockpitpackages.h \
+ src/bridge/cockpitpacketchannel.c \
+ src/bridge/cockpitpacketchannel.h \
+ src/bridge/cockpitpaths.c \
+ src/bridge/cockpitpaths.h \
+ src/bridge/cockpitpeer.c \
+ src/bridge/cockpitpeer.h \
+ src/bridge/cockpitpipechannel.c \
+ src/bridge/cockpitpipechannel.h \
+ src/bridge/cockpitpolkitagent.c \
+ src/bridge/cockpitpolkitagent.h \
+ src/bridge/cockpitrouter.c \
+ src/bridge/cockpitrouter.h \
+ src/bridge/cockpitstream.c \
+ src/bridge/cockpitstream.h \
+ src/bridge/cockpitwebsocketstream.c \
+ src/bridge/cockpitwebsocketstream.h \
$(libcockpit_bridge_METRICS) \
$(NULL)
@@ -98,16 +86,8 @@ libcockpit_bridge_a_CFLAGS = \
$(COCKPIT_BRIDGE_CFLAGS) \
$(NULL)
-libcockpit_stub_LIBS = \
- libcockpit-stub.a \
- libcockpit-common.a \
- libwebsocket.a \
- $(COCKPIT_LIBS) \
- $(NULL)
-
libcockpit_bridge_LIBS = \
libcockpit-bridge.a \
- libcockpit-stub.a \
libcockpit-common.a \
libwebsocket.a \
$(COCKPIT_BRIDGE_LIBS) \
@@ -135,16 +115,6 @@ cockpit_askpass_CFLAGS = \
$(NULL)
cockpit_askpass_LDADD = $(libcockpit_bridge_LIBS)
-libexec_PROGRAMS += cockpit-stub
-
-cockpit_stub_SOURCES = src/bridge/stub.c
-cockpit_stub_CFLAGS = \
- -I$(srcdir)/src/bridge \
- -DG_LOG_DOMAIN=\"cockpit-bridge\" \
- $(COCKPIT_CFLAGS) \
- $(NULL)
-cockpit_stub_LDADD = $(libcockpit_stub_LIBS)
-
EXTRA_DIST += \
src/bridge/cockpit.pam.insecure \
$(NULL)
diff --git a/src/bridge/stub.c b/src/bridge/stub.c
deleted file mode 100644
index 4d0c0bf8c..000000000
--- a/src/bridge/stub.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * This file is part of Cockpit.
- *
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * Cockpit is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * Cockpit is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Cockpit; If not, see .
- */
-#include "config.h"
-
-#include "cockpitdbusinternal.h"
-#include "cockpitdbusjson.h"
-#include "cockpitechochannel.h"
-#include "cockpitinteracttransport.h"
-#include "cockpithttpstream.h"
-#include "cockpitnullchannel.h"
-#include "cockpitpackages.h"
-#include "cockpitrouter.h"
-#include "cockpitwebsocketstream.h"
-
-#include "common/cockpittransport.h"
-#include "common/cockpitassets.h"
-#include "common/cockpitchannel.h"
-#include "common/cockpitjson.h"
-#include "common/cockpitlog.h"
-#include "common/cockpitpipetransport.h"
-#include "common/cockpittest.h"
-#include "common/cockpitunixfd.h"
-#include "common/cockpitwebresponse.h"
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-/* This program is meant to be used in place of cockpit-bridge
- * in non-system setting. As such only payloads that make no changes
- * to the system or support their own forms of authentication (ei: http)
- * should be included here.
- */
-
-static CockpitPackages *packages = NULL;
-
-extern gboolean cockpit_dbus_json_allow_external;
-
-static CockpitPayloadType payload_types[] = {
- { "http-stream1", cockpit_http_stream_get_type },
- { "http-stream2", cockpit_http_stream_get_type },
- { "null", cockpit_null_channel_get_type },
- { "echo", cockpit_echo_channel_get_type },
- { "websocket-stream1", cockpit_web_socket_stream_get_type },
- { "dbus-json3", cockpit_dbus_json_get_type },
- { NULL },
-};
-
-static void
-on_closed_set_flag (CockpitTransport *transport,
- const gchar *problem,
- gpointer user_data)
-{
- gboolean *flag = user_data;
- *flag = TRUE;
-}
-
-static void
-send_init_command (CockpitTransport *transport,
- gboolean interactive)
-{
- const gchar *checksum;
- JsonObject *object;
- GBytes *bytes;
-
- object = json_object_new ();
- json_object_set_string_member (object, "command", "init");
- json_object_set_int_member (object, "version", 1);
-
- /*
- * When in interactive mode pretend we received an init
- * message, and don't print one out.
- */
- if (interactive)
- {
- json_object_set_string_member (object, "host", "localhost");
- }
- else
- {
- checksum = cockpit_packages_get_checksum (packages);
- if (checksum)
- json_object_set_string_member (object, "checksum", checksum);
- }
-
- bytes = cockpit_json_write_bytes (object);
- json_object_unref (object);
-
- if (interactive)
- cockpit_transport_emit_recv (transport, NULL, bytes);
- else
- cockpit_transport_send (transport, NULL, bytes);
- g_bytes_unref (bytes);
-}
-
-static gboolean
-on_signal_done (gpointer data)
-{
- gboolean *closed = data;
- *closed = TRUE;
- return TRUE;
-}
-
-static CockpitRouter *
-setup_router (CockpitTransport *transport)
-{
- CockpitRouter *router = NULL;
- GList *bridges = NULL;
-
- packages = cockpit_packages_new ();
- bridges = cockpit_packages_get_bridges (packages);
- router = cockpit_router_new (transport, payload_types, bridges);
- g_list_free (bridges);
- return router;
-}
-
-static int
-run_bridge (const gchar *interactive)
-{
- CockpitTransport *transport;
- CockpitRouter *router;
- gboolean terminated = FALSE;
- gboolean interupted = FALSE;
- gboolean closed = FALSE;
- guint sig_term;
- guint sig_int;
- int outfd;
-
- cockpit_set_journal_logging (G_LOG_DOMAIN, !isatty (2));
-
- /*
- * This process talks on stdin/stdout. However lots of stuff wants to write
- * to stdout, such as g_debug, and uses fd 1 to do that. Reroute fd 1 so that
- * it goes to stderr, and use another fd for stdout.
- */
-
- outfd = dup (1);
- if (outfd < 0 || dup2 (2, 1) < 1)
- {
- g_warning ("bridge couldn't redirect stdout to stderr");
- if (outfd > -1)
- close (outfd);
- outfd = 1;
- }
-
- sig_term = g_unix_signal_add (SIGTERM, on_signal_done, &terminated);
- sig_int = g_unix_signal_add (SIGINT, on_signal_done, &interupted);
-
- cockpit_dbus_json_allow_external = FALSE;
-
- cockpit_dbus_internal_startup (interactive != NULL);
-
- if (interactive)
- {
- transport = cockpit_interact_transport_new (0, outfd, interactive);
- }
- else
- {
- transport = cockpit_pipe_transport_new_fds ("stdio", 0, outfd);
- }
-
- g_resources_register (cockpitassets_get_resource ());
- cockpit_web_failure_resource = "/org/cockpit-project/Cockpit/fail.html";
-
- /* Set a path if nothing is set */
- g_setenv ("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 0);
-
- router = setup_router (transport);
- cockpit_dbus_process_startup ();
-
- g_signal_connect (transport, "closed", G_CALLBACK (on_closed_set_flag), &closed);
- send_init_command (transport, interactive ? TRUE : FALSE);
-
- while (!terminated && !closed && !interupted)
- g_main_context_iteration (NULL, TRUE);
-
- g_object_unref (router);
- g_object_unref (transport);
-
- g_source_remove (sig_term);
- g_source_remove (sig_int);
-
- /* So the caller gets the right signal */
- if (terminated)
- raise (SIGTERM);
-
- return 0;
-}
-
-static void
-print_rules (void)
-{
- CockpitRouter *router = NULL;
- CockpitTransport *transport = cockpit_interact_transport_new (0, 1, "--");
-
- router = setup_router (transport);
-
- cockpit_router_dump_rules (router);
-
- g_object_unref (router);
- g_object_unref (transport);
-}
-
-static void
-print_version (void)
-{
- gint i, offset, len;
-
- g_print ("Version: %s\n", PACKAGE_VERSION);
- g_print ("Protocol: 1\n");
-
- g_print ("Payloads: ");
- offset = 10;
- for (i = 0; payload_types[i].name != NULL; i++)
- {
- len = strlen (payload_types[i].name);
- if (offset + len > 70)
- {
- g_print ("\n");
- offset = 0;
- }
-
- if (offset == 0)
- {
- g_print (" ");
- offset = 4;
- };
-
- g_print ("%s ", payload_types[i].name);
- offset += len + 1;
- }
-}
-
-int
-main (int argc,
- char **argv)
-{
- GOptionContext *context;
- GError *error = NULL;
- int ret;
-
- static gboolean opt_packages = FALSE;
- static gboolean opt_rules = FALSE;
- static gboolean opt_version = FALSE;
- static gchar *opt_interactive = NULL;
-
- static GOptionEntry entries[] = {
- { "interact", 0, 0, G_OPTION_ARG_STRING, &opt_interactive, "Interact with the raw protocol", "boundary" },
- { "packages", 0, 0, G_OPTION_ARG_NONE, &opt_packages, "Show Cockpit package information", NULL },
- { "rules", 0, 0, G_OPTION_ARG_NONE, &opt_rules, "Show Cockpit bridge rules", NULL },
- { "version", 0, 0, G_OPTION_ARG_NONE, &opt_version, "Show Cockpit version information", NULL },
- { NULL }
- };
-
- signal (SIGPIPE, SIG_IGN);
-
- /* Debugging issues during testing */
-#if WITH_DEBUG
- signal (SIGABRT, cockpit_test_signal_backtrace);
- signal (SIGSEGV, cockpit_test_signal_backtrace);
-#endif
-
- g_setenv ("GSETTINGS_BACKEND", "memory", TRUE);
- g_setenv ("GIO_USE_PROXY_RESOLVER", "dummy", TRUE);
- g_setenv ("GIO_USE_VFS", "local", TRUE);
-
- /*
- * All channels that are added here should
- * not rely on running as a real user, however
- * they may lookup paths, such as run dir or
- * home directory. Glib has problems if
- * g_get_user_database_entry is called without
- * a real user, which it's path functions
- * do as a last resort when no environment vars
- * are set. So set HOME if it isn't set..
- */
- g_setenv("HOME", "/", FALSE);
-
-
- context = g_option_context_new (NULL);
- g_option_context_add_main_entries (context, entries, NULL);
- g_option_context_set_description (context,
- "cockpit-stub provides a limited number of channels and is meant to be"
- "used in place of cockpit-bridge in non-system setting. When\n"
- "run from the command line one of the options above must be specified.\n");
-
- g_option_context_parse (context, &argc, &argv, &error);
- g_option_context_free (context);
-
- if (error)
- {
- g_printerr ("cockpit-stub: %s\n", error->message);
- g_error_free (error);
- return 1;
- }
-
- if (opt_packages)
- {
- cockpit_packages_dump ();
- return 0;
- }
- else if (opt_rules)
- {
- print_rules ();
- return 0;
- }
- else if (opt_version)
- {
- print_version ();
- return 0;
- }
-
- if (!opt_interactive && isatty (1))
- {
- g_printerr ("cockpit-stub: no option specified\n");
- return 2;
- }
-
- ret = run_bridge (opt_interactive);
-
- if (packages)
- cockpit_packages_free (packages);
-
- g_free (opt_interactive);
- return ret;
-}
diff --git a/test/common/cdp-driver.js b/test/common/cdp-driver.js
index 47696515b..be45f7bce 100755
--- a/test/common/cdp-driver.js
+++ b/test/common/cdp-driver.js
@@ -91,12 +91,6 @@ function setupLogging(client) {
process.stderr.write(details.description || JSON.stringify(details) + "\n");
- // ignore c3 crashes (https://github.com/c3js/c3/issues/2187)
- if (details.exception && details.exception.description &&
- details.exception.description.indexOf("TypeError: Cannot read property 'data_types' of null") >= 0 &&
- details.exception.description.indexOf("/kubernetes.js") >= 0)
- return;
-
unhandledExceptions.push(details.exception.message ||
details.exception.description ||
details.exception.value ||
diff --git a/test/image-prepare b/test/image-prepare
index cab6a69ea..ce911fa43 100755
--- a/test/image-prepare
+++ b/test/image-prepare
@@ -129,9 +129,7 @@ def run_install_script(machine, do_build, do_install, skips, arg, args):
do_install = False
skips = list(skips or [])
- if "atomic" in machine.image:
- skips.append("cockpit-kubernetes")
- else:
+ if "atomic" not in machine.image:
skips.append("cockpit-ostree")
skip_args = [" --skip '%s'" % skip for skip in skips]
diff --git a/test/verify/check-kubernetes b/test/verify/check-kubernetes
deleted file mode 100755
index 489644a96..000000000
--- a/test/verify/check-kubernetes
+++ /dev/null
@@ -1,282 +0,0 @@
-#!/usr/bin/python3
-# -*- coding: utf-8 -*-
-
-# This file is part of Cockpit.
-#
-# Copyright (C) 2015 Red Hat, Inc.
-#
-# Cockpit is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# Cockpit is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with Cockpit; If not, see .
-
-import unittest
-
-import parent
-
-import kubelib
-from testlib import *
-
-
-@skipImage("No kubernetes packaged", "debian-stable", "debian-testing", "ubuntu-1804",
- "ubuntu-stable", "fedora-i386", "rhel-7-6", "rhel-7-6-distropkg", "rhel-7-7", "rhel-8-0", "rhel-8-0-distropkg", "rhel-8-1", "centos-7")
-@skipImage("No cockpit-kubernetes packaged", "continuous-atomic", "fedora-atomic", "rhel-atomic", "fedora-30", "fedora-testing")
-@skipPackage("cockpit-kubernetes")
-class TestKubernetes(kubelib.KubernetesCase, kubelib.KubernetesCommonTests):
-
- def setUp(self):
- kubelib.KubernetesCase.setUp(self)
- m = self.machine
-
- self.start_kubernetes()
-
- m.upload(["verify/files/mock-k8s-tiny-app.json"], "/tmp")
- self.wait_api_server()
- # HACK: https://github.com/cockpit-project/cockpit/issues/9179 ; fixed
- # in docker-images.setup, drop this after all images got rebuilt
- m.execute("docker tag gcr.io/google_containers/pause-amd64:3.0 k8s.gcr.io/pause-amd64:3.1 || true")
-
-
-@skipImage("No kubernetes packaged", "debian-stable", "debian-testing", "ubuntu-1804",
- "ubuntu-stable", "fedora-i386", "rhel-7-6", "rhel-7-6-distropkg", "rhel-7-7", "rhel-8-0", "rhel-8-0-distropkg", "rhel-8-1", "centos-7")
-@skipImage("No cockpit-kubernetes packaged", "continuous-atomic", "fedora-atomic", "rhel-atomic", "fedora-30", "fedora-testing")
-@skipPackage("cockpit-kubernetes")
-class TestConnection(kubelib.KubernetesCase):
-
- def testConnect(self):
- m = self.machine
- b = self.browser
-
- # Connect without starting a kube server
- self.login_and_go("/kubernetes")
- b.wait_in_text(".curtains-ct", "Couldn't connect to server")
- b.wait_in_text(".curtains-ct", "Couldn't find running API server")
- self.assertIn("Reconnect", b.text("#kubernetes-reconnect"))
-
- # Start a kube-apiserver with a 'wrong' http port, forcing use of https
- m.execute("echo 'KUBE_API_PORT=\"--port=1111\"' >> /etc/kubernetes/apiserver")
- m.execute("sed -i s/8080/1111/g /etc/kubernetes/*")
- self.start_kubernetes()
-
- # Setup the kube stuff in the right place
- m.upload(["verify/files/mock-kube-config-basic.json"], "/tmp")
- m.execute("mkdir -p /home/admin/.kube/ && mv /tmp/mock-kube-config-basic.json /home/admin/.kube/config")
-
- # Click the Reconnect button
- b.click("#kubernetes-reconnect")
- b.wait_in_text("#node-list", "127.0.0.1")
- b.logout()
-
- # Check that this failed as a double check
- output = m.execute("curl -sS http://10.111.113.1:8080/api 2>&1 || true")
- self.assertIn("Connection refused", output)
-
- # Check that this failed as a double check
- output = m.execute("curl -k -sS https://10.111.113.1:6443/api 2>&1 || true")
- self.assertRegex(output, "Unauthorized|No policy matched|Forbidden")
-
- m.execute("rm -r /home/admin/.kube")
- self.login_and_go("/kubernetes")
-
- b.wait_present(".curtains-ct")
- b.click("#kubernetes-connection-tb")
-
- b.wait_present("modal-dialog")
- b.wait_in_text("div.modal-footer div.dialog-error", "Connection Error:")
- b.wait_present("#kubernetes-address")
- b.wait_present("#kubernetes-cluster")
- b.wait_not_present("#kubernetes-user")
-
- b.wait_present("#kubernetes-cluster ul.dropdown-menu")
- b.wait_in_text("#kubernetes-cluster button", "Add New Cluster")
-
- b.click("#kubernetes-requires-auth")
- b.wait_present("#kubernetes-user")
- b.wait_present("#kubernetes-username")
- b.wait_in_text("#kubernetes-user button", "Add New User")
- b.set_val("#kubernetes-address", "")
- b.click("modal-dialog div.modal-footer button.btn-primary")
- b.wait_present("#kubernetes-address + div.dialog-error")
- b.wait_present("#kubernetes-username + div.dialog-error")
-
- b.set_val("#kubernetes-address", "https://10.111.113.1:6443")
- b.set_val("#kubernetes-username", "bad")
- b.set_val("#kubernetes-password", "password")
-
- b.click("modal-dialog div.modal-footer button.btn-primary")
- b.wait_present("modal-dialog input[value='pem']")
- b.wait_present("modal-dialog input[value='skip']")
- b.wait_in_text("modal-dialog pre", "Certificate:")
- b.click("modal-dialog input[value='pem']")
- b.click("modal-dialog div.modal-footer button.btn-primary")
-
- b.wait_present("#kubernetes-address")
- b.wait_present("#kubernetes-user")
- b.wait_in_text("div.modal-footer div.dialog-error", "Connection Error:")
-
- # Data not saved
- b.wait_in_text("#kubernetes-cluster button", "Add New Cluster")
- b.wait_in_text("#kubernetes-user button", "Add New User")
-
- # Form is
- b.wait_val("#kubernetes-address", "https://10.111.113.1:6443")
- b.wait_present("#kubernetes-requires-auth:checked")
- b.wait_val("#kubernetes-username", "bad")
-
- b.set_val("#kubernetes-username", "admin")
- b.set_val("#kubernetes-password", "fubar")
- b.click("modal-dialog div.modal-footer button.btn-primary")
- b.wait_not_present("modal-dialog")
-
- b.wait_in_text("#node-list", "127.0.0.1")
-
- b.wait_not_present("#kubernetes-change-connection")
-
- # Temp certificate isn't saved
- b.reload()
- b.enter_page("/kubernetes")
- b.wait_present(".curtains-ct")
- b.click("#kubernetes-connection-tb")
-
- b.wait_present("modal-dialog input[value='pem']")
- b.click("modal-dialog input[value='skip']")
- b.click("modal-dialog div.modal-footer button.btn-primary")
- b.wait_not_present("modal-dialog")
-
- b.wait_in_text("#node-list", "127.0.0.1")
-
- # Reload works
- b.reload()
- b.enter_page("/kubernetes")
- b.wait_in_text("#node-list", "127.0.0.1")
-
- # Changing works
- b.click("#kubernetes-change-connection")
- b.wait_present("modal-dialog")
- b.wait_present("#kubernetes-cluster")
- b.wait_present("#kubernetes-user")
-
- b.wait_in_text("#kubernetes-cluster button", "10-111-113-1:6443")
- b.wait_in_text("#kubernetes-user button", "admin/10-111-113-1:6443")
-
- b.wait_val("#kubernetes-address", "https://10.111.113.1:6443")
- b.wait_present("#kubernetes-requires-auth:checked")
- b.wait_val("#kubernetes-username", "admin")
- b.wait_present("#kubernetes-skip-verify:checked")
-
- b.set_val("#kubernetes-address", "https://10.111.113.1:6443")
- b.set_val("#kubernetes-username", "scruffy")
- b.set_val("#kubernetes-password", "scruffy")
- b.click("modal-dialog div.modal-footer button.btn-primary")
- b.wait_not_present("modal-dialog")
-
- # Changes took and dropdowns work
- b.click("#kubernetes-change-connection")
- b.wait_present("modal-dialog")
- b.wait_present("#kubernetes-cluster")
- b.wait_present("#kubernetes-user")
-
- b.wait_in_text("#kubernetes-cluster button", "10-111-113-1:6443")
- b.click("#kubernetes-cluster button")
- b.click("#kubernetes-cluster ul li:last-child a")
- b.wait_in_text("#kubernetes-cluster button", "Add New Cluster")
- b.wait_val("#kubernetes-address", "")
- b.wait_present("#kubernetes-skip-verify:not(:checked)")
-
- b.click("#kubernetes-cluster button")
- b.click("#kubernetes-cluster ul li:first-child a")
- b.wait_in_text("#kubernetes-cluster button", "10-111-113-1:6443")
- b.wait_val("#kubernetes-address", "https://10.111.113.1:6443")
- b.wait_present("#kubernetes-requires-auth:checked")
- b.wait_present("#kubernetes-skip-verify:checked")
-
- b.wait_in_text("#kubernetes-user button", "admin/10-111-113-1:6443")
- b.wait_val("#kubernetes-username", "scruffy")
- b.click("#kubernetes-user button")
- b.click("#kubernetes-user ul li:last-child a")
- b.wait_in_text("#kubernetes-user button", "Add New User")
- b.wait_val("#kubernetes-username", "")
- b.wait_val("#kubernetes-password", "")
- b.click("#kubernetes-user button")
- b.click("#kubernetes-user ul li:first-child a")
- b.wait_in_text("#kubernetes-user button", "admin/10-111-113-1:6443")
- b.wait_val("#kubernetes-username", "scruffy")
- b.wait_val("#kubernetes-password", "scruffy")
-
- b.click("modal-dialog div.modal-footer button.btn-cancel")
- b.wait_not_present("modal-dialog")
-
- b.wait_in_text("#node-list", "127.0.0.1")
-
- self.allow_journal_messages(".*: couldn't connect: Connection refused",
- ".*: Unacceptable TLS certificate.*",
- ".*: Connection reset by peer.*",
- "connection unexpectedly closed by peer",
- ".*: Error sending data: Broken pipe.*")
-
-
-@skipImage("No kubernetes packaged", "debian-stable", "debian-testing", "ubuntu-1804",
- "ubuntu-stable", "fedora-i386", "rhel-7-6", "rhel-7-6-distropkg", "rhel-7-7", "rhel-8-0", "rhel-8-0-distropkg", "rhel-8-1", "centos-7")
-@unittest.skipIf(True, "Nulecule deploys temporarily removed.")
-@skipPackage("cockpit-kubernetes")
-class TestNulecule(kubelib.KubernetesCase):
-
- def setUp(self):
- kubelib.KubernetesCase.setUp(self)
-
- self.start_kubernetes()
- self.wait_api_server()
-
- def testDeployDialog(self):
- b = self.browser
- m = self.machine
-
- self.login_and_go("/kubernetes")
- b.wait_in_text("#node-list", "127.0.0.1")
-
- # 1)check atomic version
- output = m.execute("atomic -v 2>&1")
- self.assertTrue(float(output) >= 1.1)
-
- # 2) fail invalid image
- b.click("#deploy-app")
- b.wait_popup("deploy-app-dialog")
- b.set_val("#deploy-app-type", "nulecule")
- b.set_val("#deploy-app-nulecule-image", "submod/helloapache1")
- b.set_val("#deploy-app-namespace", "mynamespace")
- b.dialog_complete("#deploy-app-dialog", result="fail")
- b.dialog_cancel("#deploy-app-dialog")
-
- # 3) pass when valid image
- b.click("#deploy-app")
- b.wait_popup("deploy-app-dialog")
- b.set_val("#deploy-app-type", "nulecule")
- b.set_val("#deploy-app-nulecule-image", "submod/helloapache:0.1.11")
- b.set_val("#deploy-app-namespace", "mynamespace")
- b.click("#deploy-app-start")
- self.allow_journal_messages('Could not find any image matching "submod/helloapache:0.1.11".')
- b.wait_not_attr("#deploy-app-start", "disabled", "disabled")
- b.dialog_cancel("#deploy-app-dialog")
-
- # 4) fail when atomic is not installed
- m.needs_writable_usr()
- m.execute("rm /usr/bin/atomic")
- b.click("#deploy-app")
- b.wait_popup("deploy-app-dialog")
- b.set_val("#deploy-app-type", "nulecule")
- b.set_val("#deploy-app-nulecule-image", "submod/helloapache")
- b.set_val("#deploy-app-namespace", "mynamespace")
- b.dialog_complete("#deploy-app-dialog", result="fail")
- b.dialog_cancel("#deploy-app-dialog")
-
-
-if __name__ == '__main__':
- test_main()
diff --git a/test/verify/check-openshift b/test/verify/check-openshift
deleted file mode 100755
index 232188b4f..000000000
--- a/test/verify/check-openshift
+++ /dev/null
@@ -1,401 +0,0 @@
-#!/usr/bin/python3
-# -*- coding: utf-8 -*-
-
-# This file is part of Cockpit.
-#
-# Copyright (C) 2015 Red Hat, Inc.
-#
-# Cockpit is free software; you can redistribute it and/or modify it
-# under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation; either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# Cockpit is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with Cockpit; If not, see .
-
-import os
-import unittest
-
-import parent
-from kubelib import *
-from testlib import *
-
-
-# NOTE: Both TestOpenshift and TestRegistry are in this single file to
-# prevent them from being run concurrently. Both use a 'openshift'
-# machine, and we can only run a single one of those at the same time.
-
-base_dir = os.path.dirname(os.path.realpath(__file__))
-
-
-def wait_healthz(openshift):
- # Openshift prints "ok" on /healthz/ready when it's ready
- healthz = "curl -sk --stderr - https://localhost:8443/healthz/ready || true"
- wait(lambda: "ok" == openshift.execute(healthz), delay=5, tries=150)
-
-
-@skipImage("Kubernetes not packaged", "debian-stable", "debian-testing", "ubuntu-1804", "ubuntu-stable", "fedora-i386")
-@skipImage("No cockpit-kubernetes packaged", "continuous-atomic", "fedora-atomic", "rhel-atomic", "rhel-8-0", "rhel-8-0-distropkg", "rhel-8-1", "fedora-30", "fedora-testing")
-class TestOpenshift(MachineCase, OpenshiftCommonTests):
- provision = {
- "machine1": {"address": "10.111.113.1/20"},
- "openshift": {"image": "openshift", "forward": {30000: 30000, 8443: 8443}}
- }
-
- def setUp(self):
- super(TestOpenshift, self).setUp()
-
- self.openshift = self.machines['openshift']
- self.openshift.upload(["verify/files/mock-app-openshift.json"], "/tmp")
- self.kubeconfig = os.path.join(self.tmpdir, "config")
- self.openshift.download("/root/.kube/config", self.kubeconfig)
-
- m = self.machine
- m.execute("mkdir -p /home/admin/.kube")
- m.upload([self.kubeconfig], "/home/admin/.kube/config")
- m.execute("chown -R admin:admin /home/admin/.kube")
-
- wait_healthz(self.openshift)
- wait(lambda: "marmalade" in self.openshift.execute("oc get projects"), delay=5)
-
- self.openshift.execute("oc project default")
-
- # Expect the default container user limitations during testing
- self.openshift.execute(
- "oc patch securitycontextconstraints restricted -p '{ \"runAsUser\": { \"type\": \"MustRunAsRange\" } }'")
-
- self.browser.wait_timeout(120)
-
- # This happens with docker restarts and during startup polling
- self.allow_journal_messages('.*received truncated HTTP response.*')
- self.allow_journal_messages(".*api/.*couldn't connect.*")
-
- def testConnect(self):
- m = self.machine
- b = self.browser
-
- # Make sure we can write to kubeconfig
- m.execute("chown -R admin:admin /home/admin/.kube")
- self.login_and_go("/kubernetes")
-
- b.wait_in_text("#service-list", "docker-registry")
- b.click("a[href='#/volumes']")
- b.wait_in_text(".pv-listing", "No volumes are present")
- b.click("a[href='#/']")
-
- b.click("#kubernetes-change-connection")
- b.wait_present("modal-dialog")
- b.wait_present("#kubernetes-cluster")
- b.wait_not_present("#kubernetes-username")
- b.wait_not_present("#kubernetes-password")
- b.wait_not_present("#kubernetes-token")
-
- b.wait_in_text("#kubernetes-cluster button", "10-111-112-101:8443")
- b.wait_in_text("#kubernetes-user button", "system:admin/10-111-112-101:8443")
- b.wait_in_text("modal-dialog .modal-body", "Client Certificate")
-
- b.click("#kubernetes-user button")
- b.click("#kubernetes-user ul li:last-child a")
- b.wait_in_text("#kubernetes-user button", "Add New User")
- b.wait_not_present("#kubernetes-token")
- b.wait_val("#kubernetes-username", "")
- b.wait_val("#kubernetes-password", "")
- b.set_val("#kubernetes-username", "new-user")
- b.set_val("#kubernetes-password", "new-user")
-
- b.click("modal-dialog div.modal-footer button.btn-primary")
- b.wait_not_present("modal-dialog")
-
- # scruffy isn't a admin
- b.wait_not_in_text("#service-list", "docker-registry")
- b.click("a[href='#/volumes']")
- b.wait_in_text(".pv-listing", "cannot watch all")
- b.click("a[href='#/']")
-
- b.click("#kubernetes-change-connection")
- b.wait_present("modal-dialog")
- b.wait_present("#kubernetes-cluster")
- b.wait_not_present("#kubernetes-username")
- b.wait_not_present("#kubernetes-password")
- b.wait_present("#kubernetes-token")
-
- b.wait_in_text("#kubernetes-cluster button", "10-111-112-101:8443")
- b.wait_in_text("#kubernetes-user button", "new-user/10-111-112-101:8443")
- b.wait_not_in_text("modal-dialog .modal-body", "Client Certificate")
- self.assertFalse(b.val("#kubernetes-token") == "")
-
- b.logout()
-
- # Test the saved kube config file
- m.execute("rm /home/admin/.kube/config")
- m.upload([self.kubeconfig], "/home/admin/.kube/config")
- m.execute("chown -R admin:admin /home/admin/.kube")
-
- self.login_and_go("/kubernetes")
-
- b.wait_in_text("#service-list", "docker-registry")
-
- @unittest.skipIf(True, "Nulecule deploys temporarily removed.")
- def testDeployDialog(self):
- b = self.browser
- m = self.machine
- b.wait_timeout(240)
- m.execute("systemctl start docker")
- # m.execute("docker pull submod/helloapache")
- tmpfile = os.path.join(self.tmpdir, "oc")
- self.openshift.download("/usr/bin/oc", tmpfile)
- m.upload([tmpfile], "/usr/local/bin")
-
- self.login_and_go("/kubernetes")
- b.wait_in_text("#service-list", "registry")
-
- # 1)check atomic version
- output = m.execute("atomic -v 2>&1")
- self.assertTrue(float(output) >= 1.1)
-
- # 2)check provider is supported
- m.execute("mkdir /var/tmp/invalid-app1")
- m.execute("""echo -e '
-FROM busybox
-MAINTAINER cockpit
-LABEL io.projectatomic.nulecule.atomicappversion="0.1.11" \
- RUN="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run -v /:/host --net=host --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} run \${OPT3} /atomicapp" \
- STOP="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run -v /:/host --net=host --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} stop \${OPT3} /atomicapp" \
- INSTALL="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} install \${OPT3} --destination /atomicapp /application-entity" \
- io.projectatomic.nulecule.providers="kubernetes" \
- io.projectatomic.nulecule.specversion=0.0.2 \
- io.projectatomic.nulecule.atomicappversion="0.1.11"
-' > /var/tmp/invalid-app1/Dockerfile""")
- m.execute("docker build -t test/invalid-app1 /var/tmp/invalid-app1")
- m.execute("rm -rf /var/tmp/invalid-app1")
-
- b.click("#deploy-app")
- b.wait_popup("deploy-app-dialog")
- b.set_val("#deploy-app-type", "nulecule")
- b.set_val("#deploy-app-nulecule-image", "test/invalid-app1")
- b.set_val("#deploy-app-namespace", "mynamespace")
- b.click("#deploy-app-start")
- b.wait_not_attr("#deploy-app-start", "disabled", "disabled")
- b.is_visible(".modal-footer .alert")
- self.assertEqual(b.text(".modal-footer .alert"), "No supported providers found.")
- b.dialog_cancel("#deploy-app-dialog")
-
- # 3)check atomicappversion is supported
- m.execute("mkdir /var/tmp/invalid-app2")
- m.execute("""echo -e '
-FROM busybox
-MAINTAINER cockpit
-LABEL io.projectatomic.nulecule.atomicappversion="0.1.11" \
- RUN="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run -v /:/host --net=host --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} run \${OPT3} /atomicapp" \
- STOP="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run -v /:/host --net=host --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} stop \${OPT3} /atomicapp" \
- INSTALL="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} install \${OPT3} --destination /atomicapp /application-entity" \
- io.projectatomic.nulecule.providers="kubernetes,openshift" \
- io.projectatomic.nulecule.specversion=0.0.2 \
- io.projectatomic.nulecule.atomicappversion="0.0.11"
-' > /var/tmp/invalid-app2/Dockerfile""")
- m.execute("docker build -t test/invalid-app2 /var/tmp/invalid-app2")
- m.execute("rm -rf /var/tmp/invalid-app2")
-
- b.click("#deploy-app")
- b.wait_popup("deploy-app-dialog")
- b.set_val("#deploy-app-type", "nulecule")
- b.set_val("#deploy-app-nulecule-image", "test/invalid-app2")
- b.set_val("#deploy-app-namespace", "mynamespace")
- b.click("#deploy-app-start")
- b.wait_not_attr("#deploy-app-start", "disabled", "disabled")
- b.is_visible(".modal-footer .alert")
- self.assertEqual(b.text(".modal-footer .alert"), "atomicapp version 0.0.11 is not supported.")
- b.dialog_cancel("#deploy-app-dialog")
-
- # 5)check for all metadata
- m.execute("mkdir /var/tmp/invalid-app4")
- m.execute("""echo -e '
-FROM busybox
-MAINTAINER cockpit
-LABEL io.projectatomic.nulecule.providers="kubernetes,openshift"
-' > /var/tmp/invalid-app4/Dockerfile""")
- m.execute("docker build -t test/invalid-app4 /var/tmp/invalid-app4")
- m.execute("rm -rf /var/tmp/invalid-app4")
-
- b.click("#deploy-app")
- b.wait_popup("deploy-app-dialog")
- b.set_val("#deploy-app-type", "nulecule")
- b.set_val("#deploy-app-nulecule-image", "test/invalid-app4")
- b.set_val("#deploy-app-namespace", "mynamespace")
- b.click("#deploy-app-start")
- b.wait_not_attr("#deploy-app-start", "disabled", "disabled")
- b.is_visible(".modal-footer .alert")
- self.assertEqual(b.text(".modal-footer .alert"), "This image is not a supported Nulecule image")
- b.dialog_cancel("#deploy-app-dialog")
-
- # 6)check when atomicapp is not available
- m.execute("mkdir /var/tmp/invalid-app5")
- m.execute("""echo -e '
-FROM busybox
-MAINTAINER cockpit
-LABEL io.projectatomic.nulecule.atomicappversion="0.1.11" \
- RUN="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run -v /:/host --net=host --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} run \${OPT3} /atomicapp" \
- STOP="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run -v /:/host --net=host --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} stop \${OPT3} /atomicapp" \
- INSTALL="docker run -it --rm \${OPT1} --privileged -v `pwd`:/atomicapp -v /run:/run --name \${NAME} -e NAME=\${NAME} -e IMAGE=\${IMAGE} \${IMAGE} -v \${OPT2} install \${OPT3} --destination /atomicapp /application-entity" \
- io.projectatomic.nulecule.providers="kubernetes,openshift" \
- io.projectatomic.nulecule.specversion=0.0.2 \
- io.projectatomic.nulecule.atomicappversion="0.1.11"
-' > /var/tmp/invalid-app5/Dockerfile""")
- m.execute("docker build -t test/invalid-app5 /var/tmp/invalid-app5")
- m.execute("rm -rf /var/tmp/invalid-app5")
-
- b.click("#deploy-app")
- b.wait_popup("deploy-app-dialog")
- b.set_val("#deploy-app-type", "nulecule")
- b.set_val("#deploy-app-nulecule-image", "test/invalid-app5")
- b.set_val("#deploy-app-namespace", "mynamespace")
- b.click("#deploy-app-start")
- b.wait_not_attr("#deploy-app-start", "disabled", "disabled")
- b.is_visible(".modal-footer .alert")
- self.assertEqual(b.text(".modal-footer .alert"), "Image failed to install.")
- b.dialog_cancel("#deploy-app-dialog")
-
- # 7) fail when Unable to pull Nulecule app
- b.click("#deploy-app")
- b.wait_popup("deploy-app-dialog")
- b.set_val("#deploy-app-type", "nulecule")
- b.set_val("#deploy-app-nulecule-image", "submod/helloapache1")
- b.set_val("#deploy-app-namespace", "mynamespace")
- b.click("#deploy-app-start")
- b.wait_not_attr("#deploy-app-start", "disabled", "disabled")
- b.is_visible(".modal-footer .alert")
- self.assertEqual(b.text(".modal-footer .alert"), "Unable to pull Nulecule app image.")
- b.dialog_cancel("#deploy-app-dialog")
-
- # 8) check if app can be deployed
- b.click("#deploy-app")
- b.wait_popup("deploy-app-dialog")
- b.set_val("#deploy-app-type", "nulecule")
- b.set_val("#deploy-app-nulecule-image", "submod/helloapache:0.1.11")
- b.set_val("#deploy-app-namespace", "mynamespace")
- b.click("#deploy-app-start")
- self.allow_journal_messages('Could not find any image matching "submod/helloapache:0.1.11".')
- b.wait_not_attr("#deploy-app-start", "disabled", "disabled")
- b.click("#deploy-app-start")
- b.wait_popdown("deploy-app-dialog")
- b.click("a[href='#/list']")
- b.wait_present("#content .details-listing")
- b.wait_present(".details-listing tbody[data-id='pods/default/helloapache'] th")
- self.assertEqual(b.text(".details-listing tbody[data-id='pods/default/helloapache'] th"), "helloapache")
-
- def testReconnectChangeCert(self):
- m = self.machine
- b = self.browser
-
- # Try to connect with an old and non-matching client cert
- old_cert = ('LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUREVENDQWZXZ0F3SUJBZ0lCQnpBTkJna3Foa2'
- 'lHOXcwQkFRc0ZBREFtTVNRd0lnWURWUVFEREJ0dmNHVnUKYzJocFpuUXRjMmxuYm1WeVFERTBPVEEy'
- 'T0RFMk16RXdIaGNOTVRjd016STRNRFl4TXpVeVdoY05NVGt3TXpJNApNRFl4TXpVeldqQTNNUjR3SE'
- 'FZRFZRUUtFeFZ6ZVhOMFpXMDZZMngxYzNSbGNpMWhaRzFwYm5NeEZUQVRCZ05WCkJBTVRESE41YzNS'
- 'bGJUcGhaRzFwYmpDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUIKQU5Rel'
- 'J5SzUzQUhmdlZnME5GTHRSSENhMTEyK3l5a0xXdG14bjAxb2JTMy85VmovQU1UdmZwNVRkUlhKNjF'
- 'WcAo3L0N1L1pkQ3RDc1pyNnJpYVMxbUJGcmtTSkZJdmFjN2NNa3k2M0tVVXNaQmU5ZGFLdG1OMmhY'
- 'TUt0VitESStvCjJFQVJNWlV5YTZIMzJXZUpzRGM0L1lscUR5TFAxYVR3NWNwRTJPY3dWQTdoQ1dCS'
- 'ysyajIvZTl6RDhrYzM2R24KNG0wZWd3YWxlZ2UwTXFaUk1BbTFkenRpS3I1UWZ4MG9ZVUY3Z0JIYm'
- 'RjM253cGZ6a3M2K1F4Tkl6V0hlRmN2WApxcXpsMGxnT2ZGeWc0VWptYzhFcTBiKy9ER3lYSGlHNXN'
- 'vVmw1RGlVa1RKRjNrcURCZVVjZWNZaEx1VDd4emxzClk0bldYVFprc3lJMXVoZFJmS2NnbVZjQ0F3'
- 'RUFBYU0xTURNd0RnWURWUjBQQVFIL0JBUURBZ1dnTUJNR0ExVWQKSlFRTU1Bb0dDQ3NHQVFVRkJ3T'
- 'UNNQXdHQTFVZEV3RUIvd1FDTUFBd0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBRy9rTElnQ2YwK2'
- '1MZ1VXcWZjS2NLN0Nmdm9PbS9qL0FUSW1MR0YvSUtvQTRCWGhqMG5EcEszeVd3ZGt4d0hZCmxxUDh'
- 'xZ1NyQ1FaNkVoSlpMSWtjQWovTUlTUEUvSlJPa3R5TWFTMis4OGhqeGpxdUhucnZ5ODA5ZlJ5QzhF'
- 'R2kKeVIyRzhtNGJ5MEJrOWhENkVxbDYxb21VU0MzL2ozR3lPUGNZWDJEQjZsU2h4ZlFJVEpqUWNKQ'
- '0oyMnNDdlBBOApVeU9EaUgrNllZSVdtVFN5a2kzazk0Q3NOZXlRbERjNzh3a1BseUdrN0p1anFIK2p'
- 'KaURXSDQ2TXE3TTNaVVArCmowQWxhd3dtdllsRjBVZEIwdGRCenZWR21RbTRudEwwSkhVMGFqRnUy'
- 'QTYvTjJmT3VrZWI0TDR6elBzSkJFNHIKaUUyNWRJUlAvWHRoM0tjRFYyYkxtMUk9Ci0tLS0tRU5EI'
- 'ENFUlRJRklDQVRFLS0tLS0K')
- old_key = ('LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBMUROSElybmNBZC'
- 's5V0RRMFV1MUVjSnJYWGI3TEtRdGEyYkdmVFdodExmLzFXUDhBCnhPOStubE4xRmNuclZXbnY4Szc5'
- 'bDBLMEt4bXZxdUpwTFdZRVd1UklrVWk5cHp0d3lUTHJjcFJTeGtGNzExb3EKMlkzYUZjd3ExWDRNa'
- 'jZqWVFCRXhsVEpyb2ZmWlo0bXdOemo5aVdvUElzL1ZwUERseWtUWTV6QlVEdUVKWUVyNwphUGI5Nz'
- 'NNUHlSemZvYWZpYlI2REJxVjZCN1F5cGxFd0NiVjNPMklxdmxCL0hTaGhRWHVBRWR0MXplZkNsL09'
- 'TCnpyNURFMGpOWWQ0Vnk5ZXFyT1hTV0E1OFhLRGhTT1p6d1NyUnY3OE1iSmNlSWJteWhXWGtPSlNS'
- 'TWtYZVNvTUYKNVJ4NXhpRXU1UHZIT1d4amlkWmRObVN6SWpXNkYxRjhweUNaVndJREFRQUJBb0lCQ'
- 'UNxbjNDYlk0YWJteVBNUQpHMnlJRVhmcFNGMnAyc0QzYlYzUlhNcDhzV1hMekJBRndxdlQwTW9XME'
- 'xSK2tIWHRBN1NJR0tYdFhMWkZSWkMrClRwSTNyYXh2c3o2eE5wNkZUbGpEaVp6UXdBcm1ZdlNaUlg'
- 'vU0NnTFR0ZENRdEFtMDBUT2Z3UzNTb3R3K0xFK3AKMStoaDVtVlhFby9XNDRWeWYxNjNsRHAwOXBD'
- 'K3dpS0ZEa2JHVExBdnA1bnFaMnhtZDRyNzhyMi9TZmZ2YUplZQpJSlpwbENMYzMyQkVZaE4yeDRIa'
- 'HpqQkhOdTJwYkFXS2twUDVjWkZNS3QwSUkrRTN0UUNWMlkrYVZvNTY0TzRGCjZxMmFUUzVxMnRuaW'
- 'VBTS9uay8zN3hkNUVoNjRpMU8vQTU2YzdoZmxkMDVQMC9PdU9OY2dsaVVYRG44cnFvOUoKdXpFQ1F'
- 'ORUNnWUVBN0xOeWRQQlhkdEZRZ3NrWG56UlVYM3hhYWFCYU8xYnJYZzVmUnlMVm5DY2thWlRORXlE'
- 'dAp3eURxSGRUOGtRNXNIcXZ3WDNxNXR1elZBZ3NJUlhvcTZIUGtxRWdLeFZIclhTNzY1OFhLUnR1S'
- 'GswbE11ZkQxCnVPVVBaTTJYNVR4NXRmTmh1Zlh3dXZqTkdyN0E3ZEw4VUFiY3ZtS2VuSnF2bDNJZX'
- 'I0cVpkdDBDZ1lFQTVZQncKZ2pNTGJRZStEUzd1QmdsOFVmdGl5YnZCbDdTSEQ4T2RWamVOdzNEZjJ'
- 'uckltQVdLTVhNTk5GWldwbmhhc0g3Swp1bWtMQWdMNWFEWXJhaFJHN2ZwMGd0YnN0RVE5Uit2dFVp'
- 'azMxaFNHUS83dFBENU1LaU1jcFpnazhYUXI5UnlFCkVEN285bWFvUEZibnJKbFl5VXNQY0FCN3Y1W'
- 'FNxaVdqeFZMODI4TUNnWUVBNUhoSk1DcVVvZkZqL3ZsUFBiSnIKQmtlbmxYRGI1NDc4WEtzT3VFRW'
- 'RZajQ5M1ZOdHB0c1A1RnF1MytDbmNQUTAxRjR1QkZzWFMwUEtUdENMU1ZTawplZjd6WktNMUVrVUN'
- 'JODJuRFhSU3pKWTFoS3NwemdpUmhjaERWWTlFNEZYQlBTa1EyVWhVOW9RVXBZNGQ5dkRCCjdoVFJt'
- 'VXJqd2xGa3o0K3RvczdyVmxrQ2dZRUF4RW8vY0V5aVNDV29HblI2Sm5XMGZCWUxuMGxVUWlHb3B3W'
- 'UQKS3Z1bTUzTkNNd1p6VFByb0FIVkw1T2kzZ2ZoTWNNcHhNRkNwbHBYZXBaQTNQNnFLSS83ajZnaF'
- 'RPYmRueG56MgpaU0JWM21kOWt1aVdGY0dldVNlQTErMHlJOFhkMXU0RjBqTk1ZM3JZQjR1NDZQbmJ'
- 'ZNGNzYy9vbDNXNFNXVzZLCkRUcDJoS3NDZ1lCSlpMQys3Uy9zRGVqdkl0MTZ2Q3JzbDJlWlFsb1p0'
- 'clNoVCtTb0hmR1NPRXZkMXp1NStBL3UKaVVDYyt1SHdUa1c0RVpMTEdBYkUzTG1xSllJcXNkNVpUW'
- 'UkxWTZ1TGoyV1NGWFZYUXVLanVlTDZJdGttc1dvZgpyMHFtQU93RHdFVDFvRXlNVUJoOTJVMmhxSHR'
- 'aamlMdkxQdDc5aUhacDNtTnlLVjc5QXY3dVE9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=')
-
- m.execute("sed -i '/client-certificate-data:/ s/:.*$/: %s/; /client-key-data:/ s/:.*$/: %s/' /home/admin/.kube/config" % (
- old_cert, old_key))
- m.execute("chown -R admin:admin /home/admin/.kube")
- self.login_and_go("/kubernetes")
-
- b.wait_in_text(".curtains-ct", "Couldn't connect to server")
- b.wait_in_text(".curtains-ct", "Unauthorized")
- b.wait_present(".curtains-ct #kubernetes-reconnect")
-
- # now provide a good certificate, and reconnect
- m.upload([self.kubeconfig], "/home/admin/.kube/config")
- m.execute("chown -R admin:admin /home/admin/.kube")
-
- b.click("#kubernetes-reconnect")
- b.wait_present("#service-list")
-
-
-@skipImage("Kubernetes not packaged", "debian-stable", "debian-testing", "ubuntu-1804", "ubuntu-stable", "fedora-i386")
-@skipImage("No cockpit-kubernetes packaged", "continuous-atomic", "fedora-atomic", "rhel-atomic", "rhel-8-0", "rhel-8-0-distropkg", "rhel-8-1", "fedora-30", "fedora-testing")
-class TestRegistry(MachineCase, RegistryTests):
- provision = {
- "machine1": {"address": "10.111.113.1/20"},
- "openshift": {"image": "openshift"}
- }
- registry_root = "/kubernetes/registry"
-
- def setup_user(self, user, password):
- tmpfile = os.path.join(self.tmpdir, "kubeconfig")
- self.openshift.execute('printf "{0}\r\n{1}\r\n" | oc login'.format(user, password))
- self.openshift.download("/root/.kube/config", tmpfile)
- with open(tmpfile, "r") as f:
- self.machine.execute("mkdir -p /home/admin/.kube && cat > /home/admin/.kube/config", input=f.read())
-
- def setUp(self):
- super(TestRegistry, self).setUp()
-
- self.openshift = self.machines['openshift']
-
- # Sync over the kube config file
- tmpfile = os.path.join(self.tmpdir, "config")
- self.openshift.download("/root/.kube/config", tmpfile)
- with open(tmpfile, "r") as f:
- self.machine.execute("mkdir -p /home/admin/.kube && cat > /home/admin/.kube/config", input=f.read())
- wait_healthz(self.openshift)
- wait(lambda: "marmalade" in self.openshift.execute("oc get projects"), delay=5)
- self.openshift.execute("oc project default")
-
- self.browser.wait_timeout(120)
-
- # This happens with docker restarts and during startup polling
- self.allow_journal_messages('.*received truncated HTTP response.*')
- self.allow_journal_messages(".*/api.*couldn't connect.*")
-
-
-if __name__ == '__main__':
- test_main()
diff --git a/test/verify/check-pages b/test/verify/check-pages
index d2afab3f3..9c7849efb 100755
--- a/test/verify/check-pages
+++ b/test/verify/check-pages
@@ -206,11 +206,6 @@ OnCalendar=daily
self.assertEqual(b.text("#ngettext-context-disks-1"), u"$0 Datenträger fehlt")
self.assertEqual(b.text("#ngettext-context-disks-2"), u"$0 Datenträger fehlen")
- # Angular
- self.assertEqual(b.text("#angular-translate"), "Bereit")
- self.assertEqual(b.text("#angular-context"), "Bereiten")
- self.assertEqual(b.text("#angular-interpolate"), u"'Marmalade' löschen!!!")
-
# Log out and check that login page is translated now
b.logout()
b.wait_visible('#password-group')
@@ -353,11 +348,6 @@ OnCalendar=daily
self.assertEqual(b.text('#ngettext-context-disks-1'), u'$0 disco não encontrado')
self.assertEqual(b.text('#ngettext-context-disks-2'), u'$0 discos não encontrados')
- # Angular
- self.assertEqual(b.text('#angular-translate'), 'Pronto')
- self.assertEqual(b.text('#angular-context'), 'Pronto')
- self.assertEqual(b.text('#angular-interpolate'), 'Deletar \'Marmalade\'')
-
# Log out and check that login page is translated now
b.logout()
b.wait_text('#password-group > label', 'Senha')
diff --git a/test/verify/files/embed-cockpit.html b/test/verify/files/embed-cockpit.html
index 50423f643..a8e54a5a9 100644
--- a/test/verify/files/embed-cockpit.html
+++ b/test/verify/files/embed-cockpit.html
@@ -102,19 +102,6 @@
-