Skip to content

Commit

Permalink
Add coturns for TLS TURN service.
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelfig committed Oct 24, 2018
1 parent 85618a2 commit ba61c67
Show file tree
Hide file tree
Showing 18 changed files with 375 additions and 26 deletions.
3 changes: 2 additions & 1 deletion .dockerignore
@@ -1,4 +1,5 @@
node_modules/
charts/
coturns/
build.sh
Dockerfile
Dockerfile
43 changes: 23 additions & 20 deletions app/common.js
Expand Up @@ -82,9 +82,7 @@ function pubsubClient(channel, password, isPublisher) {
return;
}

var room = new ms.Room({
requestTimeout: 8000,
});
var room;

var reqid = 0;
var pending = {};
Expand All @@ -98,6 +96,28 @@ function pubsubClient(channel, password, isPublisher) {
ws.onopen = function onOpen() {
connected = true;
pending[++reqid] = function onPubsub(payload) {
room = new ms.Room({
requestTimeout: 8000,
turnServers: payload.turnServers || [],
});

room.on('request', function onRequest(request, callback, errback) {
if (ws.readyState !== ws.OPEN) {
return errback(Error('WebSocket is not open'));
}

pending[++ reqid] = callback;
errors[reqid] = errback;
ws.send(JSON.stringify({type: 'MS_SEND', payload: request, meta: {id: reqid, channel: channel}}));
});
room.on('notify', function onNotification(notification) {
if (ws.readyState !== ws.OPEN) {
console.log(Error('WebSocket is not open'));
return;
}
ws.send(JSON.stringify({type: 'MS_SEND', payload: notification, meta: {channel: channel, notification: true}}));
});

room.join(peerName)
.then(function (peers) {
console.log('Channel', channel, 'joined with peers', peers);
Expand Down Expand Up @@ -152,23 +172,6 @@ function pubsubClient(channel, password, isPublisher) {
console.log('Error', e, 'handling', JSON.stringify(event.data));
}
}

room.on('request', function onRequest(request, callback, errback) {
if (ws.readyState !== ws.OPEN) {
return errback(Error('WebSocket is not open'));
}

pending[++ reqid] = callback;
errors[reqid] = errback;
ws.send(JSON.stringify({type: 'MS_SEND', payload: request, meta: {id: reqid, channel: channel}}));
});
room.on('notify', function onNotification(notification) {
if (ws.readyState !== ws.OPEN) {
console.log(Error('WebSocket is not open'));
return;
}
ws.send(JSON.stringify({type: 'MS_SEND', payload: notification, meta: {channel: channel, notification: true}}));
});
});
}

Expand Down
16 changes: 16 additions & 0 deletions build.sh
Expand Up @@ -4,6 +4,7 @@ thisdir=`dirname "$0"`
REGISTRY=${REGISTRY-michaelfig}
NAME=mediasoup-broadcast-example
VERSION=`sed -ne '/^ *"version":/{ s/^.* "version": *"\([^"]*\)".*/\1/; p; q; }' "$thisdir"/package.json`
COTURNS_VERSION=4.5.0.7

# If KUBE_CONTEXT=example, use --kube-context=example and -fcharts/example.yaml
KUBE_CONTEXT=${KUBE_CONTEXT-example}
Expand All @@ -14,6 +15,11 @@ build)
docker build -t michaelfig/mediasoup-broadcast-example:latest .
;;

build-coturns)
cd "$thisdir"
docker build -t michaelfig/coturns:latest coturns
;;

push)
cmd="$1"
shift
Expand All @@ -22,6 +28,16 @@ push)
docker push $REGISTRY/mediasoup-broadcast-example:$TAG
done
;;

push-coturns)
cmd="$1"
shift
for TAG in latest $COTURNS_VERSION ${1+"$@"}; do
docker tag michaelfig/coturns:latest $REGISTRY/coturns:$TAG
docker push $REGISTRY/coturns:$TAG
done
;;

