mirror of
https://gitlab.com/ArkHost/WHMCS-ArkHost-HetznerVPS.git
synced 2026-07-24 07:45:53 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc9d8a2e1c | ||
|
|
0f96849032 | ||
|
|
cc60ca7103 |
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
@@ -12,6 +12,7 @@ WHMCS server module for Hetzner Cloud VPS management.
|
|||||||
|
|
||||||
**Advanced**
|
**Advanced**
|
||||||
|
|
||||||
|
- Cloud-init support for automated server configuration
|
||||||
- Floating IP management with reverse DNS
|
- Floating IP management with reverse DNS
|
||||||
- Backup creation and restoration
|
- Backup creation and restoration
|
||||||
- Firewall rule management
|
- Firewall rule management
|
||||||
@@ -55,11 +56,12 @@ WHMCS server module for Hetzner Cloud VPS management.
|
|||||||
|
|
||||||
**Module Settings**
|
**Module Settings**
|
||||||
|
|
||||||
- Server Type: `cx11`, `cx21`, `cx31`, `cx41`, `cx51` , etc.
|
- Server Type: `cx23`, `cx33`, `cx43`, `cx53` (Cost-Optimized), `cpx11`, `cpx21`, `cax11`, `ccx13`, etc.
|
||||||
- Operating System: `ubuntu-20.04`, `debian-11`, etc.
|
- Operating System: `ubuntu-22.04`, `debian-11`, `rocky-9`, etc.
|
||||||
- Datacenter: `fsn1`, `nbg1`, `hel1`, `ash`, `hil`
|
- Datacenter: `fsn1`, `nbg1`, `hel1`, `ash`, `hil`, `sin`
|
||||||
- Backups: On/Off
|
- Backups: On/Off
|
||||||
- Create Floating IP: On/Off
|
- Create Floating IP: On/Off
|
||||||
|
- Cloud-Init YAML: Optional custom cloud-init configuration
|
||||||
|
|
||||||
**Custom Field (Required)**
|
**Custom Field (Required)**
|
||||||
|
|
||||||
@@ -98,6 +100,10 @@ Create in Setup → Products/Services → Configurable Options:
|
|||||||
- Option Name: `planid`
|
- Option Name: `planid`
|
||||||
- Option Type: `Dropdown`
|
- Option Type: `Dropdown`
|
||||||
- Options:
|
- Options:
|
||||||
|
- `cx23|CX23 - 2 vCPU, 4 GB RAM, 40 GB Disk, shared (Cost-Optimized)`
|
||||||
|
- `cx33|CX33 - 4 vCPU, 8 GB RAM, 80 GB Disk, shared (Cost-Optimized)`
|
||||||
|
- `cx43|CX43 - 8 vCPU, 16 GB RAM, 160 GB Disk, shared (Cost-Optimized)`
|
||||||
|
- `cx53|CX53 - 16 vCPU, 32 GB RAM, 320 GB Disk, shared (Cost-Optimized)`
|
||||||
- `cpx11|CPX 11 - 2 vCPU, 2 GB RAM, 40 GB Disk, shared`
|
- `cpx11|CPX 11 - 2 vCPU, 2 GB RAM, 40 GB Disk, shared`
|
||||||
- `cpx21|CPX 21 - 3 vCPU, 4 GB RAM, 80 GB Disk, shared`
|
- `cpx21|CPX 21 - 3 vCPU, 4 GB RAM, 80 GB Disk, shared`
|
||||||
- `cpx31|CPX 31 - 4 vCPU, 8 GB RAM, 160 GB Disk, shared`
|
- `cpx31|CPX 31 - 4 vCPU, 8 GB RAM, 160 GB Disk, shared`
|
||||||
@@ -121,34 +127,36 @@ Create in Setup → Products/Services → Configurable Options:
|
|||||||
|
|
||||||
**4\. Operating System**
|
**4\. Operating System**
|
||||||
|
|
||||||
- Option Name: `osid`
|
- Option Name: `osid`
|
||||||
- Option Type: `Dropdown`
|
- Option Type: `Dropdown`
|
||||||
- Options:
|
- Options:
|
||||||
- `lamp|lamp`
|
|
||||||
-`wordpress|wordpress`
|
|
||||||
-`jitsi|jitsi`
|
|
||||||
-`nextcloud|nextcloud`
|
|
||||||
- `docker-ce|docker-ce`
|
|
||||||
- `gitlab|gitlab`
|
|
||||||
- `debian-11|Debian 11`
|
- `debian-11|Debian 11`
|
||||||
- `rocky-8|Rocky Linux 8`
|
- `debian-12|Debian 12`
|
||||||
- `centos-stream-9|CentOS Stream 9`
|
- `debian-13|Debian 13`
|
||||||
- `ubuntu-22.04|Ubuntu 22.04`
|
- `ubuntu-22.04|Ubuntu 22.04`
|
||||||
- `prometheus-grafana|prometheus-grafana`
|
- `ubuntu-24.04|Ubuntu 24.04`
|
||||||
- `rocky-9|Rocky Linux 9`
|
|
||||||
- `wireguard|wireguard`
|
|
||||||
- `owncast|owncast`
|
|
||||||
- `photoprism|photoprism`
|
|
||||||
- `rustdesk|rustdesk`
|
|
||||||
- `centos-stream-9|CentOS Stream 9`
|
|
||||||
- `debian-11|Debian 11`
|
|
||||||
- `rocky-8|Rocky Linux 8`
|
- `rocky-8|Rocky Linux 8`
|
||||||
- `rocky-9|Rocky Linux 9`
|
- `rocky-9|Rocky Linux 9`
|
||||||
- `ubuntu-22.04|Ubuntu 22.04`
|
- `rocky-10|Rocky Linux 10`
|
||||||
- `alma-8|AlmaLinux 8`
|
- `alma-8|AlmaLinux 8`
|
||||||
- `alma-9|AlmaLinux 9`
|
- `alma-9|AlmaLinux 9`
|
||||||
- `jitsi|jitsi`
|
- `alma-10|AlmaLinux 10`
|
||||||
- `owncast|owncast`
|
- `centos-stream-9|CentOS Stream 9`
|
||||||
|
- `centos-stream-10|CentOS Stream 10`
|
||||||
|
- `opensuse-15|openSUSE 15`
|
||||||
|
- `fedora-41|Fedora 41`
|
||||||
|
- `fedora-42|Fedora 42`
|
||||||
|
- `docker-ce|Docker CE`
|
||||||
|
- `lamp|LAMP Stack`
|
||||||
|
- `wordpress|WordPress`
|
||||||
|
- `nextcloud|Nextcloud`
|
||||||
|
- `gitlab|GitLab`
|
||||||
|
- `jitsi|Jitsi`
|
||||||
|
- `wireguard|WireGuard`
|
||||||
|
- `prometheus-grafana|Prometheus + Grafana`
|
||||||
|
- `owncast|Owncast`
|
||||||
|
- `photoprism|PhotoPrism`
|
||||||
|
- `rustdesk|RustDesk`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -183,6 +191,102 @@ This ensures proper key isolation and security for each customer.
|
|||||||
|
|
||||||
We're exploring secure implementations using cloud-init or per-server user data to enable SSH key management while maintaining proper isolation.
|
We're exploring secure implementations using cloud-init or per-server user data to enable SSH key management while maintaining proper isolation.
|
||||||
|
|
||||||
|
## Cloud-Init Support
|
||||||
|
|
||||||
|
Cloud-init allows automatic server configuration during first boot. Unlike project-level SSH keys, cloud-init user_data is per-server, ensuring proper isolation in multi-tenant environments.
|
||||||
|
|
||||||
|
**Configuration:**
|
||||||
|
|
||||||
|
1. Navigate to Setup → Products/Services → Products/Services
|
||||||
|
2. Edit your product → Module Settings tab
|
||||||
|
3. Find "Cloud-Init YAML (Optional)" textarea
|
||||||
|
4. Enter your cloud-init configuration in YAML format
|
||||||
|
5. Leave empty to skip cloud-init
|
||||||
|
|
||||||
|
**Common Use Cases:**
|
||||||
|
|
||||||
|
**1. Change APT Mirrors** (original use case - avoid Hetzner mirrors):
|
||||||
|
```yaml
|
||||||
|
#cloud-config
|
||||||
|
apt:
|
||||||
|
primary:
|
||||||
|
- arches: [default]
|
||||||
|
uri: http://de.archive.ubuntu.com/ubuntu/
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. Add SSH Keys** (secure alternative to project-level keys):
|
||||||
|
```yaml
|
||||||
|
#cloud-config
|
||||||
|
users:
|
||||||
|
- name: admin
|
||||||
|
ssh_authorized_keys:
|
||||||
|
- ssh-rsa AAAAB3NzaC1yc2E... user@laptop
|
||||||
|
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||||
|
shell: /bin/bash
|
||||||
|
```
|
||||||
|
|
||||||
|
**3. Install Docker:**
|
||||||
|
```yaml
|
||||||
|
#cloud-config
|
||||||
|
packages:
|
||||||
|
- docker.io
|
||||||
|
- docker-compose
|
||||||
|
|
||||||
|
runcmd:
|
||||||
|
- systemctl enable docker
|
||||||
|
- systemctl start docker
|
||||||
|
```
|
||||||
|
|
||||||
|
**4. Security Hardening:**
|
||||||
|
```yaml
|
||||||
|
#cloud-config
|
||||||
|
packages:
|
||||||
|
- fail2ban
|
||||||
|
- ufw
|
||||||
|
|
||||||
|
runcmd:
|
||||||
|
- ufw default deny incoming
|
||||||
|
- ufw default allow outgoing
|
||||||
|
- ufw allow 22/tcp
|
||||||
|
- ufw --force enable
|
||||||
|
- systemctl enable fail2ban
|
||||||
|
- systemctl start fail2ban
|
||||||
|
```
|
||||||
|
|
||||||
|
**5. Combined Configuration:**
|
||||||
|
```yaml
|
||||||
|
#cloud-config
|
||||||
|
apt:
|
||||||
|
primary:
|
||||||
|
- arches: [default]
|
||||||
|
uri: http://mirror.example.com/ubuntu/
|
||||||
|
|
||||||
|
users:
|
||||||
|
- name: admin
|
||||||
|
ssh_authorized_keys:
|
||||||
|
- ssh-rsa AAAAB3... admin@company
|
||||||
|
sudo: ALL=(ALL) NOPASSWD:ALL
|
||||||
|
|
||||||
|
packages:
|
||||||
|
- fail2ban
|
||||||
|
- ufw
|
||||||
|
- docker.io
|
||||||
|
|
||||||
|
runcmd:
|
||||||
|
- ufw allow 22/tcp
|
||||||
|
- ufw --force enable
|
||||||
|
- systemctl enable docker fail2ban
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important Notes:**
|
||||||
|
|
||||||
|
- YAML must be valid syntax (use a YAML validator if unsure)
|
||||||
|
- If you don't start with `#cloud-config`, the module will add it automatically
|
||||||
|
- Cloud-init runs ONCE on first boot only
|
||||||
|
- Invalid YAML will cause provisioning to fail silently
|
||||||
|
- Maximum size: 32 KiB (Hetzner API limit)
|
||||||
|
- Documentation: https://docs.hetzner.cloud/#servers-create-a-server
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||

