Single binary build (#10)
Single binary build Use go rice for embedding the static files and templates to the binary file
This commit is contained in:
		
							parent
							
								
									b741a915ae
								
							
						
					
					
						commit
						9a27cc366f
					
				|  | @ -19,7 +19,9 @@ docker-compose* | ||||||
| # Others | # Others | ||||||
| .lgtm.yml | .lgtm.yml | ||||||
| .travis.yml | .travis.yml | ||||||
|  | .vscode | ||||||
| 
 | 
 | ||||||
| # App data & bin | # App data & bin | ||||||
| db | db | ||||||
|  | assets | ||||||
| wireguard-ui | wireguard-ui | ||||||
|  | @ -12,7 +12,12 @@ wireguard-ui | ||||||
| # Output of the go coverage tool, specifically when used with LiteIDE | # Output of the go coverage tool, specifically when used with LiteIDE | ||||||
| *.out | *.out | ||||||
| 
 | 
 | ||||||
| # Dependency directories (remove the comment below to include it) | # Dependency directories and files (remove the comment below to include it) | ||||||
| vendor/ | vendor/ | ||||||
| assets/ | assets/ | ||||||
| node_modules | node_modules/ | ||||||
|  | rice-box.go | ||||||
|  | 
 | ||||||
|  | # IDEs | ||||||
|  | .vscode | ||||||
|  | .idea | ||||||
|  |  | ||||||
							
								
								
									
										28
									
								
								Dockerfile
								
								
								
								
							
							
						
						
									
										28
									
								
								Dockerfile
								
								
								
								
							|  | @ -12,16 +12,19 @@ WORKDIR /build | ||||||
| # Add sources | # Add sources | ||||||
| COPY . /build | COPY . /build | ||||||
| 
 | 
 | ||||||
| # Get application dependencies and build |  | ||||||
| RUN go mod download |  | ||||||
| RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o wg-ui . |  | ||||||
| 
 |  | ||||||
| # Prepare assets | # Prepare assets | ||||||
| RUN yarn install --pure-lockfile --production && \ | RUN yarn install --pure-lockfile --production && \ | ||||||
|     yarn cache clean |     yarn cache clean | ||||||
| 
 | 
 | ||||||
|  | # Move admin-lte dist | ||||||
|  | RUN mkdir -p assets/dist/js assets/dist/css && \ | ||||||
|  |     cp /build/node_modules/admin-lte/dist/js/adminlte.min.js \ | ||||||
|  |     assets/dist/js/adminlte.min.js && \ | ||||||
|  |     cp /build/node_modules/admin-lte/dist/css/adminlte.min.css \ | ||||||
|  |     assets/dist/css/adminlte.min.css | ||||||
|  | 
 | ||||||
| # Move plugin assets | # Move plugin assets | ||||||
| RUN mkdir -p /assets/plugins && \ | RUN mkdir -p assets/plugins && \ | ||||||
|     cp -r /build/node_modules/admin-lte/plugins/jquery/ \ |     cp -r /build/node_modules/admin-lte/plugins/jquery/ \ | ||||||
|     /build/node_modules/admin-lte/plugins/fontawesome-free/ \ |     /build/node_modules/admin-lte/plugins/fontawesome-free/ \ | ||||||
|     /build/node_modules/admin-lte/plugins/bootstrap/ \ |     /build/node_modules/admin-lte/plugins/bootstrap/ \ | ||||||
|  | @ -30,8 +33,15 @@ RUN mkdir -p /assets/plugins && \ | ||||||
|     /build/node_modules/admin-lte/plugins/jquery-validation/ \ |     /build/node_modules/admin-lte/plugins/jquery-validation/ \ | ||||||
|     /build/node_modules/admin-lte/plugins/select2/ \ |     /build/node_modules/admin-lte/plugins/select2/ \ | ||||||
|     /build/node_modules/jquery-tags-input/ \ |     /build/node_modules/jquery-tags-input/ \ | ||||||
|     /assets/plugins/ |     assets/plugins/ | ||||||
| 
 | 
 | ||||||
|  | # Get go modules and build tool | ||||||
|  | RUN go mod download && \ | ||||||
|  |     go get github.com/GeertJohan/go.rice/rice | ||||||
|  | 
 | ||||||
|  | # Build | ||||||
|  | RUN rice embed-go && \ | ||||||
|  |     CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o wg-ui . | ||||||
| 
 | 
 | ||||||
| # Release stage | # Release stage | ||||||
| FROM alpine:3.11 | FROM alpine:3.11 | ||||||
|  | @ -47,12 +57,6 @@ RUN mkdir -p db | ||||||
| 
 | 
 | ||||||
| # Copy binary files | # Copy binary files | ||||||
| COPY --from=builder --chown=wgui:wgui /build/wg-ui /app | COPY --from=builder --chown=wgui:wgui /build/wg-ui /app | ||||||
| # Copy templates |  | ||||||
| COPY --from=builder --chown=wgui:wgui /build/templates /app/templates |  | ||||||
| # Copy assets |  | ||||||
| COPY --from=builder --chown=wgui:wgui /build/node_modules/admin-lte/dist/js/adminlte.min.js /app/assets/dist/js/adminlte.min.js |  | ||||||
| COPY --from=builder --chown=wgui:wgui /build/node_modules/admin-lte/dist/css/adminlte.min.css /app/assets/dist/css/adminlte.min.css |  | ||||||
| COPY --from=builder --chown=wgui:wgui /assets/plugins /app/assets/plugins |  | ||||||
| 
 | 
 | ||||||
| RUN chmod +x wg-ui | RUN chmod +x wg-ui | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										47
									
								
								README.md
								
								
								
								
							
							
						
						
									
										47
									
								
								README.md
								
								
								
								
							|  | @ -8,15 +8,24 @@ A web user interface to manage your WireGuard setup. | ||||||
| - Retrieve configs using QR code / file | - Retrieve configs using QR code / file | ||||||
| 
 | 
 | ||||||
| ## Run WireGuard-UI | ## Run WireGuard-UI | ||||||
| Only docker option for now, please refer to this example of [docker-compose.yml](https://github.com/ngoduykhanh/wireguard-ui/blob/master/docker-compose.yaml). |  | ||||||
| 
 | 
 | ||||||
| Please adjust volume mount points to work with your setup. Then run it: | Default username and password are `admin`. | ||||||
|  | 
 | ||||||
|  | ### Using docker compose | ||||||
|  | 
 | ||||||
|  | You can take a look at this example of [docker-compose.yml](https://github.com/ngoduykhanh/wireguard-ui/blob/master/docker-compose.yaml). Please adjust volume mount points to work with your setup. Then run it like below: | ||||||
| 
 | 
 | ||||||
| ``` | ``` | ||||||
| docker-compose up | docker-compose up | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Default username and password are `admin`. | ### Using binary file | ||||||
|  | 
 | ||||||
|  | Download the binary file from the release and run it with command: | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | ./wireguard-ui | ||||||
|  | ``` | ||||||
| 
 | 
 | ||||||
| ## Auto restart WireGuard daemon | ## Auto restart WireGuard daemon | ||||||
| WireGuard-UI only takes care of configuration generation. You can use systemd to watch for the changes and restart the service. Following is an example: | WireGuard-UI only takes care of configuration generation. You can use systemd to watch for the changes and restart the service. Following is an example: | ||||||
|  | @ -52,6 +61,38 @@ systemctl enable wgui.{path,service} | ||||||
| systemctl start wgui.{path,service} | systemctl start wgui.{path,service} | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
|  | ## Build | ||||||
|  | 
 | ||||||
|  | ### Build docker image | ||||||
|  | 
 | ||||||
|  | Go to the project root directory and run the following command: | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | docker build -t wireguard-ui . | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | ### Build binary file | ||||||
|  | 
 | ||||||
|  | Prepare the assets directory | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | ./prepare_assets.sh | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Then you can embed resources by generating Go source code | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | rice embed-go | ||||||
|  | go build -o wireguard-ui | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Or, append resources to executable as zip file | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | go build -o wireguard-ui | ||||||
|  | rice append --exec wireguard-ui | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
| ## Screenshot | ## Screenshot | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -2,7 +2,8 @@ version: '3' | ||||||
| 
 | 
 | ||||||
| services: | services: | ||||||
|   wg: |   wg: | ||||||
|     image: ngoduykhanh/wireguard-ui:latest |     #image: ngoduykhanh/wireguard-ui:latest | ||||||
|  |     image: wgui:latest | ||||||
|     container_name: wgui |     container_name: wgui | ||||||
|     ports: |     ports: | ||||||
|       - 5000:5000 |       - 5000:5000 | ||||||
|  | @ -12,4 +13,4 @@ services: | ||||||
|         max-size: 50m |         max-size: 50m | ||||||
|     volumes: |     volumes: | ||||||
|       - ./db:/app/db |       - ./db:/app/db | ||||||
|       - /etc/wireguard:/etc/wireguard | #      - /etc/wireguard:/etc/wireguard | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										1
									
								
								go.mod
								
								
								
								
							|  | @ -3,6 +3,7 @@ module github.com/ngoduykhanh/wireguard-ui | ||||||
| go 1.14 | go 1.14 | ||||||
| 
 | 
 | ||||||
| require ( | require ( | ||||||
|  | 	github.com/GeertJohan/go.rice v1.0.0 | ||||||
| 	github.com/glendc/go-external-ip v0.0.0-20170425150139-139229dcdddd | 	github.com/glendc/go-external-ip v0.0.0-20170425150139-139229dcdddd | ||||||
| 	github.com/go-playground/universal-translator v0.17.0 // indirect | 	github.com/go-playground/universal-translator v0.17.0 // indirect | ||||||
| 	github.com/gorilla/sessions v1.2.0 | 	github.com/gorilla/sessions v1.2.0 | ||||||
|  |  | ||||||
							
								
								
									
										8
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										8
									
								
								go.sum
								
								
								
								
							|  | @ -1,4 +1,8 @@ | ||||||
|  | github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= | ||||||
|  | github.com/GeertJohan/go.rice v1.0.0 h1:KkI6O9uMaQU3VEKaj01ulavtF7o1fWT7+pk/4voiMLQ= | ||||||
|  | github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= | ||||||
| github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= | github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= | ||||||
|  | github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= | ||||||
| github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= | ||||||
| github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= | ||||||
| github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw= | github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw= | ||||||
|  | @ -7,6 +11,8 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce | ||||||
| github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= | ||||||
| github.com/casbin/casbin/v2 v2.0.0/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= | github.com/casbin/casbin/v2 v2.0.0/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= | ||||||
| github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= | github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= | ||||||
|  | github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY= | ||||||
|  | github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= | ||||||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||||
| github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= | github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= | ||||||
|  | @ -39,6 +45,7 @@ github.com/gorilla/sessions v1.2.0 h1:S7P+1Hm5V/AT9cjEcUD5uDaQSX0OE577aCXgoaKpYb | ||||||
| github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= | github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= | ||||||
| github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 h1:EFT6MH3igZK/dIVqgGbTqWVvkZ7wJ5iGN03SVtvvdd8= | github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25 h1:EFT6MH3igZK/dIVqgGbTqWVvkZ7wJ5iGN03SVtvvdd8= | ||||||
| github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25/go.mod h1:sWkGw/wsaHtRsT9zGQ/WyJCotGWG/Anow/9hsAcBWRw= | github.com/jcelliott/lumber v0.0.0-20160324203708-dd349441af25/go.mod h1:sWkGw/wsaHtRsT9zGQ/WyJCotGWG/Anow/9hsAcBWRw= | ||||||
|  | github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= | ||||||
| github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw= | github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw= | ||||||
| github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ= | github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ= | ||||||
| github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= | ||||||
|  | @ -75,6 +82,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ | ||||||
| github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | ||||||
| github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | ||||||
| github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= | ||||||
|  | github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= | ||||||
| github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= | github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= | ||||||
| github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||||
| github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ package handler | ||||||
| import ( | import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	rice "github.com/GeertJohan/go.rice" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  | @ -429,7 +430,7 @@ func SuggestIPAllocation() echo.HandlerFunc { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ApplyServerConfig handler to write config file and restart Wireguard server
 | // ApplyServerConfig handler to write config file and restart Wireguard server
 | ||||||
| func ApplyServerConfig() echo.HandlerFunc { | func ApplyServerConfig(tmplBox *rice.Box) echo.HandlerFunc { | ||||||
| 	return func(c echo.Context) error { | 	return func(c echo.Context) error { | ||||||
| 		// access validation
 | 		// access validation
 | ||||||
| 		validSession(c) | 		validSession(c) | ||||||
|  | @ -453,7 +454,7 @@ func ApplyServerConfig() echo.HandlerFunc { | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// Write config file
 | 		// Write config file
 | ||||||
| 		err = util.WriteWireGuardServerConfig(server, clients, settings) | 		err = util.WriteWireGuardServerConfig(tmplBox, server, clients, settings) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			log.Error("Cannot apply server config: ", err) | 			log.Error("Cannot apply server config: ", err) | ||||||
| 			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, fmt.Sprintf("Cannot apply server config: %v", err)}) | 			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, fmt.Sprintf("Cannot apply server config: %v", err)}) | ||||||
|  |  | ||||||
							
								
								
									
										18
									
								
								main.go
								
								
								
								
							
							
						
						
									
										18
									
								
								main.go
								
								
								
								
							|  | @ -2,10 +2,12 @@ package main | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 	rice "github.com/GeertJohan/go.rice" | ||||||
|  | 	"github.com/labstack/echo/v4" | ||||||
| 	"github.com/ngoduykhanh/wireguard-ui/handler" | 	"github.com/ngoduykhanh/wireguard-ui/handler" | ||||||
| 	"github.com/ngoduykhanh/wireguard-ui/router" | 	"github.com/ngoduykhanh/wireguard-ui/router" | ||||||
| 	"github.com/ngoduykhanh/wireguard-ui/util" | 	"github.com/ngoduykhanh/wireguard-ui/util" | ||||||
|  | 	"net/http" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func main() { | func main() { | ||||||
|  | @ -15,8 +17,14 @@ func main() { | ||||||
| 		fmt.Print("Cannot init database: ", err) | 		fmt.Print("Cannot init database: ", err) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// create rice box for embedded template
 | ||||||
|  | 	tmplBox := rice.MustFindBox("templates") | ||||||
|  | 
 | ||||||
|  | 	// rice file server for assets. "assets" is the folder where the files come from.
 | ||||||
|  | 	assetHandler := http.FileServer(rice.MustFindBox("assets").HTTPBox()) | ||||||
|  | 
 | ||||||
| 	// register routes
 | 	// register routes
 | ||||||
| 	app := router.New() | 	app := router.New(tmplBox) | ||||||
| 
 | 
 | ||||||
| 	app.GET("/", handler.WireGuardClients()) | 	app.GET("/", handler.WireGuardClients()) | ||||||
| 	app.GET("/login", handler.LoginPage()) | 	app.GET("/login", handler.LoginPage()) | ||||||
|  | @ -33,6 +41,10 @@ func main() { | ||||||
| 	app.POST("/global-settings", handler.GlobalSettingSubmit()) | 	app.POST("/global-settings", handler.GlobalSettingSubmit()) | ||||||
| 	app.GET("/api/machine-ips", handler.MachineIPAddresses()) | 	app.GET("/api/machine-ips", handler.MachineIPAddresses()) | ||||||
| 	app.GET("/api/suggest-client-ips", handler.SuggestIPAllocation()) | 	app.GET("/api/suggest-client-ips", handler.SuggestIPAllocation()) | ||||||
| 	app.GET("/api/apply-wg-config", handler.ApplyServerConfig()) | 	app.GET("/api/apply-wg-config", handler.ApplyServerConfig(tmplBox)) | ||||||
|  | 
 | ||||||
|  | 	// servers other static files
 | ||||||
|  | 	app.GET("/static/*", echo.WrapHandler(http.StripPrefix("/static/", assetHandler))) | ||||||
|  | 
 | ||||||
| 	app.Logger.Fatal(app.Start("0.0.0.0:5000")) | 	app.Logger.Fatal(app.Start("0.0.0.0:5000")) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,24 @@ | ||||||
|  | #!/usr/bin/env bash | ||||||
|  | set -e | ||||||
|  | 
 | ||||||
|  | DIR=$(dirname "$0") | ||||||
|  | 
 | ||||||
|  | # install node modules | ||||||
|  | yarn install --pure-lockfile --production | ||||||
|  | 
 | ||||||
|  | # Copy admin-lte dist | ||||||
|  | mkdir -p "${DIR}/assets/dist/js" "${DIR}/assets/dist/css" && \ | ||||||
|  |   cp -r "${DIR}/node_modules/admin-lte/dist/js/adminlte.min.js" "${DIR}/assets/dist/js/adminlte.min.js" && \ | ||||||
|  |   cp -r "${DIR}/node_modules/admin-lte/dist/css/adminlte.min.css" "${DIR}/assets/dist/css/adminlte.min.css" | ||||||
|  | 
 | ||||||
|  | # Copy plugins | ||||||
|  | mkdir -p "${DIR}/assets/plugins" && \ | ||||||
|  |   cp -r "${DIR}/node_modules/admin-lte/plugins/jquery" \ | ||||||
|  |   "${DIR}/node_modules/admin-lte/plugins/fontawesome-free" \ | ||||||
|  |   "${DIR}/node_modules/admin-lte/plugins/bootstrap" \ | ||||||
|  |   "${DIR}/node_modules/admin-lte/plugins/icheck-bootstrap" \ | ||||||
|  |   "${DIR}/node_modules/admin-lte/plugins/toastr" \ | ||||||
|  |   "${DIR}/node_modules/admin-lte/plugins/jquery-validation" \ | ||||||
|  |   "${DIR}/node_modules/admin-lte/plugins/select2" \ | ||||||
|  |   "${DIR}/node_modules/jquery-tags-input" \ | ||||||
|  |   "${DIR}/assets/plugins/" | ||||||
|  | @ -5,6 +5,7 @@ import ( | ||||||
| 	"io" | 	"io" | ||||||
| 	"text/template" | 	"text/template" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/GeertJohan/go.rice" | ||||||
| 	"github.com/gorilla/sessions" | 	"github.com/gorilla/sessions" | ||||||
| 	"github.com/labstack/echo-contrib/session" | 	"github.com/labstack/echo-contrib/session" | ||||||
| 	"github.com/labstack/echo/v4" | 	"github.com/labstack/echo/v4" | ||||||
|  | @ -32,15 +33,42 @@ func (t *TemplateRegistry) Render(w io.Writer, name string, data interface{}, c | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // New function
 | // New function
 | ||||||
| func New() *echo.Echo { | func New(tmplBox *rice.Box) *echo.Echo { | ||||||
| 	e := echo.New() | 	e := echo.New() | ||||||
| 	e.Use(session.Middleware(sessions.NewCookieStore([]byte("secret")))) | 	e.Use(session.Middleware(sessions.NewCookieStore([]byte("secret")))) | ||||||
| 
 | 
 | ||||||
|  | 	// read html template file to string
 | ||||||
|  | 	tmplBaseString, err := tmplBox.String("base.html") | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Fatal(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tmplLoginString, err := tmplBox.String("login.html") | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Fatal(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tmplClientsString, err := tmplBox.String("clients.html") | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Fatal(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tmplServerString, err := tmplBox.String("server.html") | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Fatal(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	tmplGlobalSettingsString, err := tmplBox.String("global_settings.html") | ||||||
|  | 	if err != nil { | ||||||
|  | 		log.Fatal(err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// create template list
 | ||||||
| 	templates := make(map[string]*template.Template) | 	templates := make(map[string]*template.Template) | ||||||
| 	templates["login.html"] = template.Must(template.ParseFiles("templates/login.html")) | 	templates["login.html"] = template.Must(template.New("login").Parse(tmplLoginString)) | ||||||
| 	templates["clients.html"] = template.Must(template.ParseFiles("templates/clients.html", "templates/base.html")) | 	templates["clients.html"] = template.Must(template.New("clients").Parse(tmplBaseString + tmplClientsString)) | ||||||
| 	templates["server.html"] = template.Must(template.ParseFiles("templates/server.html", "templates/base.html")) | 	templates["server.html"] = template.Must(template.New("server").Parse(tmplBaseString + tmplServerString)) | ||||||
| 	templates["global_settings.html"] = template.Must(template.ParseFiles("templates/global_settings.html", "templates/base.html")) | 	templates["global_settings.html"] = template.Must(template.New("global_settings").Parse(tmplBaseString + tmplGlobalSettingsString)) | ||||||
| 
 | 
 | ||||||
| 	e.Logger.SetLevel(log.DEBUG) | 	e.Logger.SetLevel(log.DEBUG) | ||||||
| 	e.Pre(middleware.RemoveTrailingSlash()) | 	e.Pre(middleware.RemoveTrailingSlash()) | ||||||
|  | @ -51,7 +79,6 @@ func New() *echo.Echo { | ||||||
| 		AllowMethods: []string{echo.GET, echo.HEAD, echo.PUT, echo.PATCH, echo.POST, echo.DELETE}, | 		AllowMethods: []string{echo.GET, echo.HEAD, echo.PUT, echo.PATCH, echo.POST, echo.DELETE}, | ||||||
| 	})) | 	})) | ||||||
| 	e.Validator = NewValidator() | 	e.Validator = NewValidator() | ||||||
| 	e.Static("/static", "assets") |  | ||||||
| 	e.Renderer = &TemplateRegistry{ | 	e.Renderer = &TemplateRegistry{ | ||||||
| 		templates: templates, | 		templates: templates, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
							
								
								
									
										15
									
								
								util/util.go
								
								
								
								
							
							
						
						
									
										15
									
								
								util/util.go
								
								
								
								
							|  | @ -10,6 +10,7 @@ import ( | ||||||
| 	"text/template" | 	"text/template" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
|  | 	rice "github.com/GeertJohan/go.rice" | ||||||
| 	externalip "github.com/glendc/go-external-ip" | 	externalip "github.com/glendc/go-external-ip" | ||||||
| 	"github.com/ngoduykhanh/wireguard-ui/model" | 	"github.com/ngoduykhanh/wireguard-ui/model" | ||||||
| 	"github.com/sdomino/scribble" | 	"github.com/sdomino/scribble" | ||||||
|  | @ -268,7 +269,7 @@ func GetAvailableIP(cidr string, allocatedList []string) (string, error) { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return "", errors.New("No more available ip address") | 	return "", errors.New("no more available ip address") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ValidateIPAllocation to validate the list of client's ip allocation
 | // ValidateIPAllocation to validate the list of client's ip allocation
 | ||||||
|  | @ -312,12 +313,20 @@ func ValidateIPAllocation(serverAddresses []string, ipAllocatedList []string, ip | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // WriteWireGuardServerConfig to write Wireguard server config. e.g. wg0.conf
 | // WriteWireGuardServerConfig to write Wireguard server config. e.g. wg0.conf
 | ||||||
| func WriteWireGuardServerConfig(serverConfig model.Server, clientDataList []model.ClientData, globalSettings model.GlobalSetting) error { | func WriteWireGuardServerConfig(tmplBox *rice.Box, serverConfig model.Server, clientDataList []model.ClientData, globalSettings model.GlobalSetting) error { | ||||||
| 	t, err := template.ParseFiles("templates/wg.conf") | 	// read wg.conf template file to string
 | ||||||
|  | 	tmplWireguardConf, err := tmplBox.String("wg.conf") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// parse the template
 | ||||||
|  | 	t, err := template.New("wg_config").Parse(tmplWireguardConf) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// write config file to disk
 | ||||||
| 	f, err := os.Create(globalSettings.ConfigFilePath) | 	f, err := os.Create(globalSettings.ConfigFilePath) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue