Skip to content
This repository has been archived by the owner on Jul 30, 2019. It is now read-only.

Commit

Permalink
More info on the muguet page
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthias ETIENNE committed Aug 5, 2015
1 parent 75818cf commit 318e745
Show file tree
Hide file tree
Showing 6 changed files with 434 additions and 101 deletions.
39 changes: 26 additions & 13 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ var App = function (ProxyDriver, HTTPDriver, DNSDriver, domain, api_port, proxy_
this.proxyIp = proxy_ip
this.dnsIp = dns_ip
this.dnsPort = dns_port
this.version = require('./package.json').version

// DNS stuff
this.dnsServer = new DNSServer(this, this.dnsDriver, domain);

// proxy
this.proxy = new HTTPProxy(this.proxyDriver, this.httpDriver, this.dnsServer)
this.proxy = new HTTPProxy(this, this.proxyDriver, this.httpDriver, this.dnsServer)
}

/**
Expand All @@ -60,13 +61,24 @@ App.prototype.run = function () {
}

/**
* Gte proxy IP address
* Get proxy IP address
*
* @returns {String}
*/
App.prototype.getProxyIp = function () {
return this.proxyIp
}


/**
* Get domain
*
* @returns {String}
*/
App.prototype.getDomain = function () {
return this.domain
}

