From c07ca9c9a54944544017b31156dabc5a9115461a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrej=20Rama=C5=A1euski?= <andrej@x2.cz> Date: Sat, 30 Nov 2024 02:08:35 +0100 Subject: [PATCH] Golang version --- .dockerignore | 4 ---- .env | 2 ++ .gitlab-ci.yml | 10 ++++---- Dockerfile | 16 ++++++------- VERSION | 1 + compose.yaml | 7 ++++++ go.mod | 14 +++++++++++ go.sum | 8 +++++++ main.go | 40 +++++++++++++++++++++++++++++++ octopus/go.mod | 3 +++ octopus/octopus.go | 60 ++++++++++++++++++++++++++++++++++++++++++++++ piratar | 41 ------------------------------- 12 files changed, 148 insertions(+), 58 deletions(-) delete mode 100644 .dockerignore create mode 100644 .env create mode 100644 VERSION create mode 100644 compose.yaml create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 octopus/go.mod create mode 100644 octopus/octopus.go delete mode 100755 piratar diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 381df27..0000000 --- a/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -** -!piratar -!piratar.conf -!default.jpg diff --git a/.env b/.env new file mode 100644 index 0000000..c012b30 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +export OCTOPUS=https://chobotnice.pirati.cz/graphql/ +export OCTPUS_DEBUG=1 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5ac9641..10d3766 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,11 +1,10 @@ -image: docker:20.10.9 +image: docker:latest variables: DOCKER_TLS_CERTDIR: "/certs" - IMAGE_VER: 2.1.0 services: - - docker:20.10.9-dind + - docker:dind before_script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY @@ -13,7 +12,8 @@ before_script: build: stage: build script: + - VERSION=`cat VERSION` - docker pull $CI_REGISTRY_IMAGE:latest || true - - docker build --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$IMAGE_VER --tag $CI_REGISTRY_IMAGE:latest . - - docker push $CI_REGISTRY_IMAGE:$IMAGE_VER + - docker build --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:$VERSION --tag $CI_REGISTRY_IMAGE:latest . + - docker push $CI_REGISTRY_IMAGE:$VERSION - docker push $CI_REGISTRY_IMAGE:latest diff --git a/Dockerfile b/Dockerfile index 3f4c2f3..0de64e5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ -FROM alpine:latest -RUN apk update && apk add perl-mojolicious perl-io-socket-ssl perl-app-cpanminus make -RUN cpanm GraphQL::Client +FROM golang:alpine AS build-stage +ADD . ./ +RUN CGO_ENABLED=0 GOOS=linux go build -o /piratar -ADD . /opt/piratar -WORKDIR /opt/piratar - -USER nobody +FROM alpine +WORKDIR /app +COPY --from=build-stage /piratar /app +COPY default.jpg /app EXPOSE 3000 -CMD /opt/piratar/piratar daemon -c 3000 +ENTRYPOINT ["/app/piratar"] diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..4a36342 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +3.0.0 diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..6e0f8b7 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,7 @@ +services: + app: + image: piratar + environment: + OCTOPUS: https://chobotnice.pirati.cz/graphql/ + ports: + - "3000:3000" diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..68b7c45 --- /dev/null +++ b/go.mod @@ -0,0 +1,14 @@ +module pirates/piratar + +go 1.22.2 + +require pirates/piratar/octopus v0.0.0-00010101000000-000000000000 + +require ( + github.com/google/uuid v1.6.0 // indirect + github.com/machinebox/graphql v0.2.2 // indirect + github.com/matryer/is v1.4.1 // indirect + github.com/pkg/errors v0.9.1 // indirect +) + +replace pirates/piratar/octopus => ./octopus diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..2fe3d62 --- /dev/null +++ b/go.sum @@ -0,0 +1,8 @@ +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/machinebox/graphql v0.2.2 h1:dWKpJligYKhYKO5A2gvNhkJdQMNZeChZYyBbrZkBZfo= +github.com/machinebox/graphql v0.2.2/go.mod h1:F+kbVMHuwrQ5tYgU9JXlnskM8nOaFxCAEolaQybkjWA= +github.com/matryer/is v1.4.1 h1:55ehd8zaGABKLXQUe2awZ99BD/PTc2ls+KV/dXphgEQ= +github.com/matryer/is v1.4.1/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/main.go b/main.go new file mode 100644 index 0000000..8635994 --- /dev/null +++ b/main.go @@ -0,0 +1,40 @@ +package main + +import ( + "fmt" + "log" + "path" + "strings" + "net/http" + "pirates/piratar/octopus" +) + +func main() { + http.HandleFunc("/", handler) + + port := 3000 // TODO: ENV + fmt.Printf("Piratar service listening on port %d...\n", port) + + if err := http.ListenAndServe(fmt.Sprintf(":%d", port), nil); err != nil { + log.Fatalf("Server failed: %v", err) + } +} + +func handler(w http.ResponseWriter, r *http.Request) { + + // Extrakce username nebo UUID + id := strings.ToLower(path.Base(r.URL.Path)) + if dotIndex := strings.LastIndex(id, "."); dotIndex != -1 { + id = id[:dotIndex] + } + + // Profilova fotka nebo default + if photo, err := octopus.ProfilePhoto(id); err == nil { + fmt.Printf("Piratar for %s: %s\n", id, photo) + http.Redirect(w, r, photo, http.StatusFound) + } else { + fmt.Printf("Piratar for %s not found\n", id) + w.Header().Set("Content-Type", "image/jpeg") + http.ServeFile(w, r, "default.jpg") + } +} diff --git a/octopus/go.mod b/octopus/go.mod new file mode 100644 index 0000000..17405e1 --- /dev/null +++ b/octopus/go.mod @@ -0,0 +1,3 @@ +module pirates/piratar/octopus + +go 1.22.2 diff --git a/octopus/octopus.go b/octopus/octopus.go new file mode 100644 index 0000000..f7ef860 --- /dev/null +++ b/octopus/octopus.go @@ -0,0 +1,60 @@ +package octopus + +import ( + "os" + "fmt" + "log" + "errors" + "context" + "github.com/google/uuid" + "github.com/machinebox/graphql" +) + +func ProfilePhoto (id string) (string, error) { + var keyname string + var response struct { + AllPeople struct { + Edges []struct { + Node struct { + ProfilePhoto string `json:"profilePhoto"` + } `json:"node"` + } `json:"edges"` + } `json:"allPeople"` + } + + if _, err := uuid.Parse(id); err == nil { + keyname = "keycloakId" + } else { + keyname = "username" + } + + // GraphAPI klient + octopus := graphql.NewClient(os.Getenv("OCTOPUS")) + if os.Getenv("DEBUG") != "" { + octopus.Log = func(s string) { log.Println(s) } + } + + // Request + req := graphql.NewRequest(fmt.Sprintf( + `query profilePhoto($username: String!) { + allPeople(filters: {%s: {iExact: $username}}) { + edges { node { profilePhoto } } + }} + `, keyname )) + + req.Var("username", id) + +// define a Context for the request + ctx := context.Background() + +// run it and capture the response + if err := octopus.Run(ctx, req, &response); err != nil { + log.Fatal(err) + } + + if people := response.AllPeople.Edges; len(people) == 1 { + return people[0].Node.ProfilePhoto, nil + } else { + return "", errors.New("User not found") + } +} diff --git a/piratar b/piratar deleted file mode 100755 index e1d838b..0000000 --- a/piratar +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env perl -use Mojolicious::Lite -signatures; -use Mojo::UserAgent; -use Mojolicious::Static; -use GraphQL::Client; -use Mojo::Util qw(dumper); - -get '/*url' => sub ($c) { - - my $username = lc($c->param('url')); - $username =~ s/^.*\///; - $username =~ s/\.(png|jpg|gif)$//; - $c->app->log->debug("Username: $username"); - - my $gq = GraphQL::Client->new(url => $ENV{OCTOPUS}); - my $rc = $gq->execute(qq[ query MyQuery { - allPeople(filters: {username: {iExact: "$username"}}) { - edges { node { profilePhoto } } - }}], - ); - - if ($rc->{errors}) { - $c->app->log->warn("Octopus error: " . dumper $rc->{errors}); - } - elsif ( $rc->{data} ) { - $c->app->log->debug("Octopus response: " . dumper $rc->{data}); - - my $user = $rc->{data}{allPeople}{edges}[0]{node}; - - if ( my $photo = $user->{profilePhoto}) { - $c->app->log->info("Avatar for user $username: $photo"); - $c->redirect_to($photo); - return; - } - } - - $c->app->log->info("Avatar for user $username: FALLBACK"); - $c->reply->file('default.jpg'); -}; - -app->start; -- GitLab