forked from hswaw/hscloud
wow: init
This is a shitty MMORPG server. Private. Do not touch. Change-Id: Iddfce069f5895632d305a73fcaa2d963e25dc600
This commit is contained in:
parent
f18a531f9b
commit
1572e52c19
12 changed files with 1389 additions and 8 deletions
67
WORKSPACE
67
WORKSPACE
|
@ -15,6 +15,7 @@ http_archive(
|
||||||
)
|
)
|
||||||
|
|
||||||
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
|
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
|
||||||
|
|
||||||
protobuf_deps()
|
protobuf_deps()
|
||||||
|
|
||||||
# Force rules_python at a bleeding edge version (for pip3_import).
|
# Force rules_python at a bleeding edge version (for pip3_import).
|
||||||
|
@ -31,7 +32,9 @@ http_archive(
|
||||||
urls = ["https://github.com/tweag/rules_nixpkgs/archive/dc24090573d74adcf38730422941fd69b87682c7.tar.gz"],
|
urls = ["https://github.com/tweag/rules_nixpkgs/archive/dc24090573d74adcf38730422941fd69b87682c7.tar.gz"],
|
||||||
sha256 = "aca86baa64174478c57f74ed09d5c2313113abe94aa3af030486d1b14032d3ed",
|
sha256 = "aca86baa64174478c57f74ed09d5c2313113abe94aa3af030486d1b14032d3ed",
|
||||||
)
|
)
|
||||||
|
|
||||||
load("//third_party/nix:repository_rules.bzl", "hscloud_setup_nix")
|
load("//third_party/nix:repository_rules.bzl", "hscloud_setup_nix")
|
||||||
|
|
||||||
hscloud_setup_nix(
|
hscloud_setup_nix(
|
||||||
revision = "1179841f9a88b8a548f4b11d1a03aa25a790c379",
|
revision = "1179841f9a88b8a548f4b11d1a03aa25a790c379",
|
||||||
sha256 = "8b64041bfb9760de9e797c0a985a4830880c21732489f397e217d877edd9a990",
|
sha256 = "8b64041bfb9760de9e797c0a985a4830880c21732489f397e217d877edd9a990",
|
||||||
|
@ -46,6 +49,7 @@ http_archive(
|
||||||
"https://github.com/bazelbuild/rules_go/releases/download/v0.24.7/rules_go-v0.24.7.tar.gz",
|
"https://github.com/bazelbuild/rules_go/releases/download/v0.24.7/rules_go-v0.24.7.tar.gz",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "bazel_gazelle",
|
name = "bazel_gazelle",
|
||||||
sha256 = "bfd86b3cbe855d6c16c6fce60d76bd51f5c8dbc9cfcaef7a2bb5c1aafd0710e8",
|
sha256 = "bfd86b3cbe855d6c16c6fce60d76bd51f5c8dbc9cfcaef7a2bb5c1aafd0710e8",
|
||||||
|
@ -58,26 +62,30 @@ http_archive(
|
||||||
# Python rules
|
# Python rules
|
||||||
# Important: rules_python must be loaded before protobuf (and grpc) because they load an older version otherwise
|
# Important: rules_python must be loaded before protobuf (and grpc) because they load an older version otherwise
|
||||||
load("@rules_python//python:repositories.bzl", "py_repositories")
|
load("@rules_python//python:repositories.bzl", "py_repositories")
|
||||||
|
|
||||||
py_repositories()
|
py_repositories()
|
||||||
|
|
||||||
load("@rules_python//python:pip.bzl", "pip_repositories")
|
load("@rules_python//python:pip.bzl", "pip_repositories")
|
||||||
|
|
||||||
pip_repositories()
|
pip_repositories()
|
||||||
|
|
||||||
load("@hscloud_pip_imports//:imports.bzl", "hscloud_pip3_import")
|
load("@hscloud_pip_imports//:imports.bzl", "hscloud_pip3_import")
|
||||||
|
|
||||||
hscloud_pip3_import(
|
hscloud_pip3_import(
|
||||||
name = "pydeps",
|
name = "pydeps",
|
||||||
requirements = "//third_party/py:requirements.txt",
|
requirements = "//third_party/py:requirements.txt",
|
||||||
)
|
)
|
||||||
|
|
||||||
load("@pydeps//:requirements.bzl", "pip_install")
|
load("@pydeps//:requirements.bzl", "pip_install")
|
||||||
pip_install()
|
|
||||||
|
|
||||||
|
pip_install()
|
||||||
|
|
||||||
# Setup Go toolchain.
|
# Setup Go toolchain.
|
||||||
# This workspace is generated by hscloud_setup_nixpkgs. It will either call
|
# This workspace is generated by hscloud_setup_nixpkgs. It will either call
|
||||||
# go_register_toolchains() to automagically get Go toolchains from the Internet
|
# go_register_toolchains() to automagically get Go toolchains from the Internet
|
||||||
# or, if nix is present, instead setup a toolchain from nixpkgs.
|
# or, if nix is present, instead setup a toolchain from nixpkgs.
|
||||||
load("@hscloud_go_toolchain//:imports.bzl", "hscloud_go_register_toolchains")
|
load("@hscloud_go_toolchain//:imports.bzl", "hscloud_go_register_toolchains")
|
||||||
|
|
||||||
hscloud_go_register_toolchains()
|
hscloud_go_register_toolchains()
|
||||||
|
|
||||||
# IMPORTANT: match protobuf version above with the one loaded by grpc
|
# IMPORTANT: match protobuf version above with the one loaded by grpc
|
||||||
|
@ -90,19 +98,25 @@ http_archive(
|
||||||
|
|
||||||
# Load grpc deps after Go, to prevent overriding Go toolchains/SDK.
|
# Load grpc deps after Go, to prevent overriding Go toolchains/SDK.
|
||||||
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
|
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
|
||||||
|
|
||||||
grpc_deps()
|
grpc_deps()
|
||||||
|
|
||||||
load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
|
load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
|
||||||
|
|
||||||
grpc_extra_deps()
|
grpc_extra_deps()
|
||||||
|
|
||||||
load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies")
|
load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies")
|
||||||
|
|
||||||
go_rules_dependencies()
|
go_rules_dependencies()
|
||||||
|
|
||||||
# gazelle:repository_macro third_party/go/repositories.bzl%go_repositories
|
# gazelle:repository_macro third_party/go/repositories.bzl%go_repositories
|
||||||
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
|
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")
|
||||||
|
|
||||||
gazelle_dependencies()
|
gazelle_dependencies()
|
||||||
|
|
||||||
# Load Go third-party packages.
|
# Load Go third-party packages.
|
||||||
load("//third_party/go:repositories.bzl", "go_repositories")
|
load("//third_party/go:repositories.bzl", "go_repositories")
|
||||||
|
|
||||||
go_repositories()
|
go_repositories()
|
||||||
|
|
||||||
# Docker rules
|
# Docker rules
|
||||||
|
@ -127,6 +141,7 @@ load(
|
||||||
"@io_bazel_rules_docker//repositories:repositories.bzl",
|
"@io_bazel_rules_docker//repositories:repositories.bzl",
|
||||||
container_repositories = "repositories",
|
container_repositories = "repositories",
|
||||||
)
|
)
|
||||||
|
|
||||||
container_repositories()
|
container_repositories()
|
||||||
|
|
||||||
# Docker base images
|
# Docker base images
|
||||||
|
@ -151,6 +166,7 @@ container_pull(
|
||||||
|
|
||||||
# third_party/factorio
|
# third_party/factorio
|
||||||
load("//third_party/factorio:factorio.bzl", "factorio_repositories")
|
load("//third_party/factorio:factorio.bzl", "factorio_repositories")
|
||||||
|
|
||||||
factorio_repositories()
|
factorio_repositories()
|
||||||
|
|
||||||
# For devtools/gerrit/gerrit-oauth-provider and gerrit OWNERS plugin
|
# For devtools/gerrit/gerrit-oauth-provider and gerrit OWNERS plugin
|
||||||
|
@ -159,14 +175,17 @@ git_repository(
|
||||||
name = "com_googlesource_gerrit_bazlets",
|
name = "com_googlesource_gerrit_bazlets",
|
||||||
remote = "https://gerrit.googlesource.com/bazlets",
|
remote = "https://gerrit.googlesource.com/bazlets",
|
||||||
commit = "1d381f01c853e2c02ae35430a8e294e485635d62",
|
commit = "1d381f01c853e2c02ae35430a8e294e485635d62",
|
||||||
shallow_since = "1559431096 -0400"
|
shallow_since = "1559431096 -0400",
|
||||||
)
|
)
|
||||||
|
|
||||||
load("@com_googlesource_gerrit_bazlets//:gerrit_api.bzl", "gerrit_api")
|
load("@com_googlesource_gerrit_bazlets//:gerrit_api.bzl", "gerrit_api")
|
||||||
|
|
||||||
gerrit_api()
|
gerrit_api()
|
||||||
|
|
||||||
load("@com_googlesource_gerrit_bazlets//tools:maven_jar.bzl", gerrit_maven_jar="maven_jar", GERRIT="GERRIT")
|
load("@com_googlesource_gerrit_bazlets//tools:maven_jar.bzl", gerrit_maven_jar = "maven_jar", "GERRIT")
|
||||||
|
|
||||||
PROLOG_VERS = "1.4.3"
|
PROLOG_VERS = "1.4.3"
|
||||||
|
|
||||||
JACKSON_VER = "2.9.7"
|
JACKSON_VER = "2.9.7"
|
||||||
|
|
||||||
gerrit_maven_jar(
|
gerrit_maven_jar(
|
||||||
|
@ -186,21 +205,25 @@ gerrit_maven_jar(
|
||||||
artifact = "com.fasterxml.jackson.core:jackson-core:" + JACKSON_VER,
|
artifact = "com.fasterxml.jackson.core:jackson-core:" + JACKSON_VER,
|
||||||
sha1 = "4b7f0e0dc527fab032e9800ed231080fdc3ac015",
|
sha1 = "4b7f0e0dc527fab032e9800ed231080fdc3ac015",
|
||||||
)
|
)
|
||||||
|
|
||||||
gerrit_maven_jar(
|
gerrit_maven_jar(
|
||||||
name = "jackson-databind",
|
name = "jackson-databind",
|
||||||
artifact = "com.fasterxml.jackson.core:jackson-databind:" + JACKSON_VER,
|
artifact = "com.fasterxml.jackson.core:jackson-databind:" + JACKSON_VER,
|
||||||
sha1 = "e6faad47abd3179666e89068485a1b88a195ceb7",
|
sha1 = "e6faad47abd3179666e89068485a1b88a195ceb7",
|
||||||
)
|
)
|
||||||
|
|
||||||
gerrit_maven_jar(
|
gerrit_maven_jar(
|
||||||
name = "jackson-annotations",
|
name = "jackson-annotations",
|
||||||
artifact = "com.fasterxml.jackson.core:jackson-annotations:" + JACKSON_VER,
|
artifact = "com.fasterxml.jackson.core:jackson-annotations:" + JACKSON_VER,
|
||||||
sha1 = "4b838e5c4fc17ac02f3293e9a558bb781a51c46d",
|
sha1 = "4b838e5c4fc17ac02f3293e9a558bb781a51c46d",
|
||||||
)
|
)
|
||||||
|
|
||||||
gerrit_maven_jar(
|
gerrit_maven_jar(
|
||||||
name = "jackson-dataformat-yaml",
|
name = "jackson-dataformat-yaml",
|
||||||
artifact = "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:" + JACKSON_VER,
|
artifact = "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:" + JACKSON_VER,
|
||||||
sha1 = "a428edc4bb34a2da98a50eb759c26941d4e85960",
|
sha1 = "a428edc4bb34a2da98a50eb759c26941d4e85960",
|
||||||
)
|
)
|
||||||
|
|
||||||
gerrit_maven_jar(
|
gerrit_maven_jar(
|
||||||
name = "snakeyaml",
|
name = "snakeyaml",
|
||||||
artifact = "org.yaml:snakeyaml:1.23",
|
artifact = "org.yaml:snakeyaml:1.23",
|
||||||
|
@ -214,6 +237,7 @@ gerrit_maven_jar(
|
||||||
repository = GERRIT,
|
repository = GERRIT,
|
||||||
sha1 = "d5206556cbc76ffeab21313ffc47b586a1efbcbb",
|
sha1 = "d5206556cbc76ffeab21313ffc47b586a1efbcbb",
|
||||||
)
|
)
|
||||||
|
|
||||||
gerrit_maven_jar(
|
gerrit_maven_jar(
|
||||||
name = "prolog-compiler",
|
name = "prolog-compiler",
|
||||||
artifact = "com.googlecode.prolog-cafe:prolog-compiler:" + PROLOG_VERS,
|
artifact = "com.googlecode.prolog-cafe:prolog-compiler:" + PROLOG_VERS,
|
||||||
|
@ -221,6 +245,7 @@ gerrit_maven_jar(
|
||||||
repository = GERRIT,
|
repository = GERRIT,
|
||||||
sha1 = "f37032cf1dec3e064427745bc59da5a12757a3b2",
|
sha1 = "f37032cf1dec3e064427745bc59da5a12757a3b2",
|
||||||
)
|
)
|
||||||
|
|
||||||
gerrit_maven_jar(
|
gerrit_maven_jar(
|
||||||
name = "prolog-io",
|
name = "prolog-io",
|
||||||
artifact = "com.googlecode.prolog-cafe:prolog-io:" + PROLOG_VERS,
|
artifact = "com.googlecode.prolog-cafe:prolog-io:" + PROLOG_VERS,
|
||||||
|
@ -240,6 +265,7 @@ http_archive(
|
||||||
)
|
)
|
||||||
|
|
||||||
RULES_JVM_EXTERNAL_TAG = "3.0"
|
RULES_JVM_EXTERNAL_TAG = "3.0"
|
||||||
|
|
||||||
RULES_JVM_EXTERNAL_SHA = "62133c125bf4109dfd9d2af64830208356ce4ef8b165a6ef15bbff7460b35c3a"
|
RULES_JVM_EXTERNAL_SHA = "62133c125bf4109dfd9d2af64830208356ce4ef8b165a6ef15bbff7460b35c3a"
|
||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
|
@ -258,7 +284,7 @@ maven_install(
|
||||||
"org.spigotmc:spigot-api:1.15.2-R0.1-SNAPSHOT",
|
"org.spigotmc:spigot-api:1.15.2-R0.1-SNAPSHOT",
|
||||||
"io.grpc:grpc-netty-shaded:1.29.0",
|
"io.grpc:grpc-netty-shaded:1.29.0",
|
||||||
"io.grpc:grpc-services:1.29.0",
|
"io.grpc:grpc-services:1.29.0",
|
||||||
] + IO_GRPC_GRPC_JAVA_ARTIFACTS,
|
] + IO_GRPC_GRPC_JAVA_ARTIFACTS,
|
||||||
generate_compat_repositories = True,
|
generate_compat_repositories = True,
|
||||||
override_targets = IO_GRPC_GRPC_JAVA_OVERRIDE_TARGETS,
|
override_targets = IO_GRPC_GRPC_JAVA_OVERRIDE_TARGETS,
|
||||||
repositories = [
|
repositories = [
|
||||||
|
@ -270,12 +296,15 @@ maven_install(
|
||||||
)
|
)
|
||||||
|
|
||||||
load("@maven//:defs.bzl", "pinned_maven_install")
|
load("@maven//:defs.bzl", "pinned_maven_install")
|
||||||
|
|
||||||
pinned_maven_install()
|
pinned_maven_install()
|
||||||
|
|
||||||
load("@maven//:compat.bzl", "compat_repositories")
|
load("@maven//:compat.bzl", "compat_repositories")
|
||||||
|
|
||||||
compat_repositories()
|
compat_repositories()
|
||||||
|
|
||||||
load("@io_grpc_grpc_java//:repositories.bzl", "grpc_java_repositories")
|
load("@io_grpc_grpc_java//:repositories.bzl", "grpc_java_repositories")
|
||||||
|
|
||||||
grpc_java_repositories()
|
grpc_java_repositories()
|
||||||
|
|
||||||
# Gerrit OWNERS plugins external repositories
|
# Gerrit OWNERS plugins external repositories
|
||||||
|
@ -284,12 +313,13 @@ git_repository(
|
||||||
name = "com_googlesource_gerrit_plugin_owners",
|
name = "com_googlesource_gerrit_plugin_owners",
|
||||||
remote = "https://gerrit.googlesource.com/plugins/owners/",
|
remote = "https://gerrit.googlesource.com/plugins/owners/",
|
||||||
commit = "5e691e87b8c00a04d261a8dd313f4d16c54797e8",
|
commit = "5e691e87b8c00a04d261a8dd313f4d16c54797e8",
|
||||||
shallow_since = "1559729722 +0900"
|
shallow_since = "1559729722 +0900",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Go image repos for Docker
|
# Go image repos for Docker
|
||||||
|
|
||||||
load("@io_bazel_rules_docker//go:image.bzl", go_image_repositories = "repositories")
|
load("@io_bazel_rules_docker//go:image.bzl", go_image_repositories = "repositories")
|
||||||
|
|
||||||
go_image_repositories()
|
go_image_repositories()
|
||||||
|
|
||||||
# oniguruma, with build from //third_party/oniguruma
|
# oniguruma, with build from //third_party/oniguruma
|
||||||
|
@ -311,3 +341,24 @@ http_archive(
|
||||||
sha256 = "5de8c8e29aaa3fb9cc6b47bb27299f271354ebb72514e3accadc7d38b5bbaa72",
|
sha256 = "5de8c8e29aaa3fb9cc6b47bb27299f271354ebb72514e3accadc7d38b5bbaa72",
|
||||||
build_file = "@hscloud//third_party/jq:BUILD.external",
|
build_file = "@hscloud//third_party/jq:BUILD.external",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
go_repository(
|
||||||
|
name = "com_github_gorilla_sessions",
|
||||||
|
importpath = "github.com/gorilla/sessions",
|
||||||
|
sum = "h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI=",
|
||||||
|
version = "v1.2.1",
|
||||||
|
)
|
||||||
|
|
||||||
|
go_repository(
|
||||||
|
name = "com_github_boltdb_bolt",
|
||||||
|
importpath = "github.com/boltdb/bolt",
|
||||||
|
sum = "h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=",
|
||||||
|
version = "v1.3.1",
|
||||||
|
)
|
||||||
|
|
||||||
|
go_repository(
|
||||||
|
name = "com_github_gorilla_securecookie",
|
||||||
|
importpath = "github.com/gorilla/securecookie",
|
||||||
|
sum = "h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=",
|
||||||
|
version = "v1.1.1",
|
||||||
|
)
|
||||||
|
|
301
personal/q3k/wow/lib.libsonnet
Normal file
301
personal/q3k/wow/lib.libsonnet
Normal file
|
@ -0,0 +1,301 @@
|
||||||
|
local kube = import "../../../kube/kube.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:1607033741-f18a531f9b84c5b33653c8db5d64aaa0af337541",
|
||||||
|
},
|
||||||
|
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")) {
|
||||||
|
spec+: {
|
||||||
|
storageClassName: "waw-hdd-redundant-3",
|
||||||
|
accessModes: ["ReadWriteOnce"],
|
||||||
|
resources: {
|
||||||
|
requests: {
|
||||||
|
storage: "50Gi",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// 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")) {
|
||||||
|
spec+: {
|
||||||
|
storageClassName: "waw-hdd-redundant-3",
|
||||||
|
accessModes: ["ReadWriteOnce"],
|
||||||
|
resources: {
|
||||||
|
requests: {
|
||||||
|
storage: "128Mi",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
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.Ingress(cfg.prefix + "panel")) {
|
||||||
|
metadata+: {
|
||||||
|
annotations+: {
|
||||||
|
"kubernetes.io/tls-acme": "true",
|
||||||
|
"certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
spec+: {
|
||||||
|
tls: [
|
||||||
|
{
|
||||||
|
hosts: [cfg.panel.domain],
|
||||||
|
secretName: cfg.prefix + "panel-tls",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
host: cfg.panel.domain,
|
||||||
|
http: {
|
||||||
|
paths: [
|
||||||
|
{ path: "/", backend: wow.panelSvc.name_port },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
51
personal/q3k/wow/panel/BUILD.bazel
Normal file
51
personal/q3k/wow/panel/BUILD.bazel
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
|
||||||
|
load("@io_bazel_rules_docker//container:container.bzl", "container_image", "container_layer", "container_push")
|
||||||
|
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = [
|
||||||
|
"main.go",
|
||||||
|
"soap.go",
|
||||||
|
],
|
||||||
|
importpath = "code.hackerspace.pl/hscloud/personal/q3k/wow/panel",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = [
|
||||||
|
"@com_github_boltdb_bolt//:go_default_library",
|
||||||
|
"@com_github_coreos_go_oidc//:go_default_library",
|
||||||
|
"@com_github_golang_glog//:go_default_library",
|
||||||
|
"@com_github_gorilla_sessions//:go_default_library",
|
||||||
|
"@org_golang_x_oauth2//:go_default_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
go_binary(
|
||||||
|
name = "panel",
|
||||||
|
embed = [":go_default_library"],
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
container_layer(
|
||||||
|
name = "layer_bin",
|
||||||
|
files = [
|
||||||
|
":panel",
|
||||||
|
],
|
||||||
|
directory = "/personal/q3k/wow/panel/",
|
||||||
|
)
|
||||||
|
|
||||||
|
container_image(
|
||||||
|
name = "runtime",
|
||||||
|
base = "@prodimage-bionic//image",
|
||||||
|
layers = [
|
||||||
|
":layer_bin",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
container_push(
|
||||||
|
name = "push",
|
||||||
|
image = ":runtime",
|
||||||
|
format = "Docker",
|
||||||
|
registry = "registry.k0.hswaw.net",
|
||||||
|
repository = "q3k/panel",
|
||||||
|
tag = "{BUILD_TIMESTAMP}-{STABLE_GIT_COMMIT}",
|
||||||
|
)
|
466
personal/q3k/wow/panel/main.go
Normal file
466
personal/q3k/wow/panel/main.go
Normal file
|
@ -0,0 +1,466 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/boltdb/bolt"
|
||||||
|
oidc "github.com/coreos/go-oidc"
|
||||||
|
"github.com/golang/glog"
|
||||||
|
"github.com/gorilla/sessions"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
flagSOAPAddress string
|
||||||
|
flagSOAPUsername string
|
||||||
|
flagSOAPPassword string
|
||||||
|
flagListen string
|
||||||
|
flagSecret string
|
||||||
|
flagOAuthClientID string
|
||||||
|
flagOAuthClientSecret string
|
||||||
|
flagOAuthRedirectURL string
|
||||||
|
flagDB string
|
||||||
|
flagMOTD string
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flag.Set("logtostderr", "true")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.StringVar(&flagSOAPAddress, "soap_address", "http://127.0.0.1:7878", "Address of AC SOAP server")
|
||||||
|
flag.StringVar(&flagSOAPUsername, "soap_username", "test1", "SOAP username")
|
||||||
|
flag.StringVar(&flagSOAPPassword, "soap_password", "", "SOAP password")
|
||||||
|
flag.StringVar(&flagListen, "listen", "127.0.0.1:8080", "HTTP listen address")
|
||||||
|
flag.StringVar(&flagSecret, "secret", "", "Cookie secret")
|
||||||
|
flag.StringVar(&flagOAuthClientID, "oauth_client_id", "", "OAuth client ID")
|
||||||
|
flag.StringVar(&flagOAuthClientSecret, "oauth_client_secret", "", "OAuth client secret")
|
||||||
|
flag.StringVar(&flagOAuthRedirectURL, "oauth_redirect_url", "", "OAuth redirect URL")
|
||||||
|
flag.StringVar(&flagDB, "db", "db.db", "Path to database")
|
||||||
|
flag.StringVar(&flagMOTD, "motd", "", "Path to MOTD")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if flagSecret == "" {
|
||||||
|
glog.Exitf("-secret must be set")
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
var motd []byte
|
||||||
|
if flagMOTD == "" {
|
||||||
|
glog.Warningf("no MOTD defined, set -motd to get one")
|
||||||
|
} else {
|
||||||
|
motd, err = ioutil.ReadFile(flagMOTD)
|
||||||
|
if err != nil {
|
||||||
|
glog.Exitf("cannot read MOTD %q: %v", flagMOTD, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
db, err := bolt.Open(flagDB, 0600, nil)
|
||||||
|
if err != nil {
|
||||||
|
glog.Exitf("opening database failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
provider, err := oidc.NewProvider(context.Background(), "https://sso.hackerspace.pl")
|
||||||
|
if err != nil {
|
||||||
|
glog.Exitf("newprovider: %v", err)
|
||||||
|
}
|
||||||
|
oauth2Config := oauth2.Config{
|
||||||
|
ClientID: flagOAuthClientID,
|
||||||
|
ClientSecret: flagOAuthClientSecret,
|
||||||
|
RedirectURL: flagOAuthRedirectURL,
|
||||||
|
|
||||||
|
// Discovery returns the OAuth2 endpoints.
|
||||||
|
Endpoint: provider.Endpoint(),
|
||||||
|
|
||||||
|
// "openid" is a required scope for OpenID Connect flows.
|
||||||
|
Scopes: []string{oidc.ScopeOpenID, "profile:read"},
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.Update(func(tx *bolt.Tx) error {
|
||||||
|
for _, name := range []string{
|
||||||
|
"emailToAccount",
|
||||||
|
} {
|
||||||
|
_, err := tx.CreateBucketIfNotExists([]byte(name))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("create bucket %q: %s", name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
glog.Exitf("db setup failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s := &server{
|
||||||
|
db: db,
|
||||||
|
store: sessions.NewCookieStore([]byte(flagSecret)),
|
||||||
|
oauth2: &oauth2Config,
|
||||||
|
motd: string(motd),
|
||||||
|
}
|
||||||
|
|
||||||
|
http.HandleFunc("/", s.viewIndex)
|
||||||
|
http.HandleFunc("/login", s.viewLogin)
|
||||||
|
http.HandleFunc("/oauth", s.viewOauth)
|
||||||
|
http.HandleFunc("/callback", s.viewOauthCallback)
|
||||||
|
http.HandleFunc("/setup", s.viewOauthSetup)
|
||||||
|
http.HandleFunc("/reset", s.viewReset)
|
||||||
|
http.HandleFunc("/logout", s.viewLogout)
|
||||||
|
|
||||||
|
err = http.ListenAndServe(flagListen, nil)
|
||||||
|
if err != nil {
|
||||||
|
glog.Exitf("ListenAndServe: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type server struct {
|
||||||
|
db *bolt.DB
|
||||||
|
store *sessions.CookieStore
|
||||||
|
oauth2 *oauth2.Config
|
||||||
|
motd string
|
||||||
|
|
||||||
|
onlineLock sync.RWMutex
|
||||||
|
onlineData []playerinfo
|
||||||
|
onlineDeadline time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
tLogin = template.Must(template.New("login").Parse(`<html>
|
||||||
|
<title>super wow - who are you?</title>
|
||||||
|
<body>
|
||||||
|
<pre>
|
||||||
|
|
||||||
|
___ _ _ _ __ ___ _ __ __ _______ __
|
||||||
|
/ __| | | | '_ \ / _ \ '__| \ \ /\ / / _ \ \ /\ / /
|
||||||
|
\__ \ |_| | |_) | __/ | \ V V / (_) \ V V /
|
||||||
|
|___/\__,_| .__/ \___|_| \_/\_/ \___/ \_/\_/
|
||||||
|
|_|
|
||||||
|
_ _ _ _ _ _
|
||||||
|
| | _____ | | ___ (_)___ _ _ __ | | _____ | |_ _| |__
|
||||||
|
| |/ / _ \| |/ _ \_ / _' | '_ \| |/ / _ \ | | | | | '_ \
|
||||||
|
| < (_) | | __// / (_| | | | | < (_) | | | |_| | |_) |
|
||||||
|
|_|\_\___/|_|\___/___\__,_|_| |_|_|\_\___/ |_|\__,_|_.__/
|
||||||
|
|
||||||
|
_ _ __
|
||||||
|
| | _____ | | ___ __ _ ___ \ \
|
||||||
|
| |/ / _ \| |/ _ \/ _' |/ _ \ (_) |
|
||||||
|
| < (_) | | __/ (_| | (_) | _| |
|
||||||
|
|_|\_\___/|_|\___|\__, |\___/ (_) |
|
||||||
|
|___/ /_/
|
||||||
|
|
||||||
|
</pre>
|
||||||
|
<a href="/oauth">Sign in (or create new account) with HSWAW SSO</a>.<br/>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Not a hswaw member? Talk to q3k.
|
||||||
|
</p>
|
||||||
|
</body>`))
|
||||||
|
tSetup = template.Must(template.New("setup").Parse(`<html>
|
||||||
|
<title>super wow - setup account</title>
|
||||||
|
<body>
|
||||||
|
<b>hi, please provide details for your new WoW account</b><br/>
|
||||||
|
pick any username you want, pick a 3-16 character password that isn't the same as your sso password (duh)<br />
|
||||||
|
(this isn't your character name, this will only be used to log into WoW)
|
||||||
|
{{ if .Error }}
|
||||||
|
<br /><b>error</b>: {{ .Error }}<br />
|
||||||
|
{{ end }}
|
||||||
|
<form method="post" action="/setup">
|
||||||
|
username:<input name="username" value={{ .Username }}></input><br/>
|
||||||
|
password:<input name="password" type="password"></input><br/>
|
||||||
|
<input type=submit value="create account"/>
|
||||||
|
</form>
|
||||||
|
</body>`))
|
||||||
|
tIndex = template.Must(template.New("index").Parse(`<html>
|
||||||
|
<title>super wow</title>
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
table, th, td {
|
||||||
|
background-color: #eee;
|
||||||
|
padding: 0.2em 0.4em 0.2em 0.4em;
|
||||||
|
}
|
||||||
|
table th {
|
||||||
|
background-color: #c0c0c0;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
background-color: #fff;
|
||||||
|
border-spacing: 0.2em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<b>Hello, {{ .Username }}.</b></br>
|
||||||
|
<a href="/logout">Log out.</a><br />
|
||||||
|
{{ .MOTD }}
|
||||||
|
<p>
|
||||||
|
Your account name is {{ .Username }}. Use the password that you entered when logging in via SSO for the first time, or <form action="/reset" method="POST"><input name="password" type="password" /><input type="submit" value="set a new password"/>.</form>
|
||||||
|
</p>
|
||||||
|
<b>Currently in-game:</b>
|
||||||
|
<table>
|
||||||
|
<tr><th>Account</th><th>Character</th></tr>
|
||||||
|
{{ range .Online }}
|
||||||
|
<tr><td>{{ .Account }}</td><td>{{ .Character }}</td></tr>
|
||||||
|
{{ end }}
|
||||||
|
</table>
|
||||||
|
</body>`))
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *server) session(r *http.Request) *sessions.Session {
|
||||||
|
session, _ := s.store.Get(r, sessionName)
|
||||||
|
return session
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) sessionGet(r *http.Request, k string) string {
|
||||||
|
v, ok := s.session(r).Values[k]
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
v2, ok := v.(string)
|
||||||
|
if !ok {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return v2
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) sessionPut(w http.ResponseWriter, r *http.Request, k, v string) {
|
||||||
|
session := s.session(r)
|
||||||
|
session.Values[k] = v
|
||||||
|
session.Save(r, w)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) online(ctx context.Context) []playerinfo {
|
||||||
|
s.onlineLock.RLock()
|
||||||
|
if s.onlineData == nil || time.Now().After(s.onlineDeadline) {
|
||||||
|
s.onlineLock.RUnlock()
|
||||||
|
s.onlineLock.Lock()
|
||||||
|
data, err := onlinelist(ctx)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("onlinelist fatch failed: %v", err)
|
||||||
|
s.onlineDeadline = time.Now().Add(10 * time.Second)
|
||||||
|
} else {
|
||||||
|
s.onlineData = data
|
||||||
|
s.onlineDeadline = time.Now().Add(60 * time.Second)
|
||||||
|
}
|
||||||
|
s.onlineLock.Unlock()
|
||||||
|
s.onlineLock.RLock()
|
||||||
|
}
|
||||||
|
|
||||||
|
res := make([]playerinfo, len(s.onlineData))
|
||||||
|
for i, pi := range s.onlineData {
|
||||||
|
res[i] = pi
|
||||||
|
}
|
||||||
|
s.onlineLock.RUnlock()
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) viewIndex(w http.ResponseWriter, r *http.Request) {
|
||||||
|
account := s.sessionGet(r, "account")
|
||||||
|
if account == "" {
|
||||||
|
http.Redirect(w, r, "/login", 302)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := tIndex.Execute(w, map[string]interface{}{
|
||||||
|
"Username": account,
|
||||||
|
"Online": s.online(r.Context()),
|
||||||
|
"MOTD": template.HTML(s.motd),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("/: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sessionName = "wow"
|
||||||
|
|
||||||
|
func (s *server) viewLogin(w http.ResponseWriter, r *http.Request) {
|
||||||
|
account := s.sessionGet(r, "account")
|
||||||
|
if account != "" {
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := tLogin.Execute(w, nil)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("/login: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) viewOauth(w http.ResponseWriter, r *http.Request) {
|
||||||
|
stateBytes := make([]byte, 8)
|
||||||
|
_, err := rand.Read(stateBytes)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("/oauth: random: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
state := hex.EncodeToString(stateBytes)
|
||||||
|
s.sessionPut(w, r, "ostate", state)
|
||||||
|
url := s.oauth2.AuthCodeURL(state)
|
||||||
|
http.Redirect(w, r, url, http.StatusTemporaryRedirect)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) viewOauthCallback(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.FormValue("errors") != "" {
|
||||||
|
fmt.Fprintf(w, "Errors: %s", r.FormValue("errors"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
state := s.sessionGet(r, "ostate")
|
||||||
|
if state == "" {
|
||||||
|
glog.Errorf("No state")
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if state != r.FormValue("state") {
|
||||||
|
glog.Errorf("Invalid state")
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
oauth2Token, err := s.oauth2.Exchange(r.Context(), r.FormValue("code"))
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("Exchange failed: %v", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
client := s.oauth2.Client(r.Context(), oauth2Token)
|
||||||
|
res, err := client.Get("https://sso.hackerspace.pl/api/1/userinfo")
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("Userinfo failed: %v", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
data, _ := ioutil.ReadAll(res.Body)
|
||||||
|
|
||||||
|
ui := userinfo{}
|
||||||
|
err = json.Unmarshal(data, &ui)
|
||||||
|
if err != nil || ui.Email == "" {
|
||||||
|
glog.Errorf("Userinfo unarshal failed: %v", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
account, err := s.accountForEmail(ui.Email)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("account get failed: %v", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if account != "" {
|
||||||
|
s.sessionPut(w, r, "account", account)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
} else {
|
||||||
|
s.sessionPut(w, r, "email", ui.Email)
|
||||||
|
http.Redirect(w, r, "/setup", 302)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) viewOauthSetup(w http.ResponseWriter, r *http.Request) {
|
||||||
|
email := s.sessionGet(r, "email")
|
||||||
|
if email == "" {
|
||||||
|
glog.Errorf("No email")
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if r.Method == "GET" {
|
||||||
|
tSetup.Execute(w, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
username := r.FormValue("username")
|
||||||
|
password := r.FormValue("password")
|
||||||
|
if !reAccount.MatchString(username) {
|
||||||
|
tSetup.Execute(w, map[string]string{
|
||||||
|
"Username": username,
|
||||||
|
"Error": "Invalid username - must be 3-16 a-z 0-9 - _",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !rePassword.MatchString(password) {
|
||||||
|
tSetup.Execute(w, map[string]string{
|
||||||
|
"Username": username,
|
||||||
|
"Error": "Invalid password - must be 3-16 a-z A-Z 0-9 - _",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// this races. ugh. no way to list users. yolo.
|
||||||
|
err := createAccount(r.Context(), username, password)
|
||||||
|
if err != nil {
|
||||||
|
tSetup.Execute(w, map[string]string{
|
||||||
|
"Username": username,
|
||||||
|
"Error": "Account already exists, pick a different username",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.db.Update(func(tx *bolt.Tx) error {
|
||||||
|
b := tx.Bucket([]byte("emailToAccount"))
|
||||||
|
v := string(b.Get([]byte(email)))
|
||||||
|
if v != "" {
|
||||||
|
s.sessionPut(w, r, "account", v)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
b.Put([]byte(email), []byte(username))
|
||||||
|
s.sessionPut(w, r, "account", username)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("setup tx: %v", err)
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (s *server) viewReset(w http.ResponseWriter, r *http.Request) {
|
||||||
|
account := s.sessionGet(r, "account")
|
||||||
|
if account == "" {
|
||||||
|
glog.Errorf("No account")
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
password := r.FormValue("password")
|
||||||
|
if !rePassword.MatchString(password) {
|
||||||
|
fmt.Fprintf(w, "pick a 3-16 password with not too many special chars")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// this races. ugh. no way to list users. yolo.
|
||||||
|
err := ensureAccount(r.Context(), account, password)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("ensureAccount(%q, _): %v", account, err)
|
||||||
|
fmt.Fprintf(w, "something went wrong, lol")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, "new password set.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) viewLogout(w http.ResponseWriter, r *http.Request) {
|
||||||
|
s.sessionPut(w, r, "account", "")
|
||||||
|
s.sessionPut(w, r, "email", "")
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *server) accountForEmail(email string) (string, error) {
|
||||||
|
res := ""
|
||||||
|
err := s.db.View(func(tx *bolt.Tx) error {
|
||||||
|
b := tx.Bucket([]byte("emailToAccount"))
|
||||||
|
v := b.Get([]byte(email))
|
||||||
|
res = string(v)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type userinfo struct {
|
||||||
|
Email string `json:"email"`
|
||||||
|
}
|
215
personal/q3k/wow/panel/soap.go
Normal file
215
personal/q3k/wow/panel/soap.go
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Envelope struct {
|
||||||
|
XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"`
|
||||||
|
Body *Body
|
||||||
|
}
|
||||||
|
|
||||||
|
type Body struct {
|
||||||
|
XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"`
|
||||||
|
Request *Request
|
||||||
|
Response *Response
|
||||||
|
Fault *Fault
|
||||||
|
}
|
||||||
|
|
||||||
|
type Request struct {
|
||||||
|
XMLName xml.Name `xml:"urn:AC executeCommand"`
|
||||||
|
Command string `xml:"command"`
|
||||||
|
}
|
||||||
|
type Response struct {
|
||||||
|
XMLName xml.Name `xml:"urn:AC executeCommandResponse"`
|
||||||
|
Result string `xml:"result"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Fault struct {
|
||||||
|
XMLName xml.Name `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault"`
|
||||||
|
Code string `xml:"faultcode"`
|
||||||
|
String string `xml:"faultstring"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type commandRes struct {
|
||||||
|
result string
|
||||||
|
fault string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
reAccount = regexp.MustCompile(`^[a-z0-9\-_\.]{3,16}$`)
|
||||||
|
rePassword = regexp.MustCompile(`^[a-zA-Z0-9\-_\.]{3,16}$`)
|
||||||
|
)
|
||||||
|
|
||||||
|
func createAccount(ctx context.Context, name, password string) error {
|
||||||
|
if !reAccount.MatchString(name) {
|
||||||
|
return fmt.Errorf("invalid account name")
|
||||||
|
}
|
||||||
|
if !rePassword.MatchString(password) {
|
||||||
|
return fmt.Errorf("invalid password name")
|
||||||
|
}
|
||||||
|
res, err := runCommand(ctx, fmt.Sprintf("account create %s %s", name, password))
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("Account create: %v", err)
|
||||||
|
return fmt.Errorf("server unavailable")
|
||||||
|
}
|
||||||
|
if res.result == fmt.Sprintf("Account created: %s", name) {
|
||||||
|
glog.Infof("Created account %q", name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
glog.Errorf("Account create fault: %q/%q", res.fault, res.result)
|
||||||
|
return fmt.Errorf("server error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ensureAccount(ctx context.Context, name, password string) error {
|
||||||
|
if !reAccount.MatchString(name) {
|
||||||
|
return fmt.Errorf("invalid account name")
|
||||||
|
}
|
||||||
|
if !rePassword.MatchString(password) {
|
||||||
|
return fmt.Errorf("invalid password name")
|
||||||
|
}
|
||||||
|
res, err := runCommand(ctx, fmt.Sprintf("account create %s %s", name, password))
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("Account create: %v", err)
|
||||||
|
return fmt.Errorf("server unavailable")
|
||||||
|
}
|
||||||
|
if res.result == fmt.Sprintf("Account created: %s", name) {
|
||||||
|
glog.Infof("Created account %q", name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if res.fault != "Account with this name already exist!" {
|
||||||
|
glog.Errorf("Account create fault: %q/%q", res.fault, res.result)
|
||||||
|
return fmt.Errorf("server error")
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err = runCommand(ctx, fmt.Sprintf("account set password %s %s %s", name, password, password))
|
||||||
|
if res.result == "The password was changed" {
|
||||||
|
glog.Infof("Updated password for account %q", name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
glog.Infof("password update fault: %q/%q", res.fault, res.result)
|
||||||
|
return fmt.Errorf("server error")
|
||||||
|
}
|
||||||
|
|
||||||
|
func runCommand(ctx context.Context, cmd string) (*commandRes, error) {
|
||||||
|
data, err := xml.Marshal(&Envelope{
|
||||||
|
Body: &Body{
|
||||||
|
Request: &Request{
|
||||||
|
Command: cmd,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("marshal: %w", err)
|
||||||
|
}
|
||||||
|
buf := bytes.NewBuffer(data)
|
||||||
|
req, err := http.NewRequestWithContext(ctx, "POST", flagSOAPAddress, buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("NewRequest(POST, %q): %w", flagSOAPAddress, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
req.SetBasicAuth(flagSOAPUsername, flagSOAPPassword)
|
||||||
|
resp, err := http.DefaultClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("req.Do: %w", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
respBytes, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("ReadAll response: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
respEnvelope := Envelope{}
|
||||||
|
err = xml.Unmarshal(respBytes, &respEnvelope)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unmarshal: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if respEnvelope.Body == nil {
|
||||||
|
return nil, fmt.Errorf("no body returned")
|
||||||
|
}
|
||||||
|
|
||||||
|
if respEnvelope.Body.Fault != nil {
|
||||||
|
fault := respEnvelope.Body.Fault
|
||||||
|
if fault.Code == "SOAP-ENV:Client" {
|
||||||
|
return &commandRes{
|
||||||
|
fault: strings.TrimSpace(fault.String),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("SOAP error %q: %v", fault.Code, fault.String)
|
||||||
|
}
|
||||||
|
|
||||||
|
result := ""
|
||||||
|
if respEnvelope.Body.Response != nil {
|
||||||
|
result = respEnvelope.Body.Response.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
return &commandRes{
|
||||||
|
result: strings.TrimSpace(result),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type playerinfo struct {
|
||||||
|
Account string
|
||||||
|
Character string
|
||||||
|
}
|
||||||
|
|
||||||
|
func onlinelist(ctx context.Context) ([]playerinfo, error) {
|
||||||
|
res, err := runCommand(ctx, "account onlinelist")
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("onlinelist: %v", err)
|
||||||
|
return nil, fmt.Errorf("server unavailable")
|
||||||
|
}
|
||||||
|
if res.fault != "" {
|
||||||
|
glog.Errorf("onlinelist fault: %q", res.fault)
|
||||||
|
return nil, fmt.Errorf("server unavailable")
|
||||||
|
}
|
||||||
|
|
||||||
|
lines := strings.Split(res.result, "\n")
|
||||||
|
header := false
|
||||||
|
var pi []playerinfo
|
||||||
|
for _, line := range lines {
|
||||||
|
switch {
|
||||||
|
case strings.HasPrefix(line, "-="):
|
||||||
|
continue
|
||||||
|
case strings.HasPrefix(line, "-["):
|
||||||
|
default:
|
||||||
|
glog.Warningf("unparseable line %q", line)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !header {
|
||||||
|
header = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if len(line) != 69 {
|
||||||
|
glog.Warningf("wrong line length: %q", line)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
account := strings.ToLower(strings.TrimSpace(line[2:18]))
|
||||||
|
if line[18:20] != "][" {
|
||||||
|
glog.Warningf("unparseable line %q (wrong sep1)", line)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
character := strings.TrimSpace(line[20:32])
|
||||||
|
if line[32:34] != "][" {
|
||||||
|
glog.Warningf("unparseable line %q (wrong sep2)", line)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
pi = append(pi, playerinfo{
|
||||||
|
Account: account,
|
||||||
|
Character: character,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
glog.Infof("Onlinelist: %v", pi)
|
||||||
|
return pi, nil
|
||||||
|
}
|
90
personal/q3k/wow/prod.jsonnet
Normal file
90
personal/q3k/wow/prod.jsonnet
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
local wow = import "lib.libsonnet";
|
||||||
|
local mysql = import "../../../kube/mysql.libsonnet";
|
||||||
|
|
||||||
|
{
|
||||||
|
q3k: wow {
|
||||||
|
local sqlPassword = (std.split(importstr "secrets/plain/mysql-root-password", "\n"))[0],
|
||||||
|
local soapPassword = (std.split(importstr "secrets/plain/soap-password", "\n"))[0],
|
||||||
|
local panelSecret = (std.split(importstr "secrets/plain/panel-secret", "\n"))[0],
|
||||||
|
local oauthSecret = (std.split(importstr "secrets/plain/oauth-secret", "\n"))[0],
|
||||||
|
local motd = importstr "secrets/plain/motd.txt",
|
||||||
|
|
||||||
|
local wow = self,
|
||||||
|
local cfg = self.cfg,
|
||||||
|
cfg+:: {
|
||||||
|
namespace: "personal-q3k",
|
||||||
|
prefix: "wow-",
|
||||||
|
address: "185.236.240.62",
|
||||||
|
db+: {
|
||||||
|
// Run everything as mysql root, #yolo.
|
||||||
|
local mkConfig = function(name) {
|
||||||
|
host: wow.mysql.svc.host,
|
||||||
|
port: wow.mysql.svc.port,
|
||||||
|
user: "root",
|
||||||
|
password: sqlPassword,
|
||||||
|
database: "acore_%s" % [name],
|
||||||
|
},
|
||||||
|
auth+: mkConfig("auth"),
|
||||||
|
world+: mkConfig("world"),
|
||||||
|
characters+: mkConfig("characters"),
|
||||||
|
},
|
||||||
|
panel+: {
|
||||||
|
domain: "wow.q3k.org",
|
||||||
|
soap+: {
|
||||||
|
username: "test1",
|
||||||
|
password: soapPassword,
|
||||||
|
},
|
||||||
|
secret: panelSecret,
|
||||||
|
oauth+: {
|
||||||
|
clientID: "56403ef3-df6f-4893-b475-d6c18284ed42",
|
||||||
|
clientSecret: oauthSecret,
|
||||||
|
},
|
||||||
|
motd: motd,
|
||||||
|
},
|
||||||
|
overrides+: {
|
||||||
|
worldserver: {
|
||||||
|
RealmZone: 8,
|
||||||
|
Motd: "Welcome to Pabianice. Enjoy your grind.",
|
||||||
|
|
||||||
|
"Rate.Drop.Item.Poor": 2,
|
||||||
|
"Rate.Drop.Item.Normal": 2,
|
||||||
|
"Rate.Drop.Item.Uncommon": 10,
|
||||||
|
"Rate.Drop.Item.Rare": 10,
|
||||||
|
"Rate.Drop.Item.Epic": 10,
|
||||||
|
"Rate.Drop.Item.Legendary": 10,
|
||||||
|
"Rate.Drop.Item.Artifact": 10,
|
||||||
|
"Rate.Drop.Item.Referenced": 10,
|
||||||
|
"Rate.Drop.Money": 10,
|
||||||
|
"Rate.XP.Kill": 5,
|
||||||
|
"Rate.XP.Explore": 5,
|
||||||
|
"Rate.XP.BattlegroundKill": 10,
|
||||||
|
"Rate.MoveSpeed": 2,
|
||||||
|
"SkillGain.Crafting": 5,
|
||||||
|
"SkillGain.Defense": 5,
|
||||||
|
"SkillGain.Gathering": 5,
|
||||||
|
"SkillGain.Weapon": 5,
|
||||||
|
|
||||||
|
"MinPetitionSigns": 5,
|
||||||
|
"GM.AllowFriend": 1,
|
||||||
|
},
|
||||||
|
ahbot: {
|
||||||
|
"AuctionHouseBot.EnableSeller": 1,
|
||||||
|
"AuctionHouseBot.EnableBuyer": 1,
|
||||||
|
"AuctionHouseBot.Account": 21,
|
||||||
|
"AuctionHouseBot.GUID": 12,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Run a single shitty database.
|
||||||
|
mysql: mysql {
|
||||||
|
cfg+:: {
|
||||||
|
namespace: cfg.namespace,
|
||||||
|
appName: "wow",
|
||||||
|
prefix: cfg.prefix,
|
||||||
|
password: sqlPassword,
|
||||||
|
user: "acore",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
46
personal/q3k/wow/secrets/cipher/motd.txt
Normal file
46
personal/q3k/wow/secrets/cipher/motd.txt
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
-----BEGIN PGP MESSAGE-----
|
||||||
|
|
||||||
|
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
|
||||||
|
=+xOs
|
||||||
|
-----END PGP MESSAGE-----
|
40
personal/q3k/wow/secrets/cipher/mysql-root-password
Normal file
40
personal/q3k/wow/secrets/cipher/mysql-root-password
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
-----BEGIN PGP MESSAGE-----
|
||||||
|
|
||||||
|
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
|
||||||
|
aWFvNnQqaSChijotTt2MWLdELukMt09mblpjpWc=
|
||||||
|
=BH/F
|
||||||
|
-----END PGP MESSAGE-----
|
40
personal/q3k/wow/secrets/cipher/oauth-secret
Normal file
40
personal/q3k/wow/secrets/cipher/oauth-secret
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
-----BEGIN PGP MESSAGE-----
|
||||||
|
|
||||||
|
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
|
||||||
|
EWu/MPG8dkc8r8FJyy4oI0we4ec=
|
||||||
|
=KoHU
|
||||||
|
-----END PGP MESSAGE-----
|
40
personal/q3k/wow/secrets/cipher/panel-secret
Normal file
40
personal/q3k/wow/secrets/cipher/panel-secret
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
-----BEGIN PGP MESSAGE-----
|
||||||
|
|
||||||
|
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
|
||||||
|
Z39r7G++Es9JHr2AqnoEY3s=
|
||||||
|
=E5nj
|
||||||
|
-----END PGP MESSAGE-----
|
40
personal/q3k/wow/secrets/cipher/soap-password
Normal file
40
personal/q3k/wow/secrets/cipher/soap-password
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
-----BEGIN PGP MESSAGE-----
|
||||||
|
|
||||||
|
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
|
||||||
|
eFZDGjE5IA==
|
||||||
|
=l4Xr
|
||||||
|
-----END PGP MESSAGE-----
|
1
personal/q3k/wow/secrets/plain/.gitignore
vendored
Normal file
1
personal/q3k/wow/secrets/plain/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
*
|
Loading…
Reference in a new issue