/**
* Callback on the first containers list received
*
Expand Down Expand Up @@ -120,8 +132,8 @@ App.prototype.getProxyRoutes = function () {
var flags = DockerContainer.IS_RUNNING | DockerContainer.HAS_PROXY_ENABLED | DockerContainer.HAS_EXPOSED_PORTS;

var routes = ContainersHelper.filterContainers(this.containers, flags).map(function (cnt) {
return cnt.getProxyRoutes(this.domain)
}.bind(this))
return cnt.getProxyRoutes()
})

if (routes.length) {
routes = routes.reduce(function (prev, next) {
Expand All @@ -137,17 +149,18 @@ App.prototype.getProxyRoutes = function () {
*/
App.prototype.getDnsEntries = function () {

var entries = this.containers.map(function (cnt) {
return cnt.getDnsEntries(this.domain)
}.bind(this))

if (entries.length) {
entries = entries.reduce(function (prev, next) {
return prev.concat(next)
var finalEntries = {}
, entries = this.containers.map(function (cnt) {
return cnt.getDnsEntries()
})
}

return entries
entries.forEach(function (entry) {
for (var n in entry) {
finalEntries[n] = (finalEntries[n] || []).concat(entry[n])
}
})

return finalEntries
}

module.exports = App
32 changes: 19 additions & 13 deletions lib/dns-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ var EventEmitter = require('events').EventEmitter

require('colors')

var DNSServer = function (app, driver, domain) {
var DNSServer = function (app, driver) {

EventEmitter.call(this)

this.domain = domain
this.app = app
this.driver = driver
this.entries = {}
Expand Down Expand Up @@ -64,7 +63,7 @@ util.inherits(DNSServer, EventEmitter)
* @private
*/
DNSServer.prototype._setupResolver = function (port, ip) {
var file = path.join('/etc/resolver', this.domain)
var file = path.join('/etc/resolver', this.app.getDomain())

var contents = [
"nameserver " + ip,
Expand All @@ -81,32 +80,39 @@ DNSServer.prototype._setupResolver = function (port, ip) {
DNSServer.prototype.setEntries = function (entries) {

this.entries = {}
this.entries['muguet.' + this.domain] = this.app.getProxyIp()
this.entries['muguet.' + this.app.getDomain()] = this.app.getProxyIp()

var self = this

entries.forEach(function (entry) {
entry.names.forEach(function (name) {
self.entries[name] = entry.ip
for (var ip in entries) {
entries[ip].forEach(function(name) {
self.entries[name] = ip
Logger.info(util.format('Resolving domain %s to IP %s', name.yellow, ip.yellow))
})
})
}
}

DNSServer.prototype.getEntries = function () {
return this.entries
}

DNSServer.prototype.getPort = function () {
return this.port
}

DNSServer.prototype.listen = function (port, ip) {
port = port || 9999
this._setupResolver(port, ip)
this.port = port || 9999
this._setupResolver(this.port, ip)

var self = this

this.server
.on('error', function() {
Logger.error("Muguet DNS Server cannot listen on port %s", String(port).red)
Logger.error("Muguet DNS Server cannot listen on port %s", String(self.port).red)
process.exit()
})
.listen(port, '::', function () {
Logger.info('Muguet DNS Server listening on port %s', String(port).yellow)
.listen(this.port, '::', function () {
Logger.info('Muguet DNS Server listening on port %s', String(self.port).yellow)
})

return this
Expand Down
74 changes: 46 additions & 28 deletions lib/docker-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

var Logger = require('./logger')
, _ = require('lodash')
, sprintf = require('util').format


/**
* Represent a docker container
Expand Down Expand Up @@ -237,22 +239,20 @@ DockerContainer.prototype.getComposeContainerNumber = function () {

/**
*
* @param domain
* @returns {Array}
* @returns {Object}
*/
DockerContainer.prototype.getDnsEntries = function (domain) {
DockerContainer.prototype.getDnsEntries = function () {

var ports = this.getPorts();
var ports = this.getPorts(),
entries = {}

var entries = ports.map(function (portSpecs) {
ports.forEach(function (portSpecs) {

var hostname = this.getProxiedHostname(portSpecs.PrivatePort, domain),
aliases = this.getHostnameAliases(domain, portSpecs.PrivatePort)
var hostname = this.getProxiedHostname(portSpecs.PrivatePort)
, aliases = this.getHostnameAliases(portSpecs.PrivatePort)
, ip = this.shouldBeProxified() ? this.app.getProxyIp() : this.getIPAddress()

return {
ip : this.shouldBeProxified() ? this.app.getProxyIp() : this.getIPAddress(),
names : [hostname].concat(aliases)
}
entries[ip] = _.uniq((entries[ip] || []).concat(hostname).concat(aliases))

}.bind(this))

Expand All @@ -262,47 +262,66 @@ DockerContainer.prototype.getDnsEntries = function (domain) {
/**
* build single container routes
*
* @param {HTTPProxy} proxy
* @param {DockerContainer} cnt
* @return {Array}
* @private
*/
DockerContainer.prototype.getProxyRoutes = function (domain) {
DockerContainer.prototype.getProxyRoutes = function () {

if (false === this.shouldBeProxified()) {
return []
}

var ports = this.getProxifiedPorts(),
port80Bound = {}

var routes = ports.map(function (portSpecs) {
return ports.map(function (portSpecs) {

var hostname = this.getProxiedHostname(portSpecs.PrivatePort, domain),
aliases = this.getHostnameAliases(domain, portSpecs.PrivatePort),
var hostname = this.getProxiedHostname(portSpecs.PrivatePort),
aliases = this.getHostnameAliases(portSpecs.PrivatePort),
mappedPort = port80Bound[hostname] = port80Bound[hostname] ? portSpecs.PublicPort : 80

return this._getRouteObject(hostname, aliases, this.getIPAddress(), mappedPort, portSpecs)

}.bind(this))

return routes
}

DockerContainer.prototype.getProxiedHostname = function (port, domain) {
return this.getExtendedSubDomain(port) + '.' + domain
/**
* Return the proxied hostname for a specific port
*
* @param {number} port
* @returns {string}
*/
DockerContainer.prototype.getProxiedHostname = function (port) {
return this.getExtendedSubDomain(port) + '.' + this.app.getDomain()
}

/**
* Return the extended sub-domain for a specific port
*
* @param {number} port
* @returns {string}
*/
DockerContainer.prototype.getExtendedSubDomain = function (port) {
return this.getMappedSubDomainByPort(port, '.') + this.getSubDomain()
}

DockerContainer.prototype.getHostnameAliases = function (domain, port) {
/**
* Get hostname aliases
*
* @param {number} port
* @returns {Array}
*/
DockerContainer.prototype.getHostnameAliases = function (port) {
var subDomain = this.getMappedSubDomainByPort(port, '.')
return _.uniq([
subDomain + this.getHostname() + '.' + domain,
subDomain + this.getId().substr(0, 12) + '.' + domain
subDomain + this.getHostname() + '.' + this.app.getDomain(),
subDomain + this.getId().substr(0, 12) + '.' + this.app.getDomain()
])
}

/**
*
* @param port
* @param {number} port
* @returns {string} can be empty
*/
DockerContainer.prototype.getMappedSubDomainByPort = function (port, suffix) {
Expand All @@ -312,7 +331,6 @@ DockerContainer.prototype.getMappedSubDomainByPort = function (port, suffix) {

/**
*
* @param {DockerContainer} cnt
* @returns {Array}
*/
DockerContainer.prototype.getProxifiedPorts = function () {
Expand All @@ -325,7 +343,7 @@ DockerContainer.prototype.getProxifiedPorts = function () {
var restrictions = this.getPortsRestrictions()
if (restrictions && restrictions.indexOf(port_mapping.PrivatePort) === -1) {
var msg = "Filtering tcp port %d beause of 'only-ports' policy (%s) for container '%s'"
Logger.debug(msg, port_mapping.PrivatePort, restrictions, this.getSubDomain())
Logger.info(sprintf(msg, port_mapping.PrivatePort, restrictions, this.getSubDomain()))
return false
}
return true
Expand Down Expand Up @@ -354,7 +372,7 @@ DockerContainer.prototype._getRouteObject = function (hostname, hostname_aliases
hostname_aliases: hostname_aliases,
port: mappedPort,
container_public_addr: this.app.getDockerInfos().hostname,
container_public_port: port_mapping.PublicPort || null,
container_public_port: port_mapping.PublicPort,
container_private_addr: container_addr,
container_private_port: port_mapping.PrivatePort
}
Expand Down
41 changes: 35 additions & 6 deletions lib/http-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
var http = require('http')
, measured = require('measured')
, Logger = require('./logger')
, sprintf = require('util').format

require('colors')

/**
*
* @constructor
*/
var HTTPProxy = function (httpProxyDriver, httpDriver, dns_server) {
var HTTPProxy = function (app, httpProxyDriver, httpDriver, dns_server) {
this.app = app
this.portToServerMap = {}
this.routes = []
this.stats = {}
Expand Down Expand Up @@ -102,6 +104,13 @@ HTTPProxy.prototype.getRoutes = function (withstats) {
}.bind(this))
}

HTTPProxy.prototype.getProxiedDomains = function() {
return this.routes.map(function (route) {
var url = 'http://' + route.hostname + ':' + route.port
return sprintf('<a href="%s">%s</a>', url, url)
}.bind(this))
}

/**
* Get route for request
*
Expand Down Expand Up @@ -207,14 +216,34 @@ HTTPProxy.prototype.listen = function (stats_port) {
// --- HOME ---
case '/':
contentType = 'text/html'
var dnsEntries = [],
entries = self.dnsServer.getEntries()
for (var name in entries) {
dnsEntries.push(name + ' &#8594; ' + entries[name])
}
responseData = [
'<style>body { font-family: Helvetica Neue, Helvetica, Arial; font-size:0.9em} a, a:visited {color:#5EA53A} #main {width:400px; margin:100px auto; } ul {list-style-type: square; margin: 10px; padding:0 !important; text-align: center} li {display:inline-block; min-width:180px; margin-right: 20px; text-align: center} li:last-child {margin-right: 0} img {width:100%; height: auto}</style>',
'<style>body { font-family: Helvetica Neue, Helvetica, Arial; font-size:0.9em} a, a:visited {color:#5EA53A} a:hover{color:#2D6626} #main {width:400px; margin:60px auto; } #json {list-style-type: square; margin: -16px 0 20px 0; padding:0 !important; text-align: center; font-size:85%} #json li {display:inline-block; min-width:170px; margin-right: 4px; text-align: center} #json li:first-child {margin-left:48px} #json li:last-child {margin-right: 0} img {width:100%; height: auto} p {text-align:center; font-size:80%; margin-top:40px; line-height: 1.3} b.big {font-size:110%}</style>',
'<html><head><title>Muguet</title></head><body>',
'<div id="main">',
'<img src="https://raw.githubusercontent.com/mattallty/muguet/master/assets/muguet.png" />',
'<ul>',
'<li><a href="/proxy-routes">Reverse Proxy Routes</a></li>',
'<li><a href="/dns-entries">DNS entries</a></li>',
'<img src="https://raw.githubusercontent.com/mattallty/muguet/master/assets/muguet.png" border="0" />',
'<ul id="json">',
'<li><a href="/proxy-routes">Reverse Proxy Routes (JSON)</a></li>',
'<li><a href="/dns-entries">DNS entries (JSON)</a></li>',
'</ul>',
'<p>',
'Domain set to <b>' + self.app.getDomain() + '</b><br />',
'Proxy server listening on ports <b>' + Object.keys(self.portToServerMap).join(', ') + '</b><br />',
'DNS server listening on port <b>' + self.dnsServer.getPort() + '</b><br />',
'</p>',
'<p>',
'<b class="big">Proxied domains</b><br />' + self.getProxiedDomains().join('<br />'),
'</p>',
'<p>',
'<b class="big">DNS entries</b><br />' + dnsEntries.join('<br />'),
'</p>',
'<p>',
'<a href="https://github.com/mattallty/muguet">Muguet v' + self.app.version + '</a>',
'</p>',
'</div>'
].join('')
break
Expand Down
Loading

0 comments on commit 318e745

Please sign in to comment.