-
Notifications
You must be signed in to change notification settings - Fork 133
[WIP] Add the Ability to use Redis for Storage #85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 9 commits
a755576
0ac02d9
3c28591
63f2a77
f251f45
3beaf58
f95f120
f2adccf
94bb611
f143f16
b385007
efc7679
23b66d3
07bfe07
d1c3a1a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
language: node_js | ||
services: | ||
- redis-server | ||
sudo: false | ||
node_js: | ||
- "6" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,7 +33,7 @@ using the npm package manager: | |
npm install -g configurable-http-proxy | ||
|
||
To install from the source code found in this GitHub repo: | ||
|
||
git clone https://github.com/jupyterhub/configurable-http-proxy.git | ||
cd configurable-http-proxy | ||
# Use -g for global install | ||
|
@@ -54,7 +54,7 @@ The configurable proxy runs two HTTP(S) servers: | |
|
||
### Setting a default target | ||
|
||
When you start the proxy from the command line, you can set a | ||
When you start the proxy from the command line, you can set a | ||
default target (`--default-target` option) to be used when no | ||
matching route is found in the proxy table: | ||
|
||
|
@@ -63,41 +63,49 @@ matching route is found in the proxy table: | |
### Command-line options | ||
|
||
``` | ||
Usage: configurable-http-proxy [options] | ||
Usage: configurable-http-proxy [options] | ||
|
||
Options: | ||
|
||
-h, --help output usage information | ||
-V, --version output the version number | ||
--ip <ip-address> Public-facing IP of the proxy | ||
--port <n> (defaults to 8000) Public-facing port of the proxy | ||
|
||
--ssl-key <keyfile> SSL key to use, if any | ||
--ssl-cert <certfile> SSL certificate to use, if any | ||
--ssl-ca <ca-file> SSL certificate authority, if any | ||
--ssl-request-cert Request SSL certs to authenticate clients | ||
--ssl-reject-unauthorized Reject unauthorized SSL connections (only meaningful if --ssl-request-cert is given) | ||
--ssl-protocol <ssl-protocol> Set specific HTTPS protocol, e.g. TLSv1_2, TLSv1, etc. | ||
--ssl-protocol <ssl-protocol> Set specific SSL protocol, e.g. TLSv1.2, SSLv3 | ||
--ssl-ciphers <ciphers> `:`-separated ssl cipher list. Default excludes RC4 | ||
--ssl-allow-rc4 Allow RC4 cipher for SSL (disabled by default) | ||
--ssl-dhparam <dhparam-file> SSL Diffie-Helman Parameters pem file, if any | ||
|
||
--api-ip <ip> Inward-facing IP for API requests | ||
--api-port <n> Inward-facing port for API requests (defaults to --port=value+1) | ||
--api-ssl-key <keyfile> SSL key to use, if any, for API requests | ||
--api-ssl-cert <certfile> SSL certificate to use, if any, for API requests | ||
--api-ssl-ca <ca-file> SSL certificate authority, if any, for API requests | ||
--api-ssl-request-cert Request SSL certs to authenticate clients for API requests | ||
--api-ssl-reject-unauthorized Reject unauthorized SSL connections (only meaningful if --api-ssl-request-cert is given) | ||
|
||
--default-target <host> Default proxy target (proto://host[:port]) | ||
--error-target <host> Alternate server for handling proxy errors (proto://host[:port]) | ||
--error-path <path> Alternate server for handling proxy errors (proto://host[:port]) | ||
--redirect-port <redirect-port> Redirect HTTP requests on this port to the server on HTTPS | ||
--pid-file <pid-file> Write our PID to a file | ||
|
||
--storage-provider <provider> The storage provider for the route table (defaults to memory) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @pseudomuto Thanks! storage-provider works better than my suggestions. I wonder if we should make the following redis options more generic i.e. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reason I chose to use I'm happy to concede here though, if you feel this would be better. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like Question, though: I'm not so experienced at deploying redis, but how many args are there likely to be used? Is it enough that we might want to have a full (JSON?) passthrough to redis-client constructor args, rather than a new PR for every redis option? Or are these three all we are likely to ever use? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are a bunch of options, though honestly I can't see most of them being used for this purpose. The list of supported options outlines them all. One thing we could do is use
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like the sound of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 for
Good point @pseudomuto 😄 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After some thought, I think we should use |
||
--redis-host <host> The redis host address (defaults to localhost) | ||
--redis-port <port> The port redis is listening on (defaults to 6379) | ||
--redis-db <db> The redis db to use (defaults to 0) | ||
|
||
--no-x-forward Don't add 'X-forward-' headers to proxied requests | ||
--no-prepend-path Avoid prepending target paths to proxied requests | ||
--no-include-prefix Don't include the routing prefix in proxied requests | ||
--auto-rewrite Rewrite the Location header host/port in redirect responses | ||
--protocol-rewrite <proto> Rewrite the Location header protocol in redirect responses to the specified protocol | ||
--insecure Disable SSL cert verification | ||
--host-routing Use host routing (host as first level of path) | ||
--statsd-host <host> Host to send statsd statistics to | ||
|
@@ -106,10 +114,9 @@ matching route is found in the proxy table: | |
--log-level <loglevel> Log level (debug, info, warn, error) | ||
``` | ||
|
||
|
||
## Using the REST API | ||
|
||
The configurable-http-proxy API is documented and available at the | ||
The configurable-http-proxy API is documented and available at the | ||
interactive swagger site, [petstore](http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyterhub/configurable-http-proxy/master/doc/rest-api.yml#/default) | ||
or as a [swagger specification file in this repo](https://github.com/jupyterhub/configurable-http-proxy/blob/master/doc/rest-api.yml). | ||
|
||
|
@@ -202,7 +209,7 @@ with their status code: | |
- 404: a client has requested a URL for which there is no routing target. | ||
This can be prevented if a `default target` is specified when starting | ||
the configurable-http-proxy. | ||
|
||
- 503: a route exists, but the upstream server isn't responding. | ||
This is more common, and can be due to any number of reasons, | ||
including the target service having died or not finished starting. | ||
|
@@ -211,10 +218,10 @@ with their status code: | |
|
||
If you specify an error path `--error-path /usr/share/chp-errors` when | ||
starting the CHP: | ||
|
||
configurable-http-proxy --error-path /usr/share/chp-errors | ||
then when a proxy error occurs, CHP will look in | ||
|
||
then when a proxy error occurs, CHP will look in | ||
`/usr/share/chp-errors/<CODE>.html` (where CODE is the status code number) | ||
for an html page to serve, e.g. `404.html` or `503.html`. | ||
|
||
|
@@ -225,7 +232,7 @@ If you specify an error path, make sure you also create `error.html`. | |
|
||
When starting the CHP, you can pass a command line option for `--error-target`. | ||
If you specify `--error-target http://localhost:1234`, | ||
then when the proxy encounters an error, it will make a GET request to | ||
then when the proxy encounters an error, it will make a GET request to | ||
this server, with URL `/CODE`, and the URL of the failing request | ||
escaped in a URL parameter, e.g.: | ||
|
||
|
@@ -247,3 +254,20 @@ first part of the URL path, e.g.: | |
"/otherdomain.biz": "http://10.0.1.4:5555", | ||
} | ||
``` | ||
|
||
## Using Redis | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using Redis as a Storage Provider |
||
|
||
If you require multiple instances of CHP to be running and kept in sync, you can use [redis] to to store the route table | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If your deployment runs multiple CHP instances, you may need to keep these instances in sync. You may use a storage provider, i.e. [redis], to store the route table instead of the default which is storing the table in memory. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: If you use an external storage provider, such as redis, the route table will not be stored in memory. |
||
rather than the default in memory option. | ||
|
||
To do so, you'll need to pass in a couple of options to CHP when launching it. Specifically, you'll need to set the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To configure CHP to launch with redis as the external storage provider, run the following: configurable-http-proxy --storage-provider redis This command launches CHP and uses [redis] on `localhost:6379 and the default redis database. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you wish to run [redis] on a different host, port, or database location, you should set the [additional options]. For example, pass the additional option when launching CHP: configurable-http-proxy --storage-provider redis --storage-provider-port 6380 |
||
storage provider and any [redis options] you need. | ||
|
||
For example, to use [redis] on `localhost:6379` and the default database, you can run the following: | ||
|
||
configurable-http-proxy --storage-provider redis | ||
|
||
If you are running [redis] on a different host, or need to customize the port/db, see [redis options]. | ||
|
||
[redis]: http://redis.io/ | ||
[redis options]: https://github.com/jupyterhub/configurable-http-proxy#command-line-options |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
var trie = require("../trie.js"); | ||
|
||
exports.create = function (BaseStore) { | ||
var routes = {}; | ||
var urls = new trie.URLTrie(); | ||
|
||
return Object.create(BaseStore, { | ||
get: { | ||
value: function (path, cb) { | ||
this.notify(cb, routes[path]); | ||
} | ||
}, | ||
getTarget: { | ||
value: function (path, cb) { | ||
this.notify(cb, urls.get(path)); | ||
} | ||
}, | ||
getAll: { | ||
value: function (cb) { | ||
this.notify(cb, routes); | ||
} | ||
}, | ||
add: { | ||
value: function (path, data, cb) { | ||
routes[path] = data; | ||
urls.add(path, data); | ||
this.notify(cb); | ||
} | ||
}, | ||
update: { | ||
value: function (path, data, cb) { | ||
Object.assign(routes[path], data); | ||
this.notify(cb); | ||
} | ||
}, | ||
remove: { | ||
value: function (path, cb) { | ||
delete routes[path]; | ||
urls.remove(path); | ||
this.notify(cb); | ||
} | ||
}, | ||
hasRoute: { | ||
value: function (path, cb) { | ||
this.notify(cb, routes.hasOwnProperty(path)); | ||
} | ||
} | ||
}); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I swear it was vim not me! 😄