From 2aa4e4f5a5b9e43bbd346fe1f68d615dbf8b1bbf Mon Sep 17 00:00:00 2001 From: area Date: Thu, 21 Oct 2021 17:01:39 -0400 Subject: [PATCH 1/2] first pass at a bot --- cloudfunctions/bot/bot.go | 65 +++++++++++++++++++++++++++++++++++++ cloudfunctions/bot/go.mod | 8 +++++ cloudfunctions/bot/go.sum | 12 +++++++ terraform/cloudfunctions.tf | 49 ++++++++++++++++++++++++++++ terraform/iam.tf | 4 +++ terraform/variables.tf | 5 +++ 6 files changed, 143 insertions(+) create mode 100644 cloudfunctions/bot/bot.go create mode 100644 cloudfunctions/bot/go.mod create mode 100644 cloudfunctions/bot/go.sum diff --git a/cloudfunctions/bot/bot.go b/cloudfunctions/bot/bot.go new file mode 100644 index 0000000..8bb1bec --- /dev/null +++ b/cloudfunctions/bot/bot.go @@ -0,0 +1,65 @@ +package interactions + +import ( + "bytes" + "crypto/ed25519" + "encoding/json" + "net/http" + "os" + + "github.com/bsdlp/discord-interactions-go/interactions" + log "github.com/sirupsen/logrus" +) + +var ( + discordPubkey, discordPubkeyPresent = os.LookupEnv("DISCORD_PUBLIC_KEY") +) + +func init() { + if !discordPubkeyPresent { + log.Fatal("Discord public key is unset") + } +} + +func Interactions(w http.ResponseWriter, r *http.Request) { + verified := interactions.Verify(r, ed25519.PublicKey(discordPubkey)) + if !verified { + http.Error(w, "signature mismatch", http.StatusUnauthorized) + return + } + + defer r.Body.Close() + var data interactions.Data + err := json.NewDecoder(r.Body).Decode(&data) + if err != nil { + // handle error + } + + // respond to ping + if data.Type == interactions.Ping { + _, err := w.Write([]byte(`{"type":1}`)) + if err != nil { + // handle error + } + return + } + + // handle command + response := &interactions.InteractionResponse{ + Type: interactions.ChannelMessage, + Data: &interactions.InteractionApplicationCommandCallbackData{ + Content: "got your message kid", + }, + } + + var responsePayload bytes.Buffer + err = json.NewEncoder(&responsePayload).Encode(response) + if err != nil { + // handle error + } + + _, err = http.Post(data.ResponseURL(), "application/json", &responsePayload) + if err != nil { + // handle err + } +} diff --git a/cloudfunctions/bot/go.mod b/cloudfunctions/bot/go.mod new file mode 100644 index 0000000..a111645 --- /dev/null +++ b/cloudfunctions/bot/go.mod @@ -0,0 +1,8 @@ +module github.com/iloveicedgreentea/valheim-gke-server/bot + +go 1.14 + +require ( + github.com/bsdlp/discord-interactions-go v0.0.0-20201227083222-a2ba84473ce8 + github.com/sirupsen/logrus v1.8.1 +) diff --git a/cloudfunctions/bot/go.sum b/cloudfunctions/bot/go.sum new file mode 100644 index 0000000..05604b6 --- /dev/null +++ b/cloudfunctions/bot/go.sum @@ -0,0 +1,12 @@ +github.com/bsdlp/discord-interactions-go v0.0.0-20201227083222-a2ba84473ce8 h1:rYda/7WZFu2f3WT7l3tNgIGBDYmc5gMUSduFEiVGT1w= +github.com/bsdlp/discord-interactions-go v0.0.0-20201227083222-a2ba84473ce8/go.mod h1:Ceq9LkT/iTYVxpftSuqMFCDpqgcDAboxVByQEF8R0NM= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/terraform/cloudfunctions.tf b/terraform/cloudfunctions.tf index 7625d68..ee9ac65 100644 --- a/terraform/cloudfunctions.tf +++ b/terraform/cloudfunctions.tf @@ -229,4 +229,53 @@ resource "google_cloudfunctions_function" "scaleup" { trigger_http = true +} + +######################## +# Bot Function +######################## + +# Source code +data "archive_file" "bot" { + type = "zip" + source_dir = "${abspath("../")}/cloudfunctions/bot" + output_path = "/tmp/bot.zip" +} + +# Archive file +resource "google_storage_bucket_object" "bot" { + name = "bot-${data.archive_file.scaleup.output_md5}.zip" + bucket = google_storage_bucket.bucket.name + source = data.archive_file.bot.output_path + + metadata = {} + +} +resource "google_cloudfunctions_function" "bot" { + depends_on = [ + google_project_service.apis + ] + + name = "interactions" + description = "interactions" + runtime = "go116" + + available_memory_mb = 128 + source_archive_bucket = google_storage_bucket.bucket.name + source_archive_object = google_storage_bucket_object.bot.name + entry_point = "Interactions" + + labels = { + function = "Interactions" + } + + service_account_email = google_service_account.bot.email + + environment_variables = { + DISCORD_PUBLIC_KEY = var.public_key + + } + + trigger_http = true + } \ No newline at end of file diff --git a/terraform/iam.tf b/terraform/iam.tf index bfe9b4e..c29ee37 100644 --- a/terraform/iam.tf +++ b/terraform/iam.tf @@ -63,6 +63,10 @@ resource "google_service_account" "scaledown" { account_id = "valheim-scaledown" display_name = "SA to scaledown" } +resource "google_service_account" "bot" { + account_id = "valheim-bot" + display_name = "SA for bot" +} resource "google_project_iam_member" "scaleup" { role = "roles/container.admin" member = "serviceAccount:${google_service_account.scaleup.email}" diff --git a/terraform/variables.tf b/terraform/variables.tf index ad2f563..25100af 100644 --- a/terraform/variables.tf +++ b/terraform/variables.tf @@ -120,4 +120,9 @@ variable "scaledown_function_schedule" { type = string default = "0 * * * *" +} + +variable "public_key" { + description = "Discord bot public key" + type = string } \ No newline at end of file From 1e79ddbb2229f7f59de6c82efff8cc545ffa86fc Mon Sep 17 00:00:00 2001 From: iloveicedgreentea <31193909+iloveicedgreentea@users.noreply.github.com> Date: Thu, 21 Oct 2021 22:35:49 -0400 Subject: [PATCH 2/2] error check on k8s access --- start_server.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/start_server.sh b/start_server.sh index 80a9d26..e224270 100755 --- a/start_server.sh +++ b/start_server.sh @@ -11,11 +11,13 @@ project_id=scaleheim if curl "https://$region-$project_id.cloudfunctions.net/$function_name" -H "Authorization: Bearer $(gcloud auth print-identity-token)" -d "{}"; then echo "Server has started. Waiting until it is ready" else - echo "Error starting server. Printing logs" + echo "Error starting server. Printing scaleup function logs" gcloud functions logs read $function_name --region=$region fi # You can uncomment this line if you give users access to list pod information. Exercise for reader. -#kubectl wait --for=condition=ready --timeout=500s pod -l $pod_label - -echo "Server is ready" +if ! kubectl wait --for=condition=ready --timeout=500s pod -l $pod_label > /dev/null 2>&1 ; then + echo "No Kubernetes access detected. Server will be ready in about 6 minutes" +else + echo "Server is ready" +fi \ No newline at end of file