blob: c13e82d129ec145bcf639e56c69c5497ee8aa0be [file] [log] [blame]
local kube = import "../../../kube/kube.libsonnet";
{
local radio = self,
local cfg = radio.cfg,
cfg:: {
namespace: error "namespace must be set",
appName: "radio",
prefix: "", # if set, should be 'foo-'
port: 2137,
icecast: {
location: error "location must be set",
admin: error "admin must be set",
limits: {
clients: 100,
sources: 2,
threadpool: 5,
queueSize: 524288,
clientTimeout: 30,
headerTimeout: 15,
sourceTimeout: 10,
burstOnConnect: true,
burstSize: 65535,
},
authentication: {
sourcePassword: error "source password must be set",
relayPassword: error "relay password must be set",
adminPassword: error "admin password must be set",
},
hostname: "localhost",
listenPort: 8080,
mounts: [],
},
tag: "latest",
image: "registry.k0.hswaw.net/app/radio:" + cfg.tag,
resources: {
requests: {
cpu: "25m",
memory: "50Mi",
},
limits: {
cpu: "100m",
memory: "200Mi",
},
},
},
mount:: {
username: error "mount username must be defined",
password: error "mount password must be defined",
genre: "Classical",
bitrate: 128,
hidden: false,
fallbackMount: null,
},
makeName(suffix):: cfg.prefix + suffix,
metadata:: {
namespace: cfg.namespace,
labels: {
"app.kubernetes.io/name": cfg.appName,
"app.kubernetes.io/managed-by": "kubecfg",
"app.kubernetes.io/component": "radio",
},
},
configMap: kube.ConfigMap(radio.makeName("icecast")) {
metadata+: radio.metadata,
data: {
"icecast.xml": std.manifestXmlJsonml(["icecast",
["location", cfg.icecast.location],
["admin", cfg.icecast.admin],
["limits",
["clients", std.toString(cfg.icecast.limits.clients)],
["sources", std.toString(cfg.icecast.limits.sources)],
["threadpool", std.toString(cfg.icecast.limits.threadpool)],
["queue-size", std.toString(cfg.icecast.limits.queueSize)],
["client-timeout", std.toString(cfg.icecast.limits.clientTimeout)],
["header-timeout", std.toString(cfg.icecast.limits.headerTimeout)],
["source-timeout", std.toString(cfg.icecast.limits.sourceTimeout)],
["burst-on-connect", if cfg.icecast.limits.burstOnConnect then "1" else "0"],
["burst-size", std.toString(cfg.icecast.limits.burstSize)],
],
["authentication",
["source-password", cfg.icecast.authentication.sourcePassword],
["relay-user", "relay"],
["relay-password", cfg.icecast.authentication.relayPassword],
["admin-user", "admin"],
["admin-password", cfg.icecast.authentication.adminPassword],
],
["hostname", cfg.icecast.hostname],
["listen-socket",
["port", std.toString(cfg.icecast.listenPort)],
],
["fileserve", "1"],
["paths",
["webroot", "/usr/share/icecast/web"],
["adminroot", "/usr/share/icecast/admin"],
],
["logging",
["accesslog", "-"],
["errorlog", "-"],
["loglevel", "2"],
],
["security",
["chroot", "0"],
],
] + [
["mount", {type: "normal"},
["mount-name", m],
["username", cfg.icecast.mounts[m].username],
["password", cfg.icecast.mounts[m].password],
["public", if cfg.icecast.mounts[m].public then "1" else "0"],
["genre", cfg.icecast.mounts[m].genre],
["bitrate", std.toString(cfg.icecast.mounts[m].bitrate)],
["hidden", if cfg.icecast.mounts[m].hidden then "1" else "0"],
] + (if cfg.icecast.mounts[m].fallbackMount != null then [
["fallback-mount", cfg.icecast.mounts[m].fallbackMount],
["fallback-override", "1"],
] else [])
for m in std.objectFields(cfg.icecast.mounts)
]),
},
},
deployment: kube.Deployment(radio.makeName("icecast")) {
metadata+: radio.metadata,
spec+: {
replicas: 1,
template+: {
spec+: {
volumes_: {
config: kube.ConfigMapVolume(radio.configMap),
},
containers_: {
radio: kube.Container(radio.makeName("radio")) {
image: cfg.image,
ports_: {
client: { containerPort: cfg.icecast.listenPort },
},
volumeMounts_: {
config: { mountPath: "/usr/share/icecast/icecast.xml", subPath: "icecast.xml" },
},
resources: cfg.resources,
},
},
},
},
},
},
svc: kube.Service(radio.makeName("icecast")) {
metadata+: radio.metadata,
target_pod:: radio.deployment.spec.template,
spec+: {
ports: [
{ name: "client", port: cfg.port, targetPort: cfg.icecast.listenPort, protocol: "TCP" },
],
type: "LoadBalancer",
},
},
}