From 570d2acf78d99de5e63d0fbd14a7c60c919dd06f Mon Sep 17 00:00:00 2001 From: Gabriel Radureau Date: Sun, 29 Sep 2024 16:56:17 +0200 Subject: [PATCH] paste code generated with chatgpt --- .gitea/workflows/dockerimage.yaml | 40 +++++++++ Dockerfile | 36 ++++++++ README.md | 9 +- go.mod | 5 ++ go.sum | 2 + main.go | 132 ++++++++++++++++++++++++++++++ 6 files changed, 223 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/dockerimage.yaml create mode 100644 Dockerfile create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go diff --git a/.gitea/workflows/dockerimage.yaml b/.gitea/workflows/dockerimage.yaml new file mode 100644 index 0000000..6cb3128 --- /dev/null +++ b/.gitea/workflows/dockerimage.yaml @@ -0,0 +1,40 @@ +--- +# template source: https://github.com/bretfisher/docker-build-workflow/blob/main/templates/call-docker-build.yaml +name: Docker Build + +on: + push: + branches: + - main + paths-ignore: + - 'README.md' + - 'argocd/**' +# cancel any previously-started, yet still active runs of this workflow on the same branch +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + steps: + + - name: Login to Gitea Container Registry + uses: docker/login-action@v3 + with: + registry: gitea.arcodange.duckdns.org + username: ${{ github.actor }} + password: ${{ secrets.PACKAGES_TOKEN }} + + - name: git checkout + uses: actions/checkout@v4 + + - name: Build and push image to Gitea Container Registry + run: |- + TAGS="latest ${{ github.ref_name }}" + docker build -t app . + for TAG in $TAGS; do + docker tag app gitea.arcodange.duckdns.org/${{ github.repository }}:$TAG + docker push gitea.arcodange.duckdns.org/${{ github.repository }}:$TAG + done + \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0694e13 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +# Utiliser une image officielle de Go pour construire l'application +FROM golang:1.20-alpine AS builder + +# Installer les dépendances pour PostgreSQL +RUN apk add --no-cache git + +# Créer le répertoire de travail +WORKDIR /app + +# Copier le module go et télécharger les dépendances +COPY go.mod go.sum ./ +RUN go mod download + +# Copier tout le code de l'application dans le conteneur +COPY . . + +# Compiler l'application en un binaire statique +RUN go build -o app . + +# Utiliser une image alpine légère pour l'exécution +FROM alpine:latest + +# Installer les dépendances requises pour PostgreSQL dans le conteneur +RUN apk --no-cache add ca-certificates + +# Créer le répertoire de l'application +WORKDIR /root/ + +# Copier le binaire compilé depuis l'image de build +COPY --from=builder /app/app . + +# Exposer le port de l'application +EXPOSE 8080 + +# Définir la commande pour démarrer l'application +CMD ["./app"] diff --git a/README.md b/README.md index 065e9b8..2275899 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,10 @@ # webapp -simple app for testing purpose \ No newline at end of file +simple web app with a database connection for testing purpose +return 42 + the number in input + +> [!NOTE] +> code generated with chat gpt + +- [ ] Connect through pgbouncer +- [ ] Credentials generated with Hashicorp Vault \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..08fb563 --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module gitea.arcodange.duckdns.org/arcodange-org/webapp + +go 1.20 + +require github.com/lib/pq v1.10.9 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..aeddeae --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= diff --git a/main.go b/main.go new file mode 100644 index 0000000..a7aa587 --- /dev/null +++ b/main.go @@ -0,0 +1,132 @@ +package main + +import ( + "database/sql" + "fmt" + "html/template" + "log" + "net/http" + "os" + "strconv" + + _ "github.com/lib/pq" // PostgreSQL driver +) + +var db *sql.DB // Global database connection + +// dbConnection initializes the database connection. +func dbConnection() (*sql.DB, error) { + connStr := os.Getenv("DATABASE_URL") // You should set this env var, e.g., postgres://username:password@localhost/dbname?sslmode=disable + return sql.Open("postgres", connStr) +} + +// indexHandler serves the HTML form for the query. +func indexHandler(w http.ResponseWriter, r *http.Request) { + tmpl := ` + + + + Query Form + + + +

Query Form

+
+ + + +
+ + + ` + t := template.Must(template.New("form").Parse(tmpl)) + t.Execute(w, nil) +} + +// selectHandler handles HTTP requests and executes a SQL query. +func selectHandler(w http.ResponseWriter, r *http.Request) { + // Get the 'param' query parameter + paramStr := r.URL.Query().Get("param") + if paramStr == "" { + http.Error(w, "Missing 'param' query parameter", http.StatusBadRequest) + return + } + + // Convert the param to an integer + param, err := strconv.Atoi(paramStr) + if err != nil { + http.Error(w, "Invalid 'param' query parameter. Must be an integer.", http.StatusBadRequest) + return + } + + // Prepare the SQL query to prevent SQL injection + query := "SELECT 42 + $1" + + // Execute the query with the provided parameter + var result int + err = db.QueryRow(query, param).Scan(&result) + if err != nil { + log.Printf("Failed to execute query: %v", err) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + return + } + + // Return the result in a simple HTML response + fmt.Fprintf(w, "

Result: %d

", result) +} + +func main() { + var err error + + // Initialize the database connection once at startup + db, err = dbConnection() + if err != nil { + log.Fatalf("Failed to connect to the database: %v", err) + } + defer db.Close() + + // Define the handler for the `/` route (serves HTML form) + http.HandleFunc("/", indexHandler) + + // Define the handler for the `/query` route (executes SQL query) + http.HandleFunc("/query", selectHandler) + + // Start the HTTP server + port := ":8080" + log.Printf("Server starting on port %s\n", port) + err = http.ListenAndServe(port, nil) + if err != nil { + log.Fatalf("Server failed to start: %v", err) + } +}