Browse Source

Some work on interface. default ipv6.

pull/109/head
Per-Arne Andersen 4 years ago
parent
commit
2c53963d91
  1. 4
      wg-manager-backend/db/wireguard.py
  2. 5
      wg-manager-backend/schemas.py
  3. 383
      wg-manager-frontend/src/app/page/dashboard/add-server/add-server.component.html
  4. 9
      wg-manager-frontend/src/app/page/dashboard/add-server/add-server.component.ts
  5. 16
      wg-manager-frontend/src/app/page/dashboard/dashboard.component.html
  6. 7
      wg-manager-frontend/src/app/services/config.service.ts

4
wg-manager-backend/db/wireguard.py

@ -183,7 +183,7 @@ def server_add(server: schemas.WGServerAdd, sess: Session, start=False):
check_interface_exists = any(map(lambda el: el.interface == server.interface, all_interfaces))
check_v4_address_exists = any(map(lambda el: el.address == server.address, all_interfaces))
check_v6_address_exists = any(map(lambda el: el.v6_address == server.v6_address, all_interfaces))
check_listen_port_exists = any(map(lambda el: el.listen_port == server.listen_port, all_interfaces))
check_listen_port_exists = any(map(lambda el: str(el.listen_port) == str(server.listen_port), all_interfaces))
if check_interface_exists:
raise WGMHTTPException(
status_code=400,
@ -194,7 +194,7 @@ def server_add(server: schemas.WGServerAdd, sess: Session, start=False):
status_code=400,
detail=f"There is already a interface with the IPv4 address: {server.address}")
if check_v6_address_exists:
if server.v6_support and check_v6_address_exists:
raise WGMHTTPException(
status_code=400,
detail=f"There is already a interface with the IPv6 address: {server.v6_address}")

5
wg-manager-backend/schemas.py

@ -60,7 +60,7 @@ class GenericModel(BaseModel):
if n_results == 0:
# Insert, does not exists at all.
# Convert from schema to model
dbm = self.Meta.model(**self.dict())
dbm = self.Meta.model(**self.dict(exclude=self.Meta.excludes)) # TODO. added exclude here. this might mess stuff?
sess.add(dbm)
else:
self.filter_query(sess).update(self.dict(include=self.columns()))
@ -179,7 +179,7 @@ class WGServer(GenericModel):
class Meta:
model = models.WGServer
key = "interface"
excludes = {"id", "peers"}
excludes = {"id", "peers", "v6_support"}
def convert(self):
self.peers = [] if not self.peers else self.peers
@ -190,6 +190,7 @@ class WGServerAdd(WGServer):
address: str
interface: str
listen_port: int
v6_support: bool
class WGPeerConfigAdd(GenericModel):

383
wg-manager-frontend/src/app/page/dashboard/add-server/add-server.component.html

