Skip to content
This repository was archived by the owner on Jan 27, 2021. It is now read-only.

Commit d3688f4

Browse files
committed
migrated repository from hackathon repo
0 parents  commit d3688f4

11 files changed

+1850
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

.gitmodules

Whitespace-only changes.

PortManager.js

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// ========================================================================
2+
// Copyright 2014 Microsoft Corporation
3+
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
// ========================================================================
16+
17+
var PortManager = (function(){
18+
function PortManager(numMinions) {
19+
this._numMinions = numMinions;
20+
this._nextPort = 1024;
21+
this.Reset();
22+
}
23+
24+
PortManager.prototype._computeNextPort = function() {
25+
var port = this._nextPort;
26+
27+
while(port in this._ports && this._ports[port] >= this._numMinions) {
28+
port++;
29+
}
30+
31+
this._nextPort = port;
32+
33+
if (!(this._nextPort in this._ports)) {
34+
this._ports[this._nextPort] = 0;
35+
}
36+
};
37+
38+
PortManager.prototype.AddUsedPort = function (port) {
39+
if (port in this._ports) {
40+
this._ports[port]++;
41+
} else {
42+
this._ports[port] = 1;
43+
}
44+
45+
if (this._nextPort === port && this._ports[port] === this._numMinions) {
46+
this._computeNextPort();
47+
}
48+
}
49+
50+
PortManager.prototype.NextPort = function(numReplicas) {
51+
if (typeof numReplicas != 'number') {
52+
numReplicas = 1;
53+
}
54+
55+
if (numReplicas > this._numMinions) {
56+
console.error("PortManager Error: cannot get more of a single port than there are minions");
57+
return null;
58+
}
59+
60+
var returnPort = this._nextPort;
61+
62+
while((typeof this._ports[returnPort] !== 'undefined') && (numReplicas + this._ports[returnPort]) > this._numMinions) {
63+
returnPort += 1;
64+
}
65+
66+
if (typeof this._ports[returnPort] === 'undefined') {
67+
this._ports[returnPort] = numReplicas;
68+
} else {
69+
this._ports[returnPort] += numReplicas;
70+
}
71+
72+
this._computeNextPort();
73+
74+
return returnPort;
75+
}
76+
77+
PortManager.prototype.PortAvailable = function(port, count) {
78+
return (count <= this._numMinions) &&
79+
(
80+
(typeof this._ports[port] === 'undefined') ||
81+
(this._ports[port] + count <= this._numMinions)
82+
);
83+
}
84+
85+
PortManager.prototype.Reset = function() {
86+
this._ports = {};
87+
}
88+
89+
return PortManager;
90+
})();
91+
92+
module.exports = { 'PortManager': PortManager };

QueuedConnection.js

+183
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
// ========================================================================
2+
// Copyright 2014 Microsoft Corporation
3+
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
// ========================================================================
16+
17+
var EventEmitter = require('events').EventEmitter
18+
var https = require('https');
19+
20+
var QueuedConnection = (function(_super){
21+
function QueuedConnection(requestOptions, requestHandler, responseHandler) {
22+
// _super.call(this);
23+
24+
this._options = requestOptions;
25+
this._requestHandler = requestHandler;
26+
this._responseHandler = responseHandler;
27+
28+
return this;
29+
}
30+
31+
QueuedConnection.prototype = Object.create(_super.prototype);
32+
33+
QueuedConnection.prototype.DoConnection = function() {
34+
var req = https.request(this._options, this._responseHandler);
35+
req.on('close', _connectionCompleteHandler(this));
36+
this._requestHandler.call(this, req);
37+
}
38+
39+
function _connectionCompleteHandler(obj) {
40+
return function() {
41+
obj.emit('complete', obj);
42+
};
43+
}
44+
45+
return QueuedConnection;
46+
})(EventEmitter);
47+
48+
var QueuedConnectionManager = (function(){
49+
function QueuedConnectionManager(options) {
50+
this._connectionQueue = [];
51+
this._activeConnection = null;
52+
53+
this._connectionOptions = options;
54+
}
55+
56+
QueuedConnectionManager.prototype.QueueConnection = function (requestOptions, requestHandler, responseHandler) {
57+
var connection = new QueuedConnection(requestOptions, requestHandler, responseHandler);
58+
59+
connection.on('complete', _connectionCompleteHandler(this));
60+
61+
if (this._activeConnection == null) {
62+
// No need to queue, do this connection immediately
63+
this._activeConnection = connection;
64+
connection.DoConnection();
65+
} else {
66+
if (typeof requestOptions['connectionPriority'] != 'undefined' && requestOptions['connectionPriority'] == 'immediate' && this._connectionQueue.length > 5) {
67+
delete requestOptions['connectionPriority'];
68+
// this._connectionQueue.splice(0, 0, connection);
69+
connection.DoConnection();
70+
} else {
71+
this._connectionQueue.push(connection);
72+
}
73+
}
74+
}
75+
76+
QueuedConnectionManager.prototype.GetRequestOptionsForApi = function(apiName, method) {
77+
var options = {
78+
'host': this._connectionOptions['host'],
79+
'port': 443,
80+
'path': "/" + ["api", this._connectionOptions['apiVersion'], apiName].join("/"),
81+
'method': typeof method === 'undefined' ? 'GET' : method,
82+
'rejectUnauthorized': false,
83+
'requestCert': true,
84+
'agent': false,
85+
'auth': this._connectionOptions["user"] + ":" + this._connectionOptions["password"],
86+
};
87+
88+
if (typeof this._connectionOptions['options'] !== 'undefined') {
89+
for (var o in this._connectionOptions['options']) {
90+
options[o] = this._connectionOptions[o];
91+
}
92+
}
93+
94+
return options;
95+
}
96+
97+
QueuedConnectionManager.prototype.DoNextConnection = function() {
98+
if (this._activeConnection != null) return;
99+
if (this._connectionQueue.length === 0) return;
100+
101+
this._activeConnection = this._connectionQueue.splice(0, 1)[0];
102+
this._activeConnection.DoConnection();
103+
}
104+
105+
QueuedConnectionManager.prototype.GetJSONQueryResultConnection = function(requestOptions, resultHander, requestBody) {
106+
var output = "";
107+
var error = null;
108+
109+
var responseHandler = function(res) {
110+
if (res.statusCode < 200 || res.statusCode >= 300) {
111+
console.error("Error: Status Code Was %d", res.statusCode, requestOptions.path);
112+
error = true;
113+
}
114+
115+
res.setEncoding("utf8");
116+
res.on("data", function(chunk){
117+
output += chunk;
118+
});
119+
}
120+
121+
var requestHandler = function (req) {
122+
req.on("error", function(err){
123+
console.error("request error: ", err, requestOptions.path)
124+
error = err;
125+
});
126+
127+
req.on("close", function(){
128+
if (error != null) {
129+
resultHander(error, output);
130+
return;
131+
}
132+
133+
var json = null;
134+
try {
135+
json = JSON.parse(output)
136+
} catch (exc) {
137+
error = exc;
138+
}
139+
140+
resultHander(error, json || output)
141+
});
142+
143+
switch (typeof requestBody) {
144+
case 'string':
145+
case 'number':
146+
req.write(requestBody);
147+
break;
148+
149+
case 'object':
150+
req.write(JSON.stringify(requestBody));
151+
break;
152+
}
153+
154+
req.setTimeout(30000, function() {console.log("The request timed out")});
155+
156+
req.end()
157+
}
158+
159+
this.QueueConnection(requestOptions, requestHandler, responseHandler);
160+
}
161+
162+
function _connectionCompleteHandler(obj) {
163+
return function(completedConnection) {
164+
var index = obj._connectionQueue.indexOf(completedConnection);
165+
166+
if (index !== -1) {
167+
delete obj._connectionQueue[index];
168+
}
169+
170+
if (completedConnection === obj._activeConnection) {
171+
obj._activeConnection = null;
172+
obj.DoNextConnection();
173+
}
174+
};
175+
};
176+
177+
return QueuedConnectionManager;
178+
})();
179+
180+
module.exports = {
181+
'QueuedConnection': QueuedConnection,
182+
'QueuedConnectionManager': QueuedConnectionManager,
183+
};

