blob: 36ba895d1399fd359c9b7f4d4295168a22e78712 [file] [log] [blame]
local kube = import "../../../kube/hscloud.libsonnet";
{
local wow = self,
local cfg = wow.cfg,
local ns = wow.ns,
cfg:: {
namespace: error "namespace must be set",
prefix: "",
images: {
acore: "registry.k0.hswaw.net/q3k/azerothcore-wowtlk:1606950998",
panel: "registry.k0.hswaw.net/q3k/panel:1607075221-54d0e977e57cc2c8d949c3a7ecf2ff21abd9d143",
},
db: {
local mkConfig = function(name) {
host: error ("db.%s.host must be set" % [name]),
port: error ("db.%s.prt must be set" % [name]),
user: error ("db.%s.user must be set" % [name]),
password: error ("db.%s.password must be set" % [name]),
database: "acore_%s" % [name],
},
auth: mkConfig("auth"),
world: mkConfig("world"),
characters: mkConfig("characters"),
},
panel: {
domain: error "panel.domain must be set",
soap: {
username: error "panel.soap.username must be set",
password: error "panel.soap.password must be set",
},
secret: error "panel.secret must be set",
oauth: {
clientID: error "panel.oauth.clientID must set",
clientSecret: error "panel.oauth.clientSecret must set",
redirectURL: "https://%s/callback" % [cfg.panel.domain],
},
motd: "",
},
overrides: {
authserver: {},
worldserver: {},
ahbot: {},
},
},
ns: kube.Namespace(cfg.namespace),
data: ns.Contain(kube.PersistentVolumeClaim(cfg.prefix + "data")) {
storage:: "50Gi",
storageClass:: "waw-hdd-redundant-3",
},
// Make a *DatabaseInfo string for use by acore config. These are not any real
// standardized DSN format, just some semicolon-delimited proprietary format.
local mkDbString = function(config) (
"%s;%d;%s;%s;%s" % [
config.host,
config.port,
config.user,
config.password,
config.database,
]
),
etc: ns.Contain(kube.Secret(cfg.prefix + "etc")) {
data: {
"worldserver.conf": std.base64(std.manifestIni({
sections: {
worldserver: {
RealmID: 1,
DataDir: "/data/current",
LoginDatabaseInfo: mkDbString(cfg.db.auth),
WorldDatabaseInfo: mkDbString(cfg.db.world),
CharacterDatabaseInfo: mkDbString(cfg.db.characters),
LogLevel: 2,
"Console.Enable": 0,
"Ra.Enable": 1,
"Ra.IP": "127.0.0.1",
"SOAP.Enabled": 1,
"SOAP.IP": "0.0.0.0",
} + cfg.overrides.worldserver,
},
})),
"mod_ahbot.conf": std.base64(std.manifestIni({
sections: {
worldserver: cfg.overrides.ahbot,
},
})),
"authserver.conf": std.base64(std.manifestIni({
sections: {
authserver: {
LoginDatabaseInfo: mkDbString(cfg.db.auth),
} + cfg.overrides.authserver,
},
})),
},
},
worldserverDeploy: ns.Contain(kube.Deployment(cfg.prefix + "worldserver")) {
spec+: {
template+: {
spec+: {
containers_: {
default: kube.Container("default") {
image: cfg.images.acore,
volumeMounts: [
{ name: "data", mountPath: "/data" },
{ name: "etc", mountPath: "/azeroth-server/etc/worldserver.conf", subPath: "worldserver.conf", },
{ name: "etc", mountPath: "/azeroth-server/etc/mod_ahbot.conf", subPath: "mod_ahbot.conf", },
],
command: [
"/entrypoint.sh",
"/azeroth-server/bin/worldserver",
],
},
},
securityContext: {
runAsUser: 999,
runAsGroup: 999,
fsGroup: 999,
},
volumes_: {
data: kube.PersistentVolumeClaimVolume(wow.data),
etc: kube.SecretVolume(wow.etc),
},
},
},
},
},
authserverDeploy: ns.Contain(kube.Deployment(cfg.prefix + "authserver")) {
spec+: {
template+: {
spec+: {
containers_: {
default: kube.Container("default") {
image: cfg.images.acore,
volumeMounts_: {
etc: { mountPath: "/azeroth-server/etc/authserver.conf", subPath: "authserver.conf", },
},
command: [
"/azeroth-server/bin/authserver",
],
},
},
securityContext: {
runAsUser: 999,
runAsGroup: 999,
},
volumes_: {
etc: kube.SecretVolume(wow.etc),
},
},
},
},
},
soapSvc: ns.Contain(kube.Service(cfg.prefix + "worldserver-soap")) {
target_pod:: wow.worldserverDeploy.spec.template,
spec+: {
ports: [
{ name: "soap", port: 7878, targetPort: 7878, protocol: "TCP" },
],
},
},
worldserverSvc: ns.Contain(kube.Service(cfg.prefix + "worldserver")) {
target_pod:: wow.worldserverDeploy.spec.template,
metadata+: {
annotations+: {
"metallb.universe.tf/allow-shared-ip": "%s/%ssvc" % [cfg.namespace, cfg.prefix],
},
},
spec+: {
ports: [
{ name: "worldserver", port: 8085, targetPort: 8085, protocol: "TCP" },
],
type: "LoadBalancer",
externalTrafficPolicy: "Cluster",
loadBalancerIP: cfg.address,
},
},
authserverSvc: ns.Contain(kube.Service(cfg.prefix + "authserver")) {
target_pod:: wow.authserverDeploy.spec.template,
metadata+: {
annotations+: {
"metallb.universe.tf/allow-shared-ip": "%s/%ssvc" % [cfg.namespace, cfg.prefix],
},
},
spec+: {
ports: [
{ name: "authserver", port: 3724, targetPort: 3724, protocol: "TCP" },
],
type: "LoadBalancer",
externalTrafficPolicy: "Cluster",
loadBalancerIP: cfg.address,
},
},
panelSecret: ns.Contain(kube.Secret(cfg.prefix + "panel-secret")) {
data+: {
soapPassword: std.base64(cfg.panel.soap.password),
secret: std.base64(cfg.panel.secret),
oauthSecret: std.base64(cfg.panel.oauth.clientSecret),
"motd.txt": std.base64(cfg.panel.motd),
},
},
panelData: ns.Contain(kube.PersistentVolumeClaim(cfg.prefix + "panel-data")) {
storage:: "128Mi",
storageClass:: "waw-hdd-redundant-3",
},
panelDeploy: ns.Contain(kube.Deployment(cfg.prefix + "panel")) {
spec+: {
template+: {
spec+: {
containers_: {
default: kube.Container("default") {
image: cfg.images.panel,
env_: {
SOAP_PASSWORD: kube.SecretKeyRef(wow.panelSecret, "soapPassword"),
SECRET: kube.SecretKeyRef(wow.panelSecret, "secret"),
OAUTH_SECRET: kube.SecretKeyRef(wow.panelSecret, "oauthSecret"),
},
command: [
"/personal/q3k/wow/panel/panel",
"-listen", "0.0.0.0:8080",
"-db", "/data/panel.db",
"-soap_address", "http://%s" % [wow.soapSvc.host_colon_port],
"-soap_password", "$(SOAP_PASSWORD)",
"-secret", "$(SECRET)",
"-oauth_client_id", cfg.panel.oauth.clientID,
"-oauth_client_secret", "$(OAUTH_SECRET)",
"-oauth_redirect_url", cfg.panel.oauth.redirectURL,
"-motd", "/secret/motd.txt",
],
volumeMounts_: {
data: { mountPath: "/data" },
secret: { mountPath: "/secret" },
},
},
},
volumes_: {
data: kube.PersistentVolumeClaimVolume(wow.panelData),
secret: kube.SecretVolume(wow.panelSecret),
},
},
},
},
},
panelSvc: ns.Contain(kube.Service(cfg.prefix + "panel")) {
target_pod:: wow.panelDeploy.spec.template,
spec+: {
ports: [
{ name: "web", port: 8080, targetPort: 8080, protocol: "TCP" },
],
},
},
panelIngress: ns.Contain(kube.SimpleIngress(cfg.prefix + "panel")) {
hosts:: [cfg.panel.domain],
target:: wow.panelSvc,
},
}