-
Notifications
You must be signed in to change notification settings - Fork 3
/
vps.service.ts
160 lines (140 loc) · 4.58 KB
/
vps.service.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import { Injectable } from '@angular/core';
import { errors } from '../../shared/errors';
import { Events } from '../../shared/events';
import { net } from 'electron';
import { LoggerService } from '../logger-service/logger.service';
import { ConfigService, ConfigKeys } from '../config-service/config.service';
const http = require('http');
const DigitalOcean = require('do-wrapper').default;
@Injectable({
providedIn: 'root'
})
export class VpsService {
private _isDropletRunning = false;
private api;
private droplet;
constructor(public events: Events, public logs: LoggerService, public config: ConfigService) {
let key = this.config.get(ConfigKeys.apiKey);
this.api = new DigitalOcean(key);
}
createDroplet(): Promise<any> {
this.logs.appendLog('Creating new droplet...');
let newDroplet = {
name: 'SelfVPN',
region: this.config.get(ConfigKeys.region),
size: 's-1vcpu-1gb',
image: 'ubuntu-18-04-x64',
ssh_keys: [],
backups: false,
monitoring: false,
ipv6: false,
user_data: `#cloud-config
runcmd:
- echo 'Started server. Updating... ' > userDataLog.txt
- export DEBIAN_FRONTEND=noninteractive
- apt-get update >> userDataLog.txt
- apt-get -qq upgrade >> userDataLog.txt
- wget https://git.io/vpnsetup -O vpnsetup.sh && sudo >> userDataLog.txt
- export VPN_IPSEC_PSK='${this.config.get(ConfigKeys.psk)}'
- export VPN_USER='${this.config.get(ConfigKeys.username)}'
- export VPN_PASSWORD='${this.config.get(ConfigKeys.password)}'
- sh vpnsetup.sh >> userDataLog.txt
- wget https://bekiruzun.com/SelfVPN/server/server && chmod +x ./server
- ./server &`
};
if (this.config.get(ConfigKeys.sshId))
newDroplet.ssh_keys.push(this.config.get(ConfigKeys.sshId));
if (this.config.get(ConfigKeys.autoDestroy)) {
newDroplet.user_data += `
- echo "DO_PAT=${this.config.get(ConfigKeys.apiKey)}" > .env
- wget https://bekiruzun.com/SelfVPN/monitor/monitor && chmod +x ./monitor
- ./monitor &`;
}
return this.api.dropletsCreate(newDroplet).then(resp => {
this.droplet = resp.body.droplet;
this._isDropletRunning = true;
this.logs.appendLog('Droplet created.');
this.checkDropletBooted();
});
}
destroyDroplet(): Promise<void> {
this.logs.appendLog('Destroying droplet...');
return new Promise<any>(async(resolve, reject) => {
if (!this.droplet && !this.droplet.id && this.droplet.id < 1)
reject();
try {
await this.api.dropletsDelete(this.droplet.id);
this._isDropletRunning = false;
this.droplet = undefined;
return resolve();
} catch (e) {
reject(e);
}
});
}
updateApiKey(key: string): Promise<void> {
let apiToCheck = new DigitalOcean(key);
return apiToCheck.account().then((resp) => {
if (resp.body.account.droplet_limit === 0) {
throw new Error(errors.DROPLET_LIMIT);
}
this.api = apiToCheck;
});
}
isDropletRunning(): boolean {
return this._isDropletRunning;
}
getDropletIP(): string {
if (this.droplet && this.droplet.networks.v4.length > 0)
return this.droplet.networks.v4[0].ip_address;
return 'Unknown';
}
getDropletRegion(): string {
if (this.droplet)
return this.droplet.region.name;
return 'Unknown';
}
checkDroplets(): Promise<void> {
this.logs.appendLog('Checking active droplets...');
return this.api.dropletsGetAll().then((resp) => {
if (resp.body.droplets && resp.body.droplets.length) {
resp.body.droplets.forEach(d => {
console.log(d);
if (d.name.toLowerCase().includes('vpn')) {
this.droplet = d;
this._isDropletRunning = true;
}
});
}
}).catch(err => {
return err;
});
}
checkDropletBooted() {
let bootChecker = setInterval(() => {
this.api.dropletsGetById(this.droplet.id).then(resp => {
console.log(resp);
let d = resp.body.droplet;
if (d.status === 'active' || d.networks.v4.length > 0) {
this.droplet = d;
this.events.publish('droplet:booted', true);
this.checkDropletReady();
clearInterval(bootChecker);
}
});
}, 10000);
}
checkDropletReady() {
let readyChecker = setInterval(() => {
http.get('http://' + this.getDropletIP() + '/', (res) => {
console.log('res', res);
if (res.statusCode === 200) {
this.events.publish('droplet:ready', true);
clearInterval(readyChecker);
}
}).on('error', (e) => {
console.log('error', e);
});
}, 10000);
}
}