upgrade|install)
cd "$thisdir"
cmd="$1"
Expand Down
21 changes: 21 additions & 0 deletions charts/coturns/.helmignore
@@ -0,0 +1,21 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
5 changes: 5 additions & 0 deletions charts/coturns/Chart.yaml
@@ -0,0 +1,5 @@
apiVersion: v1
appVersion: "1.0"
description: A Helm chart for Kubernetes
name: coturns
version: 0.1.0
15 changes: 15 additions & 0 deletions charts/coturns/templates/NOTES.txt
@@ -0,0 +1,15 @@
1. Get the application URL by running these commands:
{{- if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "coturns.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get svc -w {{ template "coturns.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "coturns.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "coturns.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl port-forward $POD_NAME 8080:80
{{- end }}
32 changes: 32 additions & 0 deletions charts/coturns/templates/_helpers.tpl
@@ -0,0 +1,32 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "coturns.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
{{- end -}}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "coturns.fullname" -}}
{{- if .Values.fullnameOverride -}}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- $name := default .Chart.Name .Values.nameOverride -}}
{{- if contains $name .Release.Name -}}
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- end -}}
{{- end -}}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "coturns.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
90 changes: 90 additions & 0 deletions charts/coturns/templates/deployment.yaml
@@ -0,0 +1,90 @@
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: {{ template "coturns.fullname" . }}
labels:
app: {{ template "coturns.name" . }}
chart: {{ template "coturns.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ template "coturns.name" . }}
release: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ template "coturns.name" . }}
release: {{ .Release.Name }}
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
{{- if .Values.coturns.authRealm }}
- name: AUTH_REALM
value: {{ .Values.coturns.authRealm | quote }}
{{- end }}
{{- if .Values.coturns.tlsSecretName }}
- name: TLS_DIRECTORY
value: /tls
{{- end }}
- name: AUTH_SECRET
valueFrom:
secretKeyRef:
name: {{ .Release.Name }}-secret
key: authSecret
{{- if .Values.service.hostNetworkIP }}
- name: EXTERNAL_IP
value: {{ .Values.service.hostNetworkIP }}
{{- end }}
{{- if .Values.coturns.tlsSecretName }}
volumeMounts:
- name: tls-secret-volume
mountPath: /tls
{{- end }}
ports:
- name: https
containerPort: 443
protocol: TCP
livenessProbe:
httpGet:
path: /
port: https
scheme: HTTPS
readinessProbe:
httpGet:
path: /
port: https
scheme: HTTPS
resources:
{{ toYaml .Values.resources | indent 12 }}
{{- if .Values.coturns.tlsSecretName }}
volumes:
- name: tls-secret-volume
secret:
secretName: {{ .Values.coturns.tlsSecretName | quote }}
{{- end }}
{{- if .Values.service.hostNetworkIP }}
hostNetwork: true
{{- end }}
{{- if or .Values.service.hostNetworkIP .Values.nodeSelector }}
nodeSelector:
{{- end }}
{{- if .Values.service.hostNetworkIP }}
hostNetworkIP: {{ .Values.service.hostNetworkIP }}
{{- end }}
{{- with .Values.nodeSelector }}
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{ toYaml . | indent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{ toYaml . | indent 8 }}
{{- end }}
12 changes: 12 additions & 0 deletions charts/coturns/templates/secret.yaml
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-secret
labels:
app: {{ template "coturns.name" . }}
chart: {{ template "coturns.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
type: Opaque
data:
authSecret: {{ default "" .Values.coturns.authSecret | b64enc | quote }}
19 changes: 19 additions & 0 deletions charts/coturns/templates/service.yaml
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
name: {{ template "coturns.fullname" . }}
labels:
app: {{ template "coturns.name" . }}
chart: {{ template "coturns.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: https
protocol: TCP
name: https
selector:
app: {{ template "coturns.name" . }}
release: {{ .Release.Name }}
47 changes: 47 additions & 0 deletions charts/coturns/values.yaml
@@ -0,0 +1,47 @@
# Default values for coturns.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

replicaCount: 1

image:
repository: michaelfig/coturns
tag: stable
pullPolicy: IfNotPresent

coturns:
# tlsSecret: coturns-tls-secret
authRealm: Example
authSecret: NotVerySecret

service:
type: ClusterIP
port: 443
# hostNetworkIP: 1.2.3.4 # example IP address
#
# You will need to label the node to which 1.2.3.4 is routed with:
# kubectl label node <MY-PUBLIC-NODE> hostNetworkIP=1.2.3.4
#
# Then the pod will use "hostNetwork: true", and it will be scheduled
# only on the node returned by:
# kubectl get node -lhostNetworkIP=1.2.3.4
#
# This also sets the environment variable EXTERNAL_IP=1.2.3.4

resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi

nodeSelector: {}

tolerations: []

affinity: {}
4 changes: 4 additions & 0 deletions charts/example.yaml
@@ -1,3 +1,7 @@
coturns:
authRealm: Example
authSecret: "NotReallyVerySecret!"
# tlsSecretName: my-tls-secret
service:
# Needs:
# kubectl label node <MY-NODE> hostNetworkIP=1.2.3.4
Expand Down
8 changes: 8 additions & 0 deletions charts/mediasoup-broadcast-example/templates/deployment.yaml
Expand Up @@ -36,6 +36,14 @@ spec:
- name: INGRESS_PATH
value: {{ .Values.ingress.path | quote }}
{{- end }}
{{- if .Values.coturns.turnServers }}
- name: TURN_SERVERS
value: {{ .Values.coturns.turnServers | quote }}
{{- end }}
{{- if .Values.coturns.authSecret }}
- name: TURN_AUTH_KEY
value: {{ .Values.coturns.authSecret | quote }}
{{- end }}
ports:
- name: http
containerPort: {{ .Values.service.containerPort }}
Expand Down

0 comments on commit ba61c67

Please sign in to comment.