From 449e8c07a534612914ca114f25261014a3abd535 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Thu, 13 Jun 2019 14:33:03 +0100 Subject: [PATCH] socks-server: publish docker ports --- packages/syntax-playground/package.json | 1 + .../syntax-playground/src/socks-service.js | 64 ++++++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/packages/syntax-playground/package.json b/packages/syntax-playground/package.json index f6bb96c..ec554a6 100644 --- a/packages/syntax-playground/package.json +++ b/packages/syntax-playground/package.json @@ -24,6 +24,7 @@ "@syndicate-lang/driver-websocket": "^0.2.0", "@syndicate-lang/server": "^0.2.0", "debug": "^4.1.1", + "dockerode": "^2.5.8", "webpack": "^4.27.1", "webpack-cli": "^3.1.2" } diff --git a/packages/syntax-playground/src/socks-service.js b/packages/syntax-playground/src/socks-service.js index 9e7e962..545ad03 100644 --- a/packages/syntax-playground/src/socks-service.js +++ b/packages/syntax-playground/src/socks-service.js @@ -1,14 +1,26 @@ // https://www.ietf.org/rfc/rfc1928.txt -const { currentFacet, genUuid, Bytes, Map, Observe, Skeleton } = require("@syndicate-lang/core"); +const { + currentFacet, genUuid, + Bytes, Map, + Observe, Skeleton, + Dataspace, +} = require("@syndicate-lang/core"); const C = activate require("@syndicate-lang/server/lib/client"); const S = activate require("@syndicate-lang/driver-streams-node"); const M = activate require("@syndicate-lang/driver-mdns"); +const { PeriodicTick } = activate require("@syndicate-lang/driver-timer"); const debugFactory = require('debug'); +const os = require('os'); assertion type VirtualTcpAddress(host, port); assertion type AddressMap(from, nodeId, to); +assertion type DockerContainerInfo(name, info); +assertion type DockerContainerPort(name, ip, port); +assertion type DockerScan(); +message type DockerContainers(blob); + assertion type ToNode(nodeId, assertion); assertion type FromNode(nodeId, assertion); assertion type RestrictedFromNode(nodeId, spec, captures); @@ -59,6 +71,50 @@ const server_addr = C.WSServer(server_url, server_scope); const nodeId = genUuid('node'); +spawn named 'docker-scan' { + const debug = debugFactory('syndicate/server:socks:docker:scan'); + const Docker = require('dockerode'); + during Observe(DockerContainerInfo(_, _)) assert DockerScan(); + during Observe(DockerContainerPort(_, _, _)) assert DockerScan(); + during DockerScan() { + + const docker = new Docker(); + function scan() { + docker.listContainers(Dataspace.wrapExternal((err, containers) => { + if (err) throw err; + react { + stop on message PeriodicTick(5000) scan(); + on start send DockerContainers(containers); + } + })); + } + on start scan(); + + on message DockerContainers($containers0) { + const containers = containers0.toJSON(); + react { + stop on message DockerContainers(_); + containers.forEach((info) => { + const net = info.NetworkSettings.Networks.bridge; + if (net) { + info.Names.forEach((n) => { + const name = n.replace('/', ''); + assert DockerContainerInfo(name, info); + info.Ports.forEach((p) => { + if (p.Type === 'tcp') { + assert DockerContainerPort(name, net.IPAddress, p.PrivatePort); + } + }); + }); + } else { + debug('No bridge network for container', info.Id, info.Names); + } + }); + } + } + } +} + spawn named 'test-remap' { during C.ServerConnected(server_addr) { during M.Discovered(M.Service($name, '_ssh._tcp'), $host, $port, _, _, "IPv4", _) { @@ -66,6 +122,12 @@ spawn named 'test-remap' { nodeId, S.TcpAddress(host, port))); } + during DockerContainerPort($name, $ip, $port) { + const servicename = name + '.' + os.hostname() + '.docker.fruit'; + assert C.ToServer(server_addr, AddressMap(VirtualTcpAddress(servicename, port), + nodeId, + S.TcpAddress(ip, port))); + } } }