|

|
||||||

|

|
||||||
@@ -234,5 +338,3 @@ Free and open source. Commercial support available.
|
|||||||
Check out our other WHMCS modules at [arkhost.com/whmcs-modules.php](https://arkhost.com/whmcs-modules.php "https://arkhost.com/whmcs-modules.php")
|
Check out our other WHMCS modules at [arkhost.com/whmcs-modules.php](https://arkhost.com/whmcs-modules.php "https://arkhost.com/whmcs-modules.php")
|
||||||
|
|
||||||
© 2025 ArkHost
|
© 2025 ArkHost
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|||||||
@@ -116,12 +116,12 @@ function ArkHostHetznerVPS_API(array $params) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Packages':
|
case 'Packages':
|
||||||
$url .= 'server_types';
|
$url .= 'server_types?per_page=50';
|
||||||
$method = 'GET';
|
$method = 'GET';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Operating Systems':
|
case 'Operating Systems':
|
||||||
$url .= 'images?type=system';
|
$url .= 'images?type=system&per_page=50';
|
||||||
$method = 'GET';
|
$method = 'GET';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -176,7 +176,21 @@ function ArkHostHetznerVPS_API(array $params) {
|
|||||||
if (ArkHostHetznerVPS_GetOption($params, 'ipv6') === 'on') {
|
if (ArkHostHetznerVPS_GetOption($params, 'ipv6') === 'on') {
|
||||||
$data['enable_ipv6'] = false;
|
$data['enable_ipv6'] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle Cloud-Init user_data if provided
|
||||||
|
$cloudInitYaml = ArkHostHetznerVPS_GetOption($params, 'cloud_init_yaml');
|
||||||
|
if ($cloudInitYaml && trim($cloudInitYaml) !== '') {
|
||||||
|
// Basic YAML validation - check if it starts with #cloud-config
|
||||||
|
$trimmedYaml = trim($cloudInitYaml);
|
||||||
|
if (strpos($trimmedYaml, '#cloud-config') !== 0) {
|
||||||
|
// Auto-prepend #cloud-config if missing
|
||||||
|
$cloudInitYaml = "#cloud-config\n" . $cloudInitYaml;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass as plain text - Hetzner API accepts user_data as plain string (max 32KiB)
|
||||||
|
$data['user_data'] = $cloudInitYaml;
|
||||||
|
}
|
||||||
|
|
||||||
// Handle SSH keys from custom field if needed
|
// Handle SSH keys from custom field if needed
|
||||||
// This would need to be implemented with a custom field
|
// This would need to be implemented with a custom field
|
||||||
break;
|
break;
|
||||||
@@ -239,7 +253,7 @@ function ArkHostHetznerVPS_API(array $params) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Operating Systems - Server':
|
case 'Operating Systems - Server':
|
||||||
$url .= 'images?type=system';
|
$url .= 'images?type=system&per_page=50';
|
||||||
$method = 'GET';
|
$method = 'GET';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -988,6 +1002,13 @@ function ArkHostHetznerVPS_ConfigOptions() {
|
|||||||
'Description' => 'Automatically create a floating IP when provisioning this server (additional cost - billed by Hetzner).',
|
'Description' => 'Automatically create a floating IP when provisioning this server (additional cost - billed by Hetzner).',
|
||||||
'Type' => 'yesno',
|
'Type' => 'yesno',
|
||||||
),
|
),
|
||||||
|
'cloud_init_yaml' => array(
|
||||||
|
'FriendlyName' => 'Cloud-Init YAML (Optional)',
|
||||||
|
'Description' => 'Custom cloud-init configuration in YAML format (max 32KiB). Passed as user_data to Hetzner API during server creation. Leave empty to skip cloud-init. <a href="https://docs.hetzner.cloud/#servers-create-a-server" target="_blank">Documentation</a>',
|
||||||
|
'Type' => 'textarea',
|
||||||
|
'Rows' => '10',
|
||||||
|
'Cols' => '60',
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -1154,12 +1175,17 @@ function ArkHostHetznerVPS_CreateAccount(array $params) {
|
|||||||
$params['model']->serviceProperties->save([
|
$params['model']->serviceProperties->save([
|
||||||
'ArkHostHetznerVPS|VPS ID' => $create['server']['id'],
|
'ArkHostHetznerVPS|VPS ID' => $create['server']['id'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Store the root password if provided
|
// Store the root password if provided
|
||||||
if (isset($create['root_password'])) {
|
if (isset($create['root_password'])) {
|
||||||
Capsule::table('tblhosting')->where('id', $params['serviceid'])->update([
|
Capsule::table('tblhosting')->where('id', $params['serviceid'])->update([
|
||||||
'password' => encrypt($create['root_password'])
|
'password' => encrypt($create['root_password'])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Save the timestamp when password was set for expiration tracking (72 hours)
|
||||||
|
$params['model']->serviceProperties->save([
|
||||||
|
'ArkHostHetznerVPS|Password Set Time' => time()
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle floating IP creation if requested via Configurable Options or Module Settings
|
// Handle floating IP creation if requested via Configurable Options or Module Settings
|
||||||
@@ -1904,7 +1930,12 @@ function ArkHostHetznerVPS_ClientAreaAPI(array $params) {
|
|||||||
Capsule::table('tblhosting')
|
Capsule::table('tblhosting')
|
||||||
->where('id', $params['serviceid'])
|
->where('id', $params['serviceid'])
|
||||||
->update(['password' => encrypt($result['root_password'])]);
|
->update(['password' => encrypt($result['root_password'])]);
|
||||||
|
|
||||||
|
// Save the timestamp when password was set for expiration tracking (72 hours)
|
||||||
|
$params['model']->serviceProperties->save([
|
||||||
|
'ArkHostHetznerVPS|Password Set Time' => time()
|
||||||
|
]);
|
||||||
|
|
||||||
$results['root_password'] = $result['root_password'];
|
$results['root_password'] = $result['root_password'];
|
||||||
$results['message'] = 'Server rebuild initiated. New root password has been saved.';
|
$results['message'] = 'Server rebuild initiated. New root password has been saved.';
|
||||||
} else {
|
} else {
|
||||||
@@ -1941,6 +1972,21 @@ function ArkHostHetznerVPS_ClientAreaAPI(array $params) {
|
|||||||
$results['result'] = 'error';
|
$results['result'] = 'error';
|
||||||
$results['message'] = 'Invalid floating IP ID for this service';
|
$results['message'] = 'Invalid floating IP ID for this service';
|
||||||
}
|
}
|
||||||
|
} else if ($action === 'Reset root') {
|
||||||
|
// Handle password reset from client area
|
||||||
|
$results = array_merge($results, is_array($result) ? $result : array('data' => $result));
|
||||||
|
|
||||||
|
// Store the new root password and timestamp if provided
|
||||||
|
if (isset($result['root_password'])) {
|
||||||
|
Capsule::table('tblhosting')->where('id', $params['serviceid'])->update([
|
||||||
|
'password' => encrypt($result['root_password'])
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Save the timestamp when password was set for expiration tracking (72 hours)
|
||||||
|
$params['model']->serviceProperties->save([
|
||||||
|
'ArkHostHetznerVPS|Password Set Time' => time()
|
||||||
|
]);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$results = array_merge($results, is_array($result) ? $result : array('data' => $result));
|
$results = array_merge($results, is_array($result) ? $result : array('data' => $result));
|
||||||
}
|
}
|
||||||
@@ -2347,6 +2393,26 @@ function ArkHostHetznerVPS_ClientArea(array $params) {
|
|||||||
$serverInfo['datacenter'] = isset($serverInfo['datacenter']['description']) ? $serverInfo['datacenter']['description'] : 'N/A';
|
$serverInfo['datacenter'] = isset($serverInfo['datacenter']['description']) ? $serverInfo['datacenter']['description'] : 'N/A';
|
||||||
$serverInfo['location'] = isset($serverInfo['datacenter']['location']['city']) ? $serverInfo['datacenter']['location']['city'] : 'N/A';
|
$serverInfo['location'] = isset($serverInfo['datacenter']['location']['city']) ? $serverInfo['datacenter']['location']['city'] : 'N/A';
|
||||||
|
|
||||||
|
// Get root password with expiration check (72 hours)
|
||||||
|
$passwordSetTime = $params['model']->serviceProperties->get('ArkHostHetznerVPS|Password Set Time');
|
||||||
|
$currentTime = time();
|
||||||
|
$expirationPeriod = 72 * 3600; // 72 hours in seconds
|
||||||
|
|
||||||
|
if (!empty($params['password']) && $params['password'] !== 'managed-via-api') {
|
||||||
|
// If no timestamp exists, show the password (backward compatibility or initial setup)
|
||||||
|
// If timestamp exists, check if it's within the 72-hour window
|
||||||
|
if (!$passwordSetTime || ($currentTime - $passwordSetTime) < $expirationPeriod) {
|
||||||
|
// Password is still valid - WHMCS already decrypts it for us in $params
|
||||||
|
// No need to call decrypt() as $params['password'] is already plain text
|
||||||
|
$serverInfo['install_root'] = $params['password'];
|
||||||
|
} else {
|
||||||
|
// Password has expired (timestamp exists and is older than 72 hours)
|
||||||
|
$serverInfo['install_root'] = '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$serverInfo['install_root'] = '';
|
||||||
|
}
|
||||||
|
|
||||||
// For now, always show backups tab - the API will handle permissions
|
// For now, always show backups tab - the API will handle permissions
|
||||||
$backupsEnabled = true;
|
$backupsEnabled = true;
|
||||||
|
|
||||||
@@ -2436,12 +2502,17 @@ function ArkHostHetznerVPS_ResetRoot(array $params) {
|
|||||||
try {
|
try {
|
||||||
$params['action'] = 'Reset root';
|
$params['action'] = 'Reset root';
|
||||||
$result = ArkHostHetznerVPS_API($params);
|
$result = ArkHostHetznerVPS_API($params);
|
||||||
|
|
||||||
// Store the new root password if provided
|
// Store the new root password if provided
|
||||||
if (isset($result['root_password'])) {
|
if (isset($result['root_password'])) {
|
||||||
Capsule::table('tblhosting')->where('id', $params['serviceid'])->update([
|
Capsule::table('tblhosting')->where('id', $params['serviceid'])->update([
|
||||||
'password' => encrypt($result['root_password'])
|
'password' => encrypt($result['root_password'])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Save the timestamp when password was set for expiration tracking (72 hours)
|
||||||
|
$params['model']->serviceProperties->save([
|
||||||
|
'ArkHostHetznerVPS|Password Set Time' => time()
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
} catch (Exception $err) {
|
} catch (Exception $err) {
|
||||||
ArkHostHetznerVPS_Error(__FUNCTION__, $params, $err);
|
ArkHostHetznerVPS_Error(__FUNCTION__, $params, $err);
|
||||||
|
|||||||
@@ -224,6 +224,12 @@ function resetRootPassword() {
|
|||||||
function() {
|
function() {
|
||||||
ArkHostHetznerVPS_API('Reset root', true, {}, function(data) {
|
ArkHostHetznerVPS_API('Reset root', true, {}, function(data) {
|
||||||
if (data.root_password) {
|
if (data.root_password) {
|
||||||
|
// Update the password field on the page
|
||||||
|
var passwordField = document.getElementById('vpsPassword');
|
||||||
|
if (passwordField) {
|
||||||
|
passwordField.value = data.root_password;
|
||||||
|
}
|
||||||
|
|
||||||
// Show password in a special modal or notification
|
// Show password in a special modal or notification
|
||||||
var passwordHtml = '<div class="alert alert-success">' +
|
var passwordHtml = '<div class="alert alert-success">' +
|
||||||
'<h5>' + lang.newRootPassword + '</h5>' +
|
'<h5>' + lang.newRootPassword + '</h5>' +
|
||||||
@@ -236,7 +242,7 @@ function resetRootPassword() {
|
|||||||
'</div>' +
|
'</div>' +
|
||||||
'<p class="mt-2 mb-0"><small>' + lang.savePassword + ' ' + lang.passwordSaved + '</small></p>' +
|
'<p class="mt-2 mb-0"><small>' + lang.savePassword + ' ' + lang.passwordSaved + '</small></p>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
|
|
||||||
// Create a modal to show the password
|
// Create a modal to show the password
|
||||||
var modal = document.createElement('div');
|
var modal = document.createElement('div');
|
||||||
modal.className = 'arkhost-confirm-overlay show';
|
modal.className = 'arkhost-confirm-overlay show';
|
||||||
|
|||||||
Reference in New Issue
Block a user