@ -1,195 +1,206 @@
<mat-card class="dashboard-card">
<mat-card-title class="card-container-left">
Add WireGuard Server
</mat-card-title>
<mat-card-title class="card-container-right">
<input #confInput hidden="true" type="file" multiple onclick="this.value=null" (change)="parseFiles($event)" accept=".conf"/>
<button
mat-flat-button
color="primary"
(click)="confInput.click()"
matTooltip="Import existing wireguard configuration. You can select both server and peer configuration. The number of imported peers are described near the submit button."
>Import Configuration</button>
</mat-card-title>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
<b>New WireGuard Server</b>
</mat-panel-title>
<mat-panel-description>
Expand this to open configuration of a new wireguard server
</mat-panel-description>
</mat-expansion-panel-header>
<form [formGroup]="serverForm" class="add-server-form">
<p><b>Network Configuration</b></p>
<table class="add-server-full-width" cellspacing="0"><tr>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Interface</mat-label>
<input formControlName="interface" matInput [placeholder]="defaultInterface">
</mat-form-field>
</td>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Endpoint</mat-label>
<input formControlName="endpoint" matInput [placeholder]="defaultEndpoint">
</mat-form-field>
</td>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Port</mat-label>
<input formControlName="listen_port" matInput [placeholder]="defaultListenPort">
</mat-form-field>
</td>
</tr>
<tr>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Default DNS</mat-label>
<input formControlName="dns" matInput [placeholder]="defaultIPv4Address">
</mat-form-field>
</td>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Default allowed IPs</mat-label>
<input formControlName="allowed_ips" matInput [placeholder]="defaultAllowedIPs">
</mat-form-field>
</td>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Default PersistentKeepalive interval</mat-label>
<input formControlName="keep_alive" matInput [placeholder]="defaultPersistentKeepalive">
</mat-form-field>
</td>
</tr>
</table>
<p><b>IPv4 Configuration</b></p>
<table class="add-server-full-width" cellspacing="0"><tr>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>IPv4 Address</mat-label>
<input formControlName="address" matInput [placeholder]="defaultIPv4Address">
</mat-form-field>
</td>
<td>
<mat-form-field matLine class="add-server-full-width">
<mat-label>Subnet</mat-label>
<select matNativeControl formControlName="subnet">
<option *ngFor="let v4Subnet of v4Subnets" [value]="v4Subnet">/{{v4Subnet}}</option>
</select>
</mat-form-field>
</td>
</tr></table>
<p><b>IPv6 Configuration</b></p>
<table class="add-server-full-width" cellspacing="0"><tr>
<td>
<mat-checkbox [checked]="defaultHasIPV6Support" [value]="defaultHasIPV6Support" (change)="ipv6SupportChanged($event)">IPv6 Support</mat-checkbox>
</td>
</tr></table>
<table class="add-server-full-width" cellspacing="0"><tr>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>IPv6 Address</mat-label>
<input formControlName="v6_address" matInput [placeholder]="defaultIPv6Address">
</mat-form-field>
</td>
<td>
<mat-form-field matLine class="add-server-full-width">
<mat-label>Subnet</mat-label>
<select matNativeControl formControlName="v6_subnet">
<option *ngFor="let v6Subnet of v6Subnets" [value]="v6Subnet">/{{v6Subnet}}</option>
</select>
</mat-form-field>
</td>
</tr></table>
<p><b>Key-pairs</b></p>
<div class="button-row">
<button type="button" [disabled]="!isEdit" (click)="getKeyPair()" mat-raised-button color="primary">
<i class="material-icons">vpn_key</i>
Generate KeyPair
</button>
</div>
<mat-card-content class="dashboard-card-content">
<table class="add-server-full-width" cellspacing="0">
<tr>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Private-Key</mat-label>
<input formControlName="private_key" matInput>
</mat-form-field>
</td>
</tr>
<tr>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Public-Key</mat-label>
<input formControlName="public_key" matInput>
</mat-form-field>
</td>
</tr>
</table>
<p><b>Scripts</b></p>
<table class="add-server-full-width" cellspacing="0">
<tr>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Post-Up</mat-label>
<textarea formControlName="post_up" matInput rows="4"></textarea>
</mat-form-field>
</td>
</tr>
<tr>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Post-Down</mat-label>
<textarea formControlName="post_down" matInput rows="4"></textarea>
</mat-form-field>
</td>
</tr>
</table>
<div class="button-row">
<button mat-raised-button color="primary"
type="submit"
[disabled]="!serverForm.valid"
(click)="serverForm.valid && add(serverForm.value)"
(keydown.enter)="serverForm.valid && add(serverForm.value)"
>
<ng-container *ngIf="!isEdit">Add Server</ng-container>
<ng-container *ngIf="isEdit">Edit Server</ng-container>
</button>
<button mat-raised-button color="warn" (click)="resetForm()">
Reset
</button>
<input #confInput hidden="true" type="file" multiple onclick="this.value=null" (change)="parseFiles($event)" accept=".conf"/>
<button
mat-raised-button
color="primary"
(click)="confInput.click()"
matTooltip="Import existing wireguard configuration. You can select both server and peer configuration. The number of imported peers are described near the submit button."
>Import Configuration</button>
<div *ngIf="this.serverForm.value['peers'] && this.serverForm.value['peers'].length > 0">
Importing <b>{{this.serverForm.value['peers'].length}}</b> peers.
</div>
<form [formGroup]="serverForm" class="add-server-form">
<p><b>Essentials</b></p>
<table class="add-server-full-width" cellspacing="0"><tr>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Interface</mat-label>
<input formControlName="interface" matInput [placeholder]="defaultInterface">
</mat-form-field>
</td>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Endpoint</mat-label>
<input formControlName="endpoint" matInput placeholder="my-address.com">
</mat-form-field>
</td>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Port</mat-label>
<input formControlName="listen_port" matInput [placeholder]="defaultListenPort">
</mat-form-field>
</td>
</tr></table>
<table class="add-server-full-width" cellspacing="0"><tr>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>IPv4 Address</mat-label>
<input formControlName="address" matInput [placeholder]="defaultIPv4Address">
</mat-form-field>
</td>
<td>
<mat-form-field matLine class="add-server-full-width">
<mat-label>Subnet</mat-label>
<select matNativeControl formControlName="subnet">
<option *ngFor="let v4Subnet of v4Subnets" [value]="v4Subnet">/{{v4Subnet}}</option>
</select>
</mat-form-field>
</td>
</tr></table>
<table class="add-server-full-width" cellspacing="0"><tr>
<td>
<mat-checkbox [checked]="true" #hasIPV6Support (change)="ipv6SupportChanged($event)">IPv6 Support</mat-checkbox>
</td>
</tr></table>
<table *ngIf="hasIPV6Support.checked" class="add-server-full-width" cellspacing="0"><tr>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>IPv6 Address</mat-label>
<input formControlName="v6_address" matInput [placeholder]="defaultIPv6Address">
</mat-form-field>
</td>
<td>
<mat-form-field matLine class="add-server-full-width">
<mat-label>Subnet</mat-label>
<select matNativeControl formControlName="v6_subnet">
<option *ngFor="let v6Subnet of v6Subnets" [value]="v6Subnet">/{{v6Subnet}}</option>
</select>
</mat-form-field>
</td>
</tr></table>
<table class="add-server-full-width" cellspacing="0"><tr>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Default DNS</mat-label>
<input formControlName="dns" matInput [placeholder]="defaultIPv4Address">
</mat-form-field>
</td>
</tr>
<tr>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Default allowed IPs</mat-label>
<input formControlName="allowed_ips" matInput [placeholder]="defaultAllowedIPs">
</mat-form-field>
</td>
</tr>
<tr>
<td>
<mat-form-field class="add-server-full-width">
<mat-label>Default PersistentKeepalive interval</mat-label>
<input formControlName="keep_alive" matInput [placeholder]="defaultPersistentKeepalive">
</mat-form-field>
</td>
</tr>
</table>
<p><b>Keys</b></p>
<p>
<mat-form-field class="add-server-full-width">
<mat-label>Private-Key</mat-label>
<input formControlName="private_key" matInput>
</mat-form-field>
</p>
<p>
<mat-form-field class="add-server-full-width">
<mat-label>Public-Key</mat-label>
<input formControlName="public_key" matInput>
</mat-form-field>
</p>
<div class="button-row">
<button type="button" [disabled]="!isEdit" (click)="getKeyPair()" mat-raised-button color="primary">
<i class="material-icons">vpn_key</i>
Generate KeyPair
</button>
</div>
<p><b>Scripts</b></p>
<p>
<mat-form-field class="add-server-full-width">
<mat-label>Post-Up</mat-label>
<input formControlName="post_up" matInput>
</mat-form-field>
</p>
<p>
<mat-form-field class="add-server-full-width">
<mat-label>Post-Down</mat-label>
<input formControlName="post_down" matInput>
</mat-form-field>
</p>
<div class="button-row">
<button mat-raised-button color="primary"
type="submit"
[disabled]="!serverForm.valid"
(click)="serverForm.valid && add(serverForm.value)"
(keydown.enter)="serverForm.valid && add(serverForm.value)"
>
<ng-container *ngIf="!isEdit">Add Server</ng-container>
<ng-container *ngIf="isEdit">Edit Server</ng-container>
</button>
<button mat-raised-button color="warn" (click)="resetForm()">
Reset
</button>
<div *ngIf="this.serverForm.value['peers'] && this.serverForm.value['peers'].length > 0">
Importing <b>{{this.serverForm.value['peers'].length}}</b> peers.
</div>
</div>
</form>
</form>
</mat-expansion-panel>
</mat-card-content>
</mat-card>

9
wg-manager-frontend/src/app/page/dashboard/add-server/add-server.component.ts

@ -37,8 +37,10 @@ export class AddServerComponent implements OnInit {
v4Subnets = [];
v6Subnets = [];
defaultEndpoint = "replace-me.com"
defaultListenPort = "51820"
defaultInterface = "wg0"
defaultHasIPV6Support = false;
defaultIPv4Subnet = 24;
defaultIPv6Subnet = 64;
defaultIPv4Address = "10.0.200.1"
@ -54,13 +56,14 @@ export class AddServerComponent implements OnInit {
initForm(){
this.serverForm = new FormGroup({
v6_address: new FormControl({value: this.defaultIPv6Address, disabled: !this.defaultHasIPV6Support}, [Validators.required, IPValidator.isIPAddress]),
v6_subnet: new FormControl({value: this.defaultIPv6Subnet, disabled: !this.defaultHasIPV6Support}, [Validators.required, Validators.min(1), Validators.max(64)]),
v6_support: new FormControl(this.defaultHasIPV6Support, [Validators.required]),
address: new FormControl(this.defaultIPv4Address, [Validators.required, IPValidator.isIPAddress]),
v6_address: new FormControl(this.defaultIPv6Address, [Validators.required, IPValidator.isIPAddress]),
subnet: new FormControl(this.defaultIPv4Subnet, [Validators.required, Validators.min(1), Validators.max(32)]),
v6_subnet: new FormControl(this.defaultIPv6Subnet, [Validators.required, Validators.min(1), Validators.max(64)]),
interface: new FormControl(this.defaultInterface, [Validators.required, Validators.minLength(3)]),
listen_port: new FormControl(this.defaultListenPort, [Validators.required, NumberValidator.stringIsNumber]),
endpoint: new FormControl('', Validators.required),
endpoint: new FormControl(this.defaultEndpoint, Validators.required),
dns: new FormControl(this.defaultDNS),
allowed_ips: new FormControl(this.defaultAllowedIPs),
keep_alive: new FormControl(this.defaultPersistentKeepalive),

16
wg-manager-frontend/src/app/page/dashboard/dashboard.component.html

@ -1,17 +1,19 @@
<div
fxFlexFill
fxLayout="row"
fxLayout="column"
fxLayout.lt-lg="column"
style="padding: 10px;"
fxLayoutGap="20px">
style="padding: 10px;" fxLayoutGap="20px">
<div fxFlex="65">
<app-server [(server)]="servers[idx]" [(servers)]="servers" *ngFor="let server of servers; let idx = index"></app-server>
<div fxFlex="100">
<app-add-server [(servers)]="servers"></app-add-server>
</div>
<div fxFlex="35">
<app-add-server [(servers)]="servers"></app-add-server>
<div fxFlex="100">
<app-server [(server)]="servers[idx]" [(servers)]="servers" *ngFor="let server of servers; let idx = index"></app-server>
</div>
</div>

7
wg-manager-frontend/src/app/services/config.service.ts

@ -25,9 +25,8 @@ export class ConfigService {
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
this.notify.notify("error", error.error.detail)
// return an observable with a user-facing error message
return throwError(
'Something bad happened; please try again later.');
this.notify.notify("error", JSON.stringify(error.error.detail))
// return an observable with a user-facing error message
return throwError('Something bad happened; please try again later.');
}
}

Loading…
Cancel
Save