README.md

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
Kubernetes Visualizer
2+
=====================
3+
4+
The demo application helps you visualize what is happening in your Kubernetes cluster by showing you where all of your workloads are being run. This both helps with understanding kubernetes, as well as visually demonstrating how its' scheduler works.
5+
6+
### Running the Demo
7+
The demo application is based off of NodeJS, so you'll need NodeJS at least 0.10.30. You'll also need the following npm modules:
8+
9+
- socket.io
10+
- cli
11+
- express
12+
13+
You can run the `install_packages.sh` script to install these if you already have node and npm installed, or you can install them manually.
14+
15+
#### Configuring the demo
16+
17+
Configuration options are passed to the demo via the command lines. The required options are the url of the Kubernetes server, and the number of minions in the cluster. You can pass this information in directly, or you can run the start_server.sh -- provided you edit it and enter in the path to your checkout of the [Kubernetes repository](https://github.com/GoogleCloudPlatform/kubernetes).
18+
19+
```
20+
$ ./index.js --help
21+
22+
Usage:
23+
index.js [OPTIONS] [ARGS]
24+
25+
Options:
26+
-s, --KubernetesServer URLURL of the Kubernetes Server
27+
-m, --NumMinions NUMBERNumber of minions in Kubernetes cluster
28+
-p, --PodRefreshInterval [NUMBER]Time between requesting the list of pods
29+
from the master (in milliseconds) (Default is 3000)
30+
-o, --OperationRefreshInterval [NUMBER]Time between checking the status
31+
on pending operations (in
32+
milliseconds) (Default is 1000)
33+
-k, --KubePath [PATH] Kubernetes repo path (Default is ../kubernetes)
34+
-a, --KubeAuthPath [PATH]Path to the kubernetes authorization file (Default is ~/.kubernetes_auth)
35+
-v, --KubeApiVersion [STRING]Version of the Kubernetes api to query against (Default is v1beta1)
36+
-p, --ListenPort [NUMBER]The port the server should listen on (Default is 3000)
37+
-r, --MaxReplicas [NUMBER]The maximum number of replicas the server will
38+
allow a client to create at once (Default is 300)
39+
-i, --DefaultImage [STRING]The default docker image to use when creating
40+
pods (Default is dockerfile/nginx)
41+
--debug Show debug information
42+
-h, --help Display help and usage details
43+
```
44+
45+
### License
46+
47+
Copyright 2014 Microsoft Corporation
48+
49+
Licensed under the Apache License, Version 2.0 (the "License");
50+
you may not use this file except in compliance with the License.
51+
You may obtain a copy of the License at
52+
53+
http://www.apache.org/licenses/LICENSE-2.0
54+
55+
Unless required by applicable law or agreed to in writing, software
56+
distributed under the License is distributed on an "AS IS" BASIS,
57+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
58+
See the License for the specific language governing permissions and
59+
limitations under the License.

0 commit comments

Comments
 (0)