Skip to content

Commit

Permalink
restart vpn
Browse files Browse the repository at this point in the history
  • Loading branch information
wardviaene committed Aug 20, 2024
1 parent 574638e commit 5c06c14
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 1 deletion.
1 change: 1 addition & 0 deletions pkg/rest/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func (c *Context) getRouter(assets fs.FS, indexHtml []byte) *http.ServeMux {
mux.Handle("/api/setup/general", c.authMiddleware(c.injectUserMiddleware(c.isAdminMiddleware(http.HandlerFunc(c.setupHandler)))))
mux.Handle("/api/setup/vpn", c.authMiddleware(c.injectUserMiddleware(c.isAdminMiddleware(http.HandlerFunc(c.vpnSetupHandler)))))
mux.Handle("/api/setup/templates", c.authMiddleware(c.injectUserMiddleware(c.isAdminMiddleware(http.HandlerFunc(c.templateSetupHandler)))))
mux.Handle("/api/setup/restart-vpn", c.authMiddleware(c.injectUserMiddleware(c.isAdminMiddleware(http.HandlerFunc(c.restartVPNHandler)))))
mux.Handle("/api/scim-setup", c.authMiddleware(c.injectUserMiddleware(c.isAdminMiddleware(http.HandlerFunc(c.scimSetupHandler)))))
mux.Handle("/api/saml-setup", c.authMiddleware(c.injectUserMiddleware(c.isAdminMiddleware(http.HandlerFunc(c.samlSetupHandler)))))
mux.Handle("/api/saml-setup/{id}", c.authMiddleware(c.injectUserMiddleware(c.isAdminMiddleware(http.HandlerFunc(c.samlSetupElementHandler)))))
Expand Down
40 changes: 40 additions & 0 deletions pkg/rest/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"net/netip"
"reflect"
"strconv"
"strings"
"time"

"github.com/google/uuid"
"github.com/in4it/wireguard-server/pkg/auth/oidc"
Expand Down Expand Up @@ -371,6 +373,44 @@ func (c *Context) templateSetupHandler(w http.ResponseWriter, r *http.Request) {
}
}

func (c *Context) restartVPNHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
c.returnError(w, fmt.Errorf("unsupported method"), http.StatusBadRequest)
return
}
client := http.Client{
Timeout: 10 * time.Second,
}
req, err := http.NewRequest(r.Method, "http://"+wireguard.CONFIGMANAGER_URI+"/restart-vpn", nil)
if err != nil {
c.returnError(w, fmt.Errorf("restart request error: %s", err), http.StatusBadRequest)
return
}
resp, err := client.Do(req)
if err != nil {
c.returnError(w, fmt.Errorf("restart error: %s", err), http.StatusBadRequest)
return
}
if resp.StatusCode != http.StatusAccepted {
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
c.returnError(w, fmt.Errorf("restart error: got status code: %d. Response: %s", resp.StatusCode, bodyBytes), http.StatusBadRequest)
return
}
c.returnError(w, fmt.Errorf("restart error: got status code: %d. Couldn't get response", resp.StatusCode), http.StatusBadRequest)
return
}

defer resp.Body.Close()
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
c.returnError(w, fmt.Errorf("body read error: %s", err), http.StatusBadRequest)
return
}

c.write(w, bodyBytes)
}

func (c *Context) scimSetupHandler(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
Expand Down
52 changes: 52 additions & 0 deletions webapp/src/Routes/Setup/Restart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Container, Button, Alert, Space } from "@mantine/core";
import { useState } from "react";
import { IconInfoCircle } from "@tabler/icons-react";
import { AppSettings } from "../../Constants/Constants";
import { useMutation } from "@tanstack/react-query";
import { useAuthContext } from "../../Auth/Auth";
import axios, { AxiosError } from "axios";

type RestartError = {
error: string;
}

export function Restart() {
const [saved, setSaved] = useState(false)
const [saveError, setSaveError] = useState("")
const {authInfo} = useAuthContext();
const alertIcon = <IconInfoCircle />;
const setupMutation = useMutation({
mutationFn: () => {
return axios.post(AppSettings.url + '/setup/restart-vpn', {}, {
headers: {
"Authorization": "Bearer " + authInfo.token
},
})
},
onSuccess: () => {
setSaved(true)
setSaveError("")
},
onError: (error:AxiosError) => {
const errorMessage = error.response?.data as RestartError
if(errorMessage?.error === undefined) {
setSaveError("Error: "+ error.message)
} else {
setSaveError("Error: "+ errorMessage.error)
}
}
})

return (
<Container my={40} size="80rem">
<Alert variant="light" color="blue" title="Note" icon={alertIcon}>This button will reload the WireGuard® Configuration. VPN Clients will be disconnected during the reload. If the configuration has changed, clients might have to download new configuration files (for example if the port or address range has changed). The VPN Server admin UI will not be restarted.</Alert>
<Space h="md" />
{saved && saveError === "" ? <Alert variant="light" color="green" title="Restarted!" icon={alertIcon}>VPN Restarted!</Alert> : null}
{saveError !== "" ? <Alert variant="light" color="red" title="Error!" icon={alertIcon} style={{marginTop: 10}}>{saveError}</Alert> : null}
<Button type="submit" mt="md" onClick={() => setupMutation.mutate()}>
Reload WireGuard® VPN
</Button>
</Container>

)
}
9 changes: 8 additions & 1 deletion webapp/src/Routes/Setup/Setup.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Container, Tabs, Title, rem } from "@mantine/core";
import classes from './Setup.module.css';
import { IconFile, IconNetwork, IconSettings } from "@tabler/icons-react";
import { IconFile, IconNetwork, IconRestore, IconRewindBackward10, IconSettings } from "@tabler/icons-react";
import { GeneralSetup } from "./GeneralSetup";
import { VPNSetup } from "./VPNSetup";
import { TemplateSetup } from "./TemplateSetup";
import { Restart } from "./Restart";

export function Setup() {
const iconStyle = { width: rem(12), height: rem(12) };
Expand All @@ -24,6 +25,9 @@ export function Setup() {
<Tabs.Tab value="templates" leftSection={<IconFile style={iconStyle} />}>
Templates
</Tabs.Tab>
<Tabs.Tab value="restart" leftSection={<IconRestore style={iconStyle} />}>
Restart
</Tabs.Tab>
</Tabs.List>
<Tabs.Panel value="general" style={{marginTop: 25}}>
<GeneralSetup />
Expand All @@ -34,6 +38,9 @@ export function Setup() {
<Tabs.Panel value="templates" style={{marginTop: 25}}>
<TemplateSetup />
</Tabs.Panel>
<Tabs.Panel value="restart" style={{marginTop: 25}}>
<Restart />
</Tabs.Panel>
</Tabs>
</Container>

Expand Down

0 comments on commit 5c06c14

Please sign in to comment.