Skip to content

Commit a01860e

Browse files
deploy
0 parents  commit a01860e

20 files changed

+3022
-0
lines changed

.dockerIgnore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
fbauth.json
2+
.env

.envExample

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
mongoUser=
2+
mongoPass=
3+
jwtSecret=
4+
5+
fbauth={ "type": "", "project_id": "", "private_key_id": "", "private_key": "", "client_email": "", "client_id": "", "auth_uri": "", "token_uri": "", "auth_provider_x509_cert_url": "", "client_x509_cert_url": ""}
6+
#fbauth needs to be in one line

.github/workflows/workflow.yml

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
on:
2+
push:
3+
branches: ["master"]
4+
5+
jobs:
6+
build:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- name: Checkout master
10+
uses: actions/checkout@main
11+
- name: Install doctl
12+
uses: digitalocean/action-doctl@v2
13+
with:
14+
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
15+
- name: Build container image
16+
run: docker build -t registry.digitalocean.com/npuzzle/main:backend-$(echo $GITHUB_SHA | head -c7) .
17+
- name: Log in to DigitalOcean Container Registry with short-lived credentials
18+
run: doctl registry login --expiry-seconds 1200
19+
- name: Push image to DigitalOcean Container Registry
20+
run: docker push registry.digitalocean.com/npuzzle/main:backend-$(echo $GITHUB_SHA | head -c7)
21+
- name: Update deployment file <IMAGE>
22+
run: TAG=$(echo $GITHUB_SHA | head -c7) && sed -i 's|<IMAGE>|registry.digitalocean.com/npuzzle/main:backend-'${TAG}'|' $GITHUB_WORKSPACE/k8s/auto-deployment.yml
23+
- name: Update deployment file <MONGOUSER>
24+
run: sed -i 's|<MONGOUSER>|'${{ secrets.MONGOUSER }}'|' $GITHUB_WORKSPACE/k8s/auto-deployment.yml
25+
- name: Update deployment file <MONGOPASS>
26+
run: sed -i 's|<MONGOPASS>|'${{ secrets.MONGOPASS }}'|' $GITHUB_WORKSPACE/k8s/auto-deployment.yml
27+
- name: Update deployment file <JWTSECRET>
28+
run: sed -i 's|<JWTSECRET>|'${{ secrets.JWTSECRET }}'|' $GITHUB_WORKSPACE/k8s/auto-deployment.yml
29+
- name: Update deployment file <FBAUTHENC>
30+
run: sed -i 's|<FBAUTHENC>|'${{ secrets.FB_AUTH_ENC }}'|' $GITHUB_WORKSPACE/k8s/auto-deployment.yml
31+
- name: Update deployment file <FBAUTHKEY>
32+
run: sed -i 's|<FBAUTHKEY>|'${{ secrets.FB_AUTH_KEY }}'|' $GITHUB_WORKSPACE/k8s/auto-deployment.yml
33+
- name: Save DigitalOcean kubeconfig with short-lived credentials
34+
run: doctl kubernetes cluster kubeconfig save --expiry-seconds 600 ${{ secrets.DO_CLUSTER_NAME }}
35+
- name: Deploy to DigitalOcean Kubernetes
36+
run: kubectl apply -f $GITHUB_WORKSPACE/k8s/auto-deployment.yml
37+
- name: Verify deployment
38+
run: kubectl rollout status deployment/npuzzle-backend

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.env
2+
fbauth.json

Dockerfile

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# syntax=docker/dockerfile:1
2+
3+
FROM golang:1.19.0-bullseye AS build
4+
5+
WORKDIR /app
6+
7+
COPY go.mod ./
8+
COPY go.sum ./
9+
RUN go mod download
10+
11+
COPY *.go ./
12+
13+
RUN go build -o /npuzzlex-be-acc
14+
15+
FROM gcr.io/distroless/base-debian11
16+
17+
WORKDIR /
18+
19+
COPY --from=build /npuzzlex-be-acc /npuzzlex-be-acc
20+
21+
EXPOSE 8080
22+
23+
USER nonroot:nonroot
24+
25+
ENTRYPOINT ["/npuzzlex-be-acc"]

Readme.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
To serveapply
2+
- go get .
3+
- go run .
4+
5+
To docker
6+
- docker build -t npuzzlex-be-acc .
7+
- docker run -dp 8080:8080 npuzzlex-be-acc
8+
9+
To kubernetes
10+
Make sure kubectl points to the correct context (desktop dev or DO k8s deploy)
11+
- kubectl apply -f deployment.yml
12+
- kubectl apply -f services.yml
13+
- Check kubectl get deploy(services)

accHome.go

+201
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"log"
6+
"net/http"
7+
8+
"github.com/gin-gonic/gin"
9+
10+
"go.mongodb.org/mongo-driver/bson"
11+
"go.mongodb.org/mongo-driver/mongo"
12+
"go.mongodb.org/mongo-driver/mongo/options"
13+
)
14+
15+
type postAccRequestBody struct {
16+
Username string `json:"username"`
17+
}
18+
19+
func postAccHome(c *gin.Context) {
20+
userid, err := validateToken(c.GetHeader("Authorization"), false, true)
21+
if err != nil {
22+
c.IndentedJSON(http.StatusBadRequest, "INVALID TOKEN")
23+
return
24+
}
25+
26+
var requestBody postAccRequestBody
27+
if err = c.BindJSON(&requestBody); err != nil {
28+
c.IndentedJSON(http.StatusBadRequest, "NEED USERNAME IN BODY")
29+
return
30+
}
31+
32+
result, err := mongoClient.Database("npuzzle").Collection("Akun").
33+
UpdateOne(context.TODO(),
34+
bson.D{{Key: "creator_id", Value: userid}},
35+
bson.D{{Key: "$set", Value: bson.D{{Key: "username", Value: requestBody.Username}}}},
36+
)
37+
if err != nil {
38+
c.IndentedJSON(http.StatusBadRequest, err)
39+
return
40+
}
41+
42+
if result.MatchedCount != 1 {
43+
c.IndentedJSON(http.StatusBadRequest, "USER NOT FOUND")
44+
return
45+
}
46+
47+
c.IndentedJSON(http.StatusOK, nil)
48+
}
49+
50+
func getAccHome(c *gin.Context) {
51+
userid, err := validateToken(c.GetHeader("Authorization"), false, true)
52+
if err != nil {
53+
c.IndentedJSON(http.StatusBadRequest, err.Error())
54+
return
55+
}
56+
57+
var pipeline mongo.Pipeline
58+
pipeline = append(pipeline, bson.D{{Key: "$match", Value: bson.D{
59+
{Key: "creator_id", Value: userid},
60+
}}})
61+
62+
pipeline = append(pipeline, bson.D{{Key: "$lookup", Value: bson.D{
63+
{Key: "from", Value: "Favourites"},
64+
{Key: "localField", Value: "creator_id"},
65+
{Key: "foreignField", Value: "creator_id"},
66+
{Key: "pipeline", Value: mongo.Pipeline{
67+
bson.D{{Key: "$project", Value: bson.D{
68+
{Key: "_id", Value: 0},
69+
{Key: "c", Value: bson.D{{Key: "$size", Value: "$puzzles"}}},
70+
}}},
71+
}},
72+
{Key: "as", Value: "countFav"},
73+
}}})
74+
75+
pipeline = append(pipeline, bson.D{{Key: "$lookup", Value: bson.D{
76+
{Key: "from", Value: "UserHistory"},
77+
{Key: "localField", Value: "creator_id"},
78+
{Key: "foreignField", Value: "creator_id"},
79+
{Key: "pipeline", Value: mongo.Pipeline{
80+
bson.D{{Key: "$project", Value: bson.D{
81+
{Key: "_id", Value: 0},
82+
{Key: "puzzles", Value: 1},
83+
}}},
84+
}},
85+
{Key: "as", Value: "comp"},
86+
}}})
87+
88+
pipeline = append(pipeline, bson.D{{Key: "$lookup", Value: bson.D{
89+
{Key: "from", Value: "Puzzle"},
90+
{Key: "localField", Value: "creator_id"},
91+
{Key: "foreignField", Value: "creator_id"},
92+
{Key: "pipeline", Value: mongo.Pipeline{
93+
bson.D{{Key: "$project", Value: bson.D{
94+
{Key: "_id", Value: 0},
95+
{Key: "puzzle_id", Value: 1},
96+
}}},
97+
}},
98+
{Key: "as", Value: "countMyP"},
99+
}}})
100+
101+
pipeline = append(pipeline, bson.D{{Key: "$lookup", Value: bson.D{
102+
{Key: "from", Value: "SavedState"},
103+
{Key: "localField", Value: "creator_id"},
104+
{Key: "foreignField", Value: "creator_id"},
105+
{Key: "pipeline", Value: mongo.Pipeline{
106+
bson.D{{Key: "$project", Value: bson.D{
107+
{Key: "_id", Value: 0},
108+
{Key: "States", Value: bson.D{{Key: "$map", Value: bson.D{
109+
{Key: "input", Value: bson.D{{Key: "$objectToArray", Value: "$States"}}},
110+
{Key: "as", Value: "e"},
111+
{Key: "in", Value: "$$e.k"},
112+
}}}},
113+
}}},
114+
}},
115+
{Key: "as", Value: "sStates"},
116+
}}})
117+
118+
pipeline = append(pipeline, bson.D{{Key: "$set", Value: bson.D{
119+
{Key: "countMyP", Value: bson.D{{Key: "$size", Value: "$countMyP"}}},
120+
{Key: "countFav", Value: bson.D{{Key: "$cond", Value: bson.D{
121+
{Key: "if", Value: bson.D{{Key: "$gt", Value: bson.A{
122+
bson.D{{Key: "$size", Value: "$countFav"}},
123+
0,
124+
}}}},
125+
{Key: "then", Value: bson.D{{Key: "$first", Value: "$countFav"}}},
126+
{Key: "else", Value: 0},
127+
}}}},
128+
{Key: "comp", Value: bson.D{{Key: "$cond", Value: bson.D{
129+
{Key: "if", Value: bson.D{{Key: "$gt", Value: bson.A{
130+
bson.D{{Key: "$size", Value: "$comp"}},
131+
0,
132+
}}}},
133+
{Key: "then", Value: bson.D{{Key: "$first", Value: "$comp"}}},
134+
{Key: "else", Value: bson.D{{Key: "puzzles", Value: bson.A{}}}},
135+
}}}},
136+
{Key: "sStates", Value: bson.D{{Key: "$cond", Value: bson.D{
137+
{Key: "if", Value: bson.D{{Key: "$gt", Value: bson.A{
138+
bson.D{{Key: "$size", Value: "$sStates"}},
139+
0,
140+
}}}},
141+
{Key: "then", Value: bson.D{{Key: "$first", Value: "$sStates"}}},
142+
{Key: "else", Value: bson.D{{Key: "States", Value: bson.A{}}}},
143+
}}}},
144+
}}})
145+
146+
pipeline = append(pipeline, bson.D{{Key: "$set", Value: bson.D{
147+
{Key: "countComp", Value: bson.D{{Key: "$size", Value: "$comp.puzzles"}}},
148+
{Key: "countFav", Value: "$countFav.c"},
149+
{Key: "comp", Value: "$comp.puzzles"},
150+
{Key: "sStates", Value: "$sStates.States"},
151+
}}})
152+
153+
pipeline = append(pipeline, bson.D{{Key: "$addFields", Value: bson.D{
154+
{Key: "countUncomp", Value: bson.D{{Key: "$subtract", Value: bson.A{
155+
bson.D{{Key: "$size", Value: "$sStates"}},
156+
bson.D{{Key: "$size", Value: bson.D{{Key: "$setIntersection", Value: bson.A{"$sStates", "$comp"}}}}},
157+
}}}},
158+
}}})
159+
160+
pipeline = append(pipeline, bson.D{{Key: "$project", Value: bson.D{
161+
{Key: "_id", Value: 0},
162+
{Key: "ftkn", Value: 0},
163+
{Key: "dtkn", Value: 0},
164+
{Key: "comp", Value: 0},
165+
{Key: "sStates", Value: 0},
166+
{Key: "creator_id", Value: 0},
167+
}}})
168+
169+
cursor, err := mongoClient.Database("npuzzle").Collection("Akun").
170+
Aggregate(context.TODO(), pipeline, options.Aggregate())
171+
172+
if err != nil {
173+
log.Panic(err)
174+
return
175+
}
176+
177+
var results []bson.D
178+
if err = cursor.All(context.TODO(), &results); err != nil {
179+
panic(err)
180+
}
181+
182+
var arr []map[string]interface{}
183+
for _, e := range results {
184+
arr = append(arr, e.Map())
185+
}
186+
187+
if len(arr) > 0 {
188+
c.IndentedJSON(http.StatusOK, gin.H{
189+
"username": arr[0]["username"],
190+
"countFavorites": arr[0]["countFav"],
191+
"countCompleted": arr[0]["countComp"],
192+
"countUncompleted": arr[0]["countUncomp"],
193+
"countMyPuzzles": arr[0]["countMyP"],
194+
})
195+
} else {
196+
c.IndentedJSON(http.StatusBadRequest, "USER ID NOT FOUND")
197+
}
198+
}
199+
200+
//curl -X POST --header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmUiOiJTdW4sIDI4IEF1ZyAyMDIyIDAzOjE1OjMyICswOTAwIiwiaWQiOiJhbXNsa2RpdWV3cmE1NDUifQ.PuNqwGfcY0h9NooicnlJRCqXOrbo28LcYdFbz_BBngs" --data "{ \"username\": \"testchange\" }" http://localhost:8080
201+
//curl -X GET --header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHBpcmUiOiJTdW4sIDI4IEF1ZyAyMDIyIDAzOjE1OjMyICswOTAwIiwiaWQiOiJhbXNsa2RpdWV3cmE1NDUifQ.PuNqwGfcY0h9NooicnlJRCqXOrbo28LcYdFbz_BBngs" http://localhost:8080

0 commit comments

Comments